Linux 및 FreeBSD VM에서 가속화된 네트워킹의 작동 방식

Azure에서 VM을 만들면 해당 구성의 각 가상 NIC에 대해 가상 네트워크 인터페이스가 만들어집니다. 가상 인터페이스는 VMbus 디바이스이며 netvsc 드라이버를 사용합니다. 이 가상 인터페이스를 사용하는 네트워크 패킷은 Azure 호스트의 가상 스위치를 통해 데이터 센터 실제 네트워크로 흐릅니다.

VM이 가속화된 네트워킹으로 구성된 경우 구성된 각 가상 NIC에 대해 두 번째 네트워크 인터페이스가 만들어집니다. 두 번째 인터페이스는 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 인프라는 Azure 호스트의 VM 배치를 제어합니다. VM 배포에서 사용하는 물리적 NIC를 지정하는 고객 옵션이 없으므로 VM에는 두 드라이버가 모두 포함되어야 합니다. 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 인터페이스를 통해 이동하고 있는 것입니다.

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 인터페이스의 초기화 및 구성과 관련된 많은 메시지를 표시합니다. 가상 인터페이스와의 결합에 대한 정보도 표시합니다. 이러한 메시지를 이해하면 프로세스의 문제를 식별하는 데 도움이 될 수 있습니다.

다음은 VF 인터페이스와 관련된 줄만 잘라낸 dmesg 명령의 출력 예제입니다. 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가 있는 PCI 디바이스(Azure 호스트에서 할당함)가 검색되었습니다. GUID에 따라 PCI 도메인 ID(이 경우 0xcf63)가 할당됩니다. PCI 도메인 ID는 VM에서 사용할 수 있는 모든 PCI 디바이스에서 고유해야 합니다. 이 고유성 요구 사항은 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 호스트 서비스 중에 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 인터페이스와의 직접적인 상호 작용을 잘못 사용하지 않는지 확인할 수 있습니다.

다음 단계