Linux および FreeBSD VM での高速ネットワークのしくみ

Azure で仮想マシン (VM) が作成されると、構成内の仮想 NIC ごとに合成ネットワーク インターフェイスが作成されます。 合成インターフェイスは VMbus デバイスで、netvsc ドライバーが使用されます。 この合成インターフェイスを使用するネットワーク パケットが、Azure ホスト内の仮想スイッチを経由し、データセンターの物理ネットワークまで流れます。

高速ネットワークを設定した VM が構成されると、構成された仮想 NIC ごとに 2 つ目のネットワーク インターフェイスが作成されます。 2 つ目のインターフェイスは、Azure ホストの物理ネットワーク NIC から提供される SR-IOV 仮想関数 (VF) です。 VF インターフェイスは Linux ゲストに PCI デバイスとして表示されます。 Azure ホストでは Mellanox の物理 NIC が使用されるため、Linux で Mellanox mlx4 または mlx5 ドライバーが使用されます。

ほとんどのネットワーク パケットが Linux ゲストと物理 NIC の間で直接送信され、仮想スイッチや、ホスト上で実行されるその他のソフトウェアは経由しません。 ハードウェアに直接アクセスするため、合成インターフェイスと比較して、ネットワーク待機時間が短く、ネットワーク パケットの処理に使用される CPU 時間も短くなります。

さまざまな Azure ホストでは、Mellanox 物理 NIC の異なるモデルが使用されています。 Linux は mlx4 と mlx5 のいずれのドライバーを使用するかを自動的に判別します。 Azure ホストへの VM の配置は、Azure インフラストラクチャによって制御されます。 VM デプロイで使用する物理 NIC を指定する顧客オプションがない場合、VM には両方のドライバーを含める必要があります。 VM が、停止または割り当てが解除された後に再起動されると、Mellanox 物理 NIC のモデルが異なるハードウェアに再デプロイされる可能性があります。 その結果、他の Mellanox ドライバーが使用される可能性があります。

VM イメージに Mellanox 物理 NIC のドライバーが含まれていない場合、ネットワーク機能は仮想 NIC のより遅い速度で動作し続けます。 ポータル、Azure CLI、Azure PowerShell には、高速ネットワーク機能が "有効" と表示されます。

FreeBSD では、Azure で実行する場合に Linux と同じ高速ネットワークがサポートされます。 この記事の残りの部分では、Linux について説明し、Linux の例を使用しますが、FreeBSD でも同じ機能を使用できます。

注意

この記事には、Microsoft が使用しなくなった "スレーブ" という用語への言及が含まれています。 ソフトウェアからこの用語を削除する時点で、該当用語がこの記事から削除されます。

結合

合成ネットワーク インターフェイスと VF インターフェイスは自動的にペアリングされ、アプリケーションで使用されるほとんどの面で単一のインターフェイスとして機能します。 netvsc ドライバーによって結合が行われます。 Linux ディストリビューションによっては、udev のルールとスクリプトが VF インターフェイスの名前付けとネットワークの構成に役立つ場合があります。

VM が複数の仮想 NIC で構成されている場合、それぞれに一意のシリアル番号が Azure ホストから提供されます。 これにより、Linux で仮想 NIC ごとに合成インターフェイスと VF インターフェイスを適切にペアリングできるようになります。

合成インターフェイスと VF インターフェイスの MAC アドレスは同じです。 これらが一緒になることで、VM 内の仮想 NIC とパケットを交換する他のネットワーク エンティティから見ると単一の NIC が構成されます。 合成インターフェイスと VF インターフェイスの両方が存在するため、他のエンティティで特別なアクションは実行されません。

どちらのインターフェイスも、Linux の ifconfig または ip addr コマンドを使用して表示できます。 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 ルールが原因で、enP\<n\> の形式で別の名前を持つ場合もあります。

特定のインターフェイスが合成インターフェイスか VF インターフェイスかは、インターフェイスで使用されるデバイス ドライバーを表示するシェル コマンド ラインを使用して判定できます。

$ ethtool -i <interface name> | grep driver

ドライバーが hv_netvsc の場合は、合成インターフェイスです。 VF インターフェイスには "mlx" を含むドライバー名があります。VF インターフェイスは、その flags フィールドに SLAVE が含まれていることからも識別可能です。 このフラグは、MAC アドレスが同じ合成インターフェイスの制御下にあることを示します。

IP アドレスは、合成インターフェイスにのみ割り当てられます。 ifconfig または ip addr 出力にも、この違いが表示されます。

アプリケーションの使用状況

アプリケーションは、他のネットワーク環境と同様に、合成インターフェイスとのみやりとりする必要があります。 送信ネットワーク パケットは netvsc ドライバーから 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 インターフェイスを介して流れています。

PCI デバイスとしての VF インターフェイスの存在は、lspci コマンドを使って確認できます。 たとえば、第 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 ドライバーが登録されました。

[    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) が割り当てられます。 PCI ドメイン ID は、VM で使用可能なすべての PCI デバイスで一意である必要があります。 この一意性の要件は、Mellanox VF インターフェイス、GPU、NVMe デバイスのほか、VM に存在する可能性がある他のデバイスに及びます。

[    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 秒後に切り替えられ、合成インターフェイスに戻ります。 このようなスイッチは、スタートアップ プロセス中に 2、3 回発生する可能性があり、構成が初期化される際の通常の動作です。

[    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 ホスト サービス中に、VM からすべての VF インターフェイスが一時的に削除される場合があります。 サービスが完了すると、VF インターフェイスがまた VM に追加されます。 通常の操作は続行されます。 VM が VF インターフェイスなしで動作している間、ネットワーク トラフィックは合成インターフェイスを介して流れ続け、アプリケーションが中断されることはありません。

これに関連して、Azure ホスト サービスには、Azure ネットワーク インフラストラクチャのコンポーネントの更新や、Azure ホスト ハイパーバイザー ソフトウェアの完全なアップグレードが含まれる場合があります。 このようなサービス イベントは、Azure インフラストラクチャの運用ニーズに応じた時間間隔で発生します。 これらのイベントは通常、1 年の間に数回発生します。

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 インターフェイスとの直接対話に依存していないことを確認できます。

次の手順