你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

Linux 和 FreeBSD VM 中加速网络的工作方式

在 Azure 中创建 VM 时,系统会在其配置中为每个虚拟 NIC 创建合成网络接口。 合成接口是 VMbus 设备,并且会使用“netvsc.sys”驱动程序。 使用此合成接口的网络数据包会通过 Azure 主机中的虚拟交换机,并进入数据中心物理网络。

如果 VM 配置了加速网络,则系统会为已配置的每个虚拟 NIC 创建第二个网络接口。 第二个接口是由 Azure 主机中的物理网络 NIC 提供的 SR-IOV 虚拟功能 (VF)。 VF 接口在 Linux 来宾中显示为 PCI 设备,并在 Linux 中使用 Mellanox“mlx4”或“mlx5”驱动程序,因为 Azure 主机使用的是 Mellanox 中的物理 NIC。 大多数网络数据包直接在 Linux 来宾和物理 NIC 之间传输,而无需遍历虚拟交换机或主机上运行的任何其他软件。 由于对硬件的直接访问,与合成接口相比,此过程的网络延迟较低,使用 CPU 处理网络数据包的时间也更少。

不同的 Azure 主机使用不同型号的 Mellanox 物理 NIC,因此 Linux 会自动确定是否使用 “mlx4”或“mlx5”驱动程序。 VM 在 Azure 主机上的位置由 Azure 基础结构控制。 如果没有用于指定 VM 部署所使用的物理 NIC 的客户选项,则 VM 必须包含这两个驱动程序。 如果已停止/解除分配 VM,然后重新启动,则系统可能会在具有不同的 Mellanox 物理 NIC 模型的硬件上重新部署该 VM。 因此,该 VM 可能会使用另一个 Mellanox 驱动程序。

如果 VM 映像不包含用于 Mellanox 物理 NIC 的驱动程序,则网络功能将继续以较慢的虚拟 NIC 速度工作,即使门户、Azure CLI 和 Azure PowerShell 的加速网络功能仍将显示为“已启用”。

在 Azure 中运行时,FreeBSD 会提供与 Linux 相同的加速网络支持。 本文的其余部分将介绍 Linux 并使用 Linux 示例,但可在 FreeBSD 中获取相同功能。

注意

本文包含对术语“从属”的引用,这是 Microsoft 不再使用的术语。 在从软件中删除该术语后,我们会将其从本文中删除。

捆绑

合成网络接口和 VF 接口会自动配对,并在可由应用程序发现的大多数方面充当单个接口。 捆绑过程由 netvsc 驱动程序完成。 根据 Linux 发行版的不同,udev 规则和脚本可帮助命名 VF 接口和网络配置。 如果 VM 配置了多个虚拟 Nic,Azure 主机将为每个 NIC 提供唯一的序列号。 该规则使 Linux 对每个虚拟 NIC 执行正确的合成和 VF 接口配对。

合成和 VF 接口都拥有相同的 MAC 地址。 从与 VM 中的虚拟 NIC 交换数据包的其他网络实体的角度来看,这些接口共同构成了单个 NIC。 由于存在合成接口和 VF 接口,其他实体不会采取任何特殊操作。

这两个接口可通过 Linux 中的“ifconfig”或“ip addr”命令可见。 以下是 Ubuntu 18.04 中的“ifconfig”输出示例:

U1804:~$ ifconfig 
enP53091s1np0: flags=6211<UP,BROADCAST,RUNNING,SLAVE,MULTICAST>  mtu 1500 
ether 00:0d:3a:f5:76:bd  txqueuelen 1000  (Ethernet) 
RX packets 365849  bytes 413711297 (413.7 MB) 
RX errors 0  dropped 0  overruns 0  frame 0 
TX packets 9447684  bytes 2206536829 (2.2 GB) 
TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0 
 
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500 
inet 10.1.19.4  netmask 255.255.255.0  broadcast 10.1.19.255 
inet6 fe80::20d:3aff:fef5:76bd  prefixlen 64  scopeid 0x20<link> 
ether 00:0d:3a:f5:76:bd  txqueuelen 1000  (Ethernet) 
RX packets 8714212  bytes 4954919874 (4.9 GB) 
RX errors 0  dropped 0  overruns 0  frame 0 
TX packets 9103233  bytes 2183731687 (2.1 GB) 
TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0 

合成接口的名称始终是“eth <n>”。 根据 Linux 发行版的不同,VF 接口的名称可能是“eth <n>”,也可能因重命名所采取的 udev 规则而采用其他形式。

可以使用 shell 命令行来确定特定接口是合成接口还是 VF 接口,此命令行显示接口使用的设备驱动程序:

$ ethtool -i <interface name> | grep driver 

如果驱动程序为“hv_netvsc”,则为合成接口。 VF 接口拥有包含“mlx”的驱动程序名称。 由于 VF 接口的标志字段包含“SLAVE”,因此其也为可识别。 此标志说明该接口受具有相同 MAC 地址的合成接口的控制。 最后,系统仅会将 IP 地址分配给合成接口,而且“ifconfig”或“ip addr”的输出内容也会显示这种区别。

应用程序使用情况

应用程序应该只与合成接口交互,就像在任何其他网络环境中一样。 传出网络数据包从 netvsc.sys 驱动程序传输到 VF 驱动程序,然后再通过 VF 接口传输。 传入数据包经 VF 接口接收和处理,然后再传输到合成接口。 例外情况包括仅由合成接口处理的传入 TCP SYN 数据包和广播/多播数据包。

可以验证数据包是否从“ethtool-S eth <n>”的输出流经 VF 接口。 包含“vf”的输出行显示了通过 VF 接口的流量。 例如:

U1804:~# ethtool -S eth0 | grep ' vf_' 
 vf_rx_packets: 111180 
 vf_rx_bytes: 395460237 
 vf_tx_packets: 9107646 
 vf_tx_bytes: 2184786508 
 vf_tx_dropped: 0 

如果这些计数器在连续执行“ethtool”命令时递增,则网络流量将流经 VF 接口。

可使用“lspci”命令查看 VF 接口是否以 PCI 设备的形式存在。 例如,在第 1 代 VM 上,可能会看到类似于以下的内容(第 2 代 VM 不拥有旧式 PCI 设备):

U1804:~# lspci 
0000:00:00.0 Host bridge: Intel Corporation 440BX/ZX/DX - 82443BX/ZX/DX Host bridge (AGP disabled) (rev 03) 
0000:00:07.0 ISA bridge: Intel Corporation 82371AB/EB/MB PIIX4 ISA (rev 01) 
0000:00:07.1 IDE interface: Intel Corporation 82371AB/EB/MB PIIX4 IDE (rev 01) 
0000:00:07.3 Bridge: Intel Corporation 82371AB/EB/MB PIIX4 ACPI (rev 02) 
0000:00:08.0 VGA compatible controller: Microsoft Corporation Hyper-V virtual VGA 
cf63:00:02.0 Ethernet controller: Mellanox Technologies MT27710 Family [ConnectX-4 Lx Virtual Function] (rev 80) 

在此示例中,输出的最后一行显示在 Mellanox ConnectX-4 物理 NIC 中识别出了 VF 接口。

“ethtool -l”或“ethtool -L”命令(用于获取和设置传输队列和接收队列的数目)对于适用于与“eth<n>”接口交互的指南是例外情况。 此命令可直接用于 VF 接口,以控制 VF 接口的队列数。 VF 接口队列的数量与合成接口队列的数量无关。

解释启动消息

在启动过程中,Linux 会显示许多与 VF 接口的初始化和配置相关的消息。 还会显示有关与合成接口捆绑的信息。 了解这些消息对于识别此过程中出现的任何问题十分实用。

以下是“dmesg”命令的输出示例,只显示到与 VF 接口相关的行。 根据 VM 中 Linux 内核版本和发行版的不同,消息可能略有不同,但总体流一致。

[    2.327663] hv_vmbus: registering driver hv_netvsc 
[    3.918902] hv_netvsc 000d3af5-76bd-000d-3af5-76bd000d3af5 eth0: VF slot 1 added 

已为 eth0 注册 netvsc.sys 驱动程序。

[    6.944883] hv_vmbus: registering driver hv_pci 

已注册 VMbus 虚拟 PCI 驱动程序。 此驱动程序在 Azure 中的 Linux VM 中提供核心 PCI 服务,因此必须先注册此驱动程序,然后才能检测并配置 VF 接口。

[    6.945132] hv_pci e9ac9b28-cf63-4466-9ae3-4b849c3ee03b: PCI VMBus probing: Using version 0x10002 
[    6.947953] hv_pci e9ac9b28-cf63-4466-9ae3-4b849c3ee03b: PCI host bridge to bus cf63:00 
[    6.947955] pci_bus cf63:00: root bus resource [mem 0xfe0000000-0xfe00fffff window] 
[    6.948805] pci cf63:00:02.0: [15b3:1016] type 00 class 0x020000 
[    6.957487] pci cf63:00:02.0: reg 0x10: [mem 0xfe0000000-0xfe00fffff 64bit pref] 
[    7.035464] pci cf63:00:02.0: enabling Extended Tags 
[    7.040811] pci cf63:00:02.0: 0.000 Gb/s available PCIe bandwidth, limited by Unknown x0 link at cf63:00:02.0 (capable of 63.008 Gb/s with 8.0 GT/s PCIe x8 link) 
[    7.041264] pci cf63:00:02.0: BAR 0: assigned [mem 0xfe0000000-0xfe00fffff 64bit pref] 

已检测到列出 GUID(由 Azure 主机分配)的 PCI 设备。 系统会根据 GUID 向其分配 PCI 域 ID(在这种情况下为 0xcf63)。 在 VM 所有可用 PCI 设备中,PCI 域 ID 必须唯一。 此唯一性要求涉及 VM 中可能存在的其他 Mellanox VF 接口、GPU、NVMe 设备等。

[    7.128515] mlx5_core cf63:00:02.0: firmware version: 14.25.8362 
[    7.139925] mlx5_core cf63:00:02.0: handle_hca_cap:524:(pid 12): log_max_qp value in current profile is 18, changing it to HCA capability limit (12) 
[    7.342391] mlx5_core cf63:00:02.0: MLX5E: StrdRq(0) RqSz(1024) StrdSz(256) RxCqeCmprss(0) 

已检测到使用 mlx5 驱动程序的 Mellanox VF,并且 mlx5 驱动程序已开始对设备执行初始化。

[    7.465085] hv_netvsc 000d3af5-76bd-000d-3af5-76bd000d3af5 eth0: VF registering: eth1 
[    7.465119] mlx5_core cf63:00:02.0 eth1: joined to eth0 

正在使用 netvsc.驱动程序的对应合成接口已检测到匹配的 VF。 mlx5 驱动程序识别其已与合成接口捆绑。

[    7.466064] mlx5_core cf63:00:02.0 eth1: Disabling LRO, not supported in legacy RQ 
[    7.480575] mlx5_core cf63:00:02.0 eth1: Disabling LRO, not supported in legacy RQ 
[    7.480651] mlx5_core cf63:00:02.0 enP53091s1np0: renamed from eth1 

Linux 内核最初将此 VF 接口命名为“eth1”。 系统根据 Udev 规则将其重命名,以避免与为合成接口指定的名称混淆。

[    8.087962] mlx5_core cf63:00:02.0 enP53091s1np0: Link up 

Mellanox VF 接口现已处于激活状态。

[    8.090127] hv_netvsc 000d3af5-76bd-000d-3af5-76bd000d3af5 eth0: Data path switched to VF: enP53091s1np0 
[    9.654979] hv_netvsc 000d3af5-76bd-000d-3af5-76bd000d3af5 eth0: Data path switched from VF: enP53091s1np0 

这些消息表示捆绑对的数据路径已切换为使用 VF 接口。 约 1.6 秒后,该数据路径将切换回使用合成接口。 此类切换过程在启动过程中可能会出现两三次,并且是配置初始化时的正常行为。

[    9.909128] mlx5_core cf63:00:02.0 enP53091s1np0: Link up 
[    9.910595] hv_netvsc 000d3af5-76bd-000d-3af5-76bd000d3af5 eth0: Data path switched to VF: enP53091s1np0 
[   11.411194] hv_netvsc 000d3af5-76bd-000d-3af5-76bd000d3af5 eth0: Data path switched from VF: enP53091s1np0 
[   11.532147] mlx5_core cf63:00:02.0 enP53091s1np0: Disabling LRO, not supported in legacy RQ 
[   11.731892] mlx5_core cf63:00:02.0 enP53091s1np0: Link up 
[   11.733216] hv_netvsc 000d3af5-76bd-000d-3af5-76bd000d3af5 eth0: Data path switched to VF: enP53091s1np0 

最终消息表示数据路径已切换为使用 VF 接口。 这一过程在 VM 的正常操作过程中为预期行为。

Azure 主机服务

当执行 Azure 主机服务时,在此服务期间,系统可能会将所有 VF 接口从 VM 中暂时删除。 服务完成后,系统会将 VF 接口重新添加至 VM,正常操作将继续进行。 尽管 VM 在没有 VF 接口的情况下运行,但网络流量仍会流过合成接口,而不会对应用程序造成任何中断。 在此环境中,Azure 主机服务可能包括更新 Azure 网络基础结构的各种组件或针对 Azure 主机虚拟机监控程序软件的完整升级。 此类服务事件在时间间隔内进行,具体取决于 Azure 基础结构的操作需求。 通常情况下,这些事件可能会在一年中出现多次。 如果应用程序仅与合成接口交互,则 VF 接口和合成接口之间的自动切换可确保工作负荷不受此类服务事件的干扰。 由于使用了合成接口,在这些过程中,延迟和 CPU 负载可能会更高。 此类过程的持续时间通常为 30 秒,但有时可能需要几分钟。

在服务事件期间删除和重新添加的 VF 接口在 VM 的“dmesg”输出中可见。 以下是相关的典型输出:

[   8160.911509] hv_netvsc 000d3af5-76bd-000d-3af5-76bd000d3af5 eth0: Data path switched from VF: enP53091s1np0 
[   8160.912120] hv_netvsc 000d3af5-76bd-000d-3af5-76bd000d3af5 eth0: VF unregistering: enP53091s1np0 
[   8162.020138] hv_netvsc 000d3af5-76bd-000d-3af5-76bd000d3af5 eth0: VF slot 1 removed 

数据路径已脱离 VF 接口,并已取消注册 VF 接口。 此时,Linux 已删除了 VF 接口的所有知识,并以如同未启用加速网络的方式般运行。

[   8225.557263] hv_netvsc 000d3af5-76bd-000d-3af5-76bd000d3af5 eth0: VF slot 1 added 
[   8225.557867] hv_pci e9ac9b28-cf63-4466-9ae3-4b849c3ee03b: PCI VMBus probing: Using version 0x10002 
[   8225.566794] hv_pci e9ac9b28-cf63-4466-9ae3-4b849c3ee03b: PCI host bridge to bus cf63:00 
[   8225.566797] pci_bus cf63:00: root bus resource [mem 0xfe0000000-0xfe00fffff window] 
[   8225.571556] pci cf63:00:02.0: [15b3:1016] type 00 class 0x020000 
[   8225.584903] pci cf63:00:02.0: reg 0x10: [mem 0xfe0000000-0xfe00fffff 64bit pref] 
[   8225.662860] pci cf63:00:02.0: enabling Extended Tags 
[   8225.667831] pci cf63:00:02.0: 0.000 Gb/s available PCIe bandwidth, limited by Unknown x0 link at cf63:00:02.0 (capable of 63.008 Gb/s with 8.0 GT/s PCIe x8 link) 
[   8225.667978] pci cf63:00:02.0: BAR 0: assigned [mem 0xfe0000000-0xfe00fffff 64bit pref] 

服务完成后重新添加 VF 接口时,将检测到拥有指定 GUID 的新 PCI 设备。 系统已为其分配与之前相同的 PCI 域 ID (0xcf63)。 针对重新添加的 VF 接口的处理方式与在初始启动过程中处理的方式类似。

[   8225.679672] mlx5_core cf63:00:02.0: firmware version: 14.25.8362 
[   8225.888476] mlx5_core cf63:00:02.0: MLX5E: StrdRq(0) RqSz(1024) StrdSz(256) RxCqeCmprss(0) 
[   8226.021016] hv_netvsc 000d3af5-76bd-000d-3af5-76bd000d3af5 eth0: VF registering: eth1 
[   8226.021058] mlx5_core cf63:00:02.0 eth1: joined to eth0 
[   8226.021968] mlx5_core cf63:00:02.0 eth1: Disabling LRO, not supported in legacy RQ 
[   8226.026631] mlx5_core cf63:00:02.0 eth1: Disabling LRO, not supported in legacy RQ 
[   8226.026699] mlx5_core cf63:00:02.0 enP53091s1np0: renamed from eth1 
[   8226.265256] mlx5_core cf63:00:02.0 enP53091s1np0: Link up 

mlx5 驱动程序会初始化 VF 接口,接口现在可正常运行。 此时的输出与初始启动时的输出类似。

[   8226.267380] hv_netvsc 000d3af5-76bd-000d-3af5-76bd000d3af5 eth0: Data path switched to VF: enP53091s1np0 

数据路径已切换回使用 VF 接口。

在未处于运行状态的 VM 中禁用/启用加速网络

可使用 Azure CLI 在未处于运行状态的 VM 中的虚拟 NIC 上开启加速网络。 例如:

$ az network nic update --name u1804895 --resource-group testrg --accelerated-network false 

禁用来宾 VM 中启用的加速网络将生成“dmesg”输出。 这与系统在 Azure 主机维护期间删除 VF 接口的输出相同。 而启用加速网络则会生成与在 Azure 主机服务后读取 VF 接口时相同的“dmesg”输出。 这些 Azure CLI 命令可用于模拟 Azure 主机服务。 使用这些命令,你可以验证你的应用程序不会错误地依赖于与 VF 接口的直接交互。

后续步骤