目录
文章目录
- 目录
- SR-IOV
- SR-IOV VEB
- SR-IOV VEPA
- SR-IOV Multi-Channel
- SR-IOV OvS
- SR-IOV 的应用
- 使能 SR-IOV VFs
- 挂在 VF 到 KVM 虚拟机中
- SR-IOV 的 NUMA 亲和性
- VF 的网络配置
- VFs Bonding
- SR-IOV 虚拟机的热迁移问题
SR-IOV
传统的 I/O 虚拟化方案需要 VMM 来捕获和模拟 VM 的 I/O 操作,当 VMM 需要处理多台 VMs 对同一个 I/O 外设的并发访问和隔离时,VMM 就成为了一个性能瓶颈。
基于 Intel VT-d 硬件辅助的 I/O 虚拟化方案中,通过 I/O MMU 结合 DMA Remapping Feature 和 Interrupt Remapping Feature 技术可以实现将整个 PCIe 设备 Passthrough(直通)给 VM 使用,而无需 VMM 的参与,但问题是 VMs 的数量太多,但物理外设只有少量的几个。
在这样的背景下,Intel 等主流网卡厂商在 PCI-SIG 推出了一项基于 Intel VT-d 硬件辅助虚拟化技术实现的 PCIe 设备虚拟化技术标准 SR-IOV(Single-Root I/O Virtualization,单根 I/O 虚拟化)。可见,SR-IOV 就是转为 VM 而设计的。
SR-IOV 通过在物理网卡中加入了一些硬件组件,实现将一个物理设备(PF)虚拟成多个虚拟设备(VFs):
-
PF(Physical Function,物理功能):PF 作为管理者的角色,负责管理所有物理资源以及 VFs 的生命周期,会为每个 VF 分配资源,例如:MAC 地址和 Rx/Tx Queues。操作系统或 VMM 需要通过 PF 来对 VFs 进行配置和使用。
-
VF(Virtual Function,虚拟功能):是一个非常轻量化的 “虚拟通道”,仅仅包含了 I/O 功能,支持单独配置 VLAN 标签、QoS 策略等网络属性。每个 VF 都具有自己的 PCIe Configuration Space(配置空间)、一个 PCIe BDF、一个 MSI-X 中断、一个 MAC 地址和一些 Rx/Tx Queues。此外,就共享 PF 的其他物理资源。
SR-IOV 技术的实现需要 2 个核心功能的支持:
- BAR 基地址映射:将 VF 的 PCIe BAR 映射到 PF 的 PCIe BAR,从而实现通过 VF 对 PF 硬件资源的访问。
- 虚拟 I/O 队列:将 VF 的 I/O 请求映射到 PF 中的共享队列或者 VF 专用队列中,以提高虚拟机的网络 I/O 性能。
缺省情况下,SR-IOV NIC 的 VF 处于禁用状态,此时 PF 充当传统的 PCIe 设备。一旦启用了 VF,PF 通过寄存器创建 VF,并通过 PF BDF 访问各个 VF 的 PCIe BAR。每个 VF 都具有一个虚拟的 PCIe Configuration Space,用于映射其寄存器集。VF 设备驱动程序对寄存器集进行操作以使用其 I/O 功能。
SR-IOV VEB
SR-IOV VEB(Virtual Ethernet Bridge,虚拟以太网交换机)是一种硬件实现的虚拟交换功能,提供高性能的二层交换转发能力。
如下图 Intel x710 VEB 所示,VMM 通过 PF 来管理 VEB 的配置,在启用了 VEB 的场景中,VEB 将 PF 和所有的 VFs 都连接了起来,通过 VF 和 PF 的 MAC 地址以及 VLAN ID 来进行二层转发。
-
Ingress(从外部网络进入到网卡):如果 Frame 的 dstMAC 和 VLAN ID 都匹配到某一个 VF,那么 Frame 就会转发到该 VF,否则 Frame 进入 PF。如果 Frame 的 dstMAC 是一个广播地址,那么 Frame 会在同一个 VLAN 中进行广播。
-
Egress(从 PF 或者 VF 发出):如果 Frame 的 MAC 地址不匹配同一 VLAN 内的任何端口(VF 或 PF),那么 Frame 从网卡向外部网络发出,否则会直接在内部转发给对应的 PF 或 VF。如如果 Frame 的 dstMAC 是一个广播地址,那么 Frame 会在同一个 VLAN 中、以及向网卡外部进行广播。
可见,SR-IOV VEB 的另一个特性就是同一主机的 VF VM 之间的东西流量不需要经过 TOR 交换机,SR-IOV NIC 通过查讯内部的 MAC Table(根据网卡型号做静态或动态配置)进行转发处理。
SR-IOV VEPA
SR-IOV VEB 具有高性能的优点,但在实际的生产环境中也带来了另外的一些缺点,例如:缺乏网络流量的可视化、缺乏网络控制策略的实施能力、缺乏管理可扩展性等。
造成这些问题的原因主要有 2 点:
- 同主机 VM 之间的东西向流量不经过集成了网络流量采集协议的 TOR 等设备。
- VM 流出主机的流量不携带任何可采集的标识信息。
所以,解决这些问题的办法对应有 2 点:
- 强制 VM 的流量必须经过采集点。
- 强制 VM 的流量必须携带采集标识。
这就是所谓的虚拟机流量感知技术,目前主要有 2 大流派:
-
思科和 VMware 主推的是 VN-Tag 技术,标准为 802.1Qbh BPE(Bridge Port Extension,端口扩展设备):尝试从接入层到汇聚层提供一个完整的虚拟化网络解决方案,尽可能达到软件定义一个可控网络的目的。它扩展了传统的网络协议,因此需要新的网络设备支持,成本较高。
-
惠普、Juniper、IBM、Qlogic、Brocade 主推的是 VEPA(Virtual Ethernet Port Aggregator,虚拟以太端口汇聚器),标准为 802.1Qbg EVB(Edge Virtual Bridging,边缘虚拟交换机):尝试以较低成本利用现有设备改进软件模拟的网络。
这里我们主要讨论 SR-IOV VEPA 技术,如下图 Intel x710 VEPA 所示,使用 VEPA 替换了 VEB。
VEPA 的核心思想是:将 VM 产生的网络流量强制转发到上联的 TOR 交换机进行转发,即便是同主机中的流量。但同时我们也知道,传统交换机的是不允许 Frame 从 Input Port 原路返回的,所以需要支持 VEPA 标准的交换机才可以实现。如下图,由 VM1 发往 VM2 或 VM3 的报文,首先被发往外部交换机,查表后,Frame 沿原路返回服务器,这种工作模式称之为发卡弯(hairpin turn)转发。
SR-IOV Multi-Channel
在数通网络里,想要标识流量,肯定是要使用特定的字段来做。HP 使用的是 QinQ(802.1ad),在标准 VEPA 的基础上使用 QinQ 的 S-TAG 来标识虚拟机流量,形成了增强型 VEPA,即:802.1Qbg Multi-Channel(多通道技术)。
多通道技术是一种通过给虚拟机报文增加 IEEE 标准报文标签,以增强 VEPA 功能的方案。通过标签机制,可以实现 VEB、Director IO 和 VEPA 的混合部署方案,借助多通道技术,管理员可以根据网络安全、性能以及可管理等方面的需求,灵活的选择虚拟机与外部网络的接入方案(VEB、Director IO 或 VEPA)。多通道技术由 HP 公司提出,最终被 IEEE 802.1 工作组接纳为 EVB 标准的一种可选方案。
多通道技术方案将交换机端口或网卡划分为多个逻辑通道,并且各通道间逻辑隔离。每个逻辑通道可根据用户需要定义成 VEB、VEPA 或 Director IO 的任何一种。每个逻辑通道作为一个独立的到外部网络的通道进行处理。多通道技术借用了 802.1ad S-TAG(QinQ)标准,通过一个附加的 S-TAG 和 VLAN-ID 来区分网卡或交换机端口上划分的不同逻辑通道。
多通道技术使外部物理交换机通过报文的 S-TAG 识别网络流量来自哪个 VEAP/VEB,或来自哪个 Director IO 的网卡。反之亦然。
如下图,多通道技术可组合出多种方案:
-
管理员通过多通道技术解决 VEB 与 VEPA 共享一个外部网络(网卡)的需求,多个 VEB 或 VEPA 共享同一个物理网卡。管理员可以为特定的虚拟机使用 VEB,以获得较好的交换性能;也可以为其他虚拟机使用 VEPA,以获得更好的网络控制策略可实施性和流量可视性。
-
直接将一个虚拟机映射到物理网卡上(SR-IOV VF Director IO),而其它的虚拟机仍然通过 VEB 或 VEPA 共享物理网卡。
SR-IOV OvS
由于 SR-IOV 只能在操作系统中通过 CLI 的方式完成配置和使用,而不具备一个原生的 SDN 控制面,所以需要额外开发相关的组件(e.g. Neutron sriov-agent),这也让 SR-IOV 的使用变得困难。
好在随着 SmartNIC 和 DPU 的兴起,将 SDN 技术和 SR-IOV 结合起来使用的技术也越来越成熟了。例如最早由 Mellanox 提出的 SmartNIC OVS Fastpath 硬件卸载方案中,就将 VF 作为了连接 VM 和 OvS Fastpath 的虚拟通道,兼具了可编程的灵活性和高性能。
SR-IOV 的应用
使能 SR-IOV VFs
Step 1. Ensure SR-IOV and VT-d are enabled in BIOS.
Step 2. Enable I/O MMU in Linux by adding intel_iommu=on to the kernel parameters, for example, using GRUB.
...
linux16 /boot/vmlinuz-3.10.0-862.11.6.rt56.819.el7.x86_64 root=LABEL=img-rootfs ro console=tty0 console=ttyS0,115200n8 crashkernel=auto rhgb quiet intel_·=on iommu=pt isolcpus=2-3,8-9 nohz=on nohz_full=2-3,8-9 rcu_nocbs=2-3,8-9 intel_pstate=disable nosoftlockup default_hugepagesz=1G hugepagesz=1G hugepages=16 LANG=en_US.UTF-8
...
Step 3. Create the VFs via the PCI SYS interface(e.g. enp129s0f0, enp129s0f1).
$ cat /etc/sysconfig/network-scripts/ifcfg-enp129s0f0
DEVICE="enp129s0f0"
BOOTPROTO="dhcp"
ONBOOT="yes"
TYPE="Ethernet"
$ cat /etc/sysconfig/network-scripts/ifcfg-enp129s0f1
DEVICE="enp129s0f1"
BOOTPROTO="dhcp"
ONBOOT="yes"
TYPE="Ethernet"
$ echo 16 > /sys/class/net/enp129s0f0/device/sriov_numvfs
$ echo 16 > /sys/class/net/enp129s0f1/device/sriov_numvfs
Step 4. Verify that the VFs have been created and are in up state.
$ lspci | grep Ethernet
03:00.0 Ethernet controller: Intel Corporation I350 Gigabit Network Connection (rev 01)
03:00.1 Ethernet controller: Intel Corporation I350 Gigabit Network Connection (rev 01)
81:00.0 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01)
81:00.1 Ethernet controller: Intel Corporation 82599ES 10-Gigabit SFI/SFP+ Network Connection (rev 01)
81:10.0 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:10.1 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:10.2 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:10.3 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:10.4 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:10.5 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:10.6 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:10.7 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:11.0 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:11.1 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:11.2 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:11.3 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:11.4 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:11.5 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:11.6 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:11.7 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:12.0 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:12.1 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:12.2 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:12.3 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:12.4 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:12.5 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:12.6 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:12.7 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:13.0 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:13.1 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:13.2 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:13.3 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:13.4 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:13.5 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:13.6 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
81:13.7 Ethernet controller: Intel Corporation 82599 Ethernet Controller Virtual Function (rev 01)
$ ip link show enp129s0f0
4: enp129s0f0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
link/ether 90:e2:ba:34:fb:32 brd ff:ff:ff:ff:ff:ff
vf 0 MAC be:40:5c:21:98:31, spoof checking on, link-state auto, trust off, query_rss off
vf 1 MAC b2:e9:21:c7:4a:e0, spoof checking on, link-state auto, trust off, query_rss off
vf 2 MAC ae:75:99:e3:dc:1d, spoof checking on, link-state auto, trust off, query_rss off
vf 3 MAC 66:73:75:d7:15:a8, spoof checking on, link-state auto, trust off, query_rss off
vf 4 MAC b6:04:f7:ed:ad:36, spoof checking on, link-state auto, trust off, query_rss off
vf 5 MAC a2:ad:62:61:2a:bd, spoof checking on, link-state auto, trust off, query_rss off
vf 6 MAC 1a:be:5b:ab:b9:fd, spoof checking on, link-state auto, trust off, query_rss off
vf 7 MAC 3a:63:44:d9:8f:44, spoof checking on, link-state auto, trust off, query_rss off
vf 8 MAC 7e:fe:c7:f6:9d:5d, spoof checking on, link-state auto, trust off, query_rss off
vf 9 MAC 4a:e9:57:84:50:29, spoof checking on, link-state auto, trust off, query_rss off
vf 10 MAC 0a:a7:e7:ff:ee:c8, spoof checking on, link-state auto, trust off, query_rss off
vf 11 MAC 02:58:45:61:15:a7, spoof checking on, link-state auto, trust off, query_rss off
vf 12 MAC 2a:75:77:ff:c1:6d, spoof checking on, link-state auto, trust off, query_rss off
vf 13 MAC be:99:4d:22:5a:87, spoof checking on, link-state auto, trust off, query_rss off
vf 14 MAC 52:44:5f:d7:fb:e3, spoof checking on, link-state auto, trust off, query_rss off
vf 15 MAC b2:16:c3:a2:5f:c7, spoof checking on, link-state auto, trust off, query_rss off
$ ip link show enp129s0f1
5: enp129s0f1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP mode DEFAULT group default qlen 1000
link/ether 90:e2:ba:34:fb:33 brd ff:ff:ff:ff:ff:ff
vf 0 MAC 86:64:1f:09:bb:d5, spoof checking on, link-state auto, trust off, query_rss off
vf 1 MAC a2:0f:71:30:31:31, spoof checking on, link-state auto, trust off, query_rss off
vf 2 MAC 0e:b1:06:54:3f:75, spoof checking on, link-state auto, trust off, query_rss off
vf 3 MAC ca:35:be:e2:ea:70, spoof checking on, link-state auto, trust off, query_rss off
vf 4 MAC 26:35:04:86:42:50, spoof checking on, link-state auto, trust off, query_rss off
vf 5 MAC e2:fe:00:1a:74:f7, spoof checking on, link-state auto, trust off, query_rss off
vf 6 MAC 6a:ef:8b:61:a6:c0, spoof checking on, link-state auto, trust off, query_rss off
vf 7 MAC fa:61:e2:f9:a1:2d, spoof checking on, link-state auto, trust off, query_rss off
vf 8 MAC 16:8c:47:34:61:03, spoof checking on, link-state auto, trust off, query_rss off
vf 9 MAC f6:85:2d:85:8e:a3, spoof checking on, link-state auto, trust off, query_rss off
vf 10 MAC 0e:4b:d8:0a:9a:7f, spoof checking on, link-state auto, trust off, query_rss off
vf 11 MAC f2:27:a6:ee:da:be, spoof checking on, link-state auto, trust off, query_rss off
vf 12 MAC 82:37:55:7f:cd:19, spoof checking on, link-state auto, trust off, query_rss off
vf 13 MAC 2e:30:e1:3b:c1:a1, spoof checking on, link-state auto, trust off, query_rss off
vf 14 MAC 4e:56:c7:3f:e5:77, spoof checking on, link-state auto, trust off, query_rss off
vf 15 MAC 56:21:25:bd:ac:18, spoof checking on, link-state auto, trust off, query_rss off
NOTE: If the interfaces are down, set them to up before launching a guest, otherwise the instance will fail to spawn.
ip link set <interface> up
# e.g.
enp129s0f1: <NO-CARRIER,BROADCAST,MULTICAST,UP>
Step 5. Persist created VFs on reboot
echo "echo '7' > /sys/class/net/eth3/device/sriov_numvfs" >> /etc/rc.local
挂在 VF 到 KVM 虚拟机中
使用指令 -device vfio-pci,host 来将指定的 VF Passthrough 到 KVM 虚拟机。
qemu-system-x86_64 -enable-kvm -drive file=<vm img>,if=virtio -cpu host -smp 16 -m 16G \
-name <vm name> -device vfio-pci,host=<vf pci bus addr> -device vfio-pci,host=<vf pci bus addr> -vnc :1 -net none
也可以以手动挂载 PCI 设备到 VM 的方式来挂载一个 VF:
- 查看 PCI 设备清单:
[root@overcloud-compute-0 ~]# virsh nodedev-list | grep pci
pci_0000_00_00_0
pci_0000_00_01_0
pci_0000_00_01_1
...
- 查看指定 PCI 设备的详情,关注 PCI 的 BDF 信息,例如:
<address domain='0x0000' bus='0x81' slot='0x10' function='0x2'/>
。
$ virsh nodedev-dumpxml pci_0000_81_10_2
<device>
<name>pci_0000_81_10_2</name>
<path>/sys/devices/pci0000:80/0000:80:03.0/0000:81:10.2</path>
<parent>pci_0000_80_03_0</parent>
<driver>
<name>ixgbevf</name>
</driver>
<capability type='pci'>
<domain>0</domain>
<bus>129</bus>
<slot>16</slot>
<function>2</function>
<product id='0x10ed'>82599 Ethernet Controller Virtual Function</product>
<vendor id='0x8086'>Intel Corporation</vendor>
<capability type='phys_function'>
<address domain='0x0000' bus='0x81' slot='0x00' function='0x0'/>
</capability>
<iommuGroup number='46'>
<address domain='0x0000' bus='0x81' slot='0x10' function='0x2'/>
</iommuGroup>
<numa node='1'/>
<pci-express>
<link validity='cap' port='0' width='0'/>
<link validity='sta' width='0'/>
</pci-express>
</capability>
</device>
-
Shut down the guest.
-
根据上述设备信息编写 new-dev XML 文件
$ cat /tmp/new-device.xml
<interface type='hostdev' managed='yes'>
<source>
<address type='pci' domain='0x0000' bus='0x81' slot='0x10' function='0x2' />
</source>
</interface>
- 将 VF 到 VM。
$ virsh attach-device VM1 /tmp/new-device.xml --live --config
Device attached successfully
- 查看 VM 的 XML 更新。
$ virsh dumpxml vm1
...
<devices>
...
<interface type='hostdev' managed='yes'>
<mac address='52:54:00:f0:d3:b8'/>
<driver name='kvm'/>
<source>
<address type='pci' domain='0x0000' bus='0x81' slot='0x10' function='0x2' />
</source>
<alias name='hostdev0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
</interface>
...
</devices>
- 启动虚拟机
virsh start MyGuest
- 进入 GuestOS 查看网卡信息
$ ip addr show eth4
4: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
link/ether 2c:53:4a:02:20:3d brd ff:ff:ff:ff:ff:ff
inet 192.168.99.169/24 brd 192.168.99.255 scope global eth1
valid_lft forever preferred_lft forever
inet6 fe80::5054:ff:fe3b:6128/64 scope link
valid_lft forever preferred_lft forever
- 卸载 VM 的 PCI 设备。
$ virsh nodedev-dettach pci_0000_06_10_0
Device pci_0000_06_10_0 detached
SR-IOV 的 NUMA 亲和性
PCIe 设备的 DMA 都具有 NUMA 亲和性特性,SR-IOV 也不例外,为了让 VF Passthrough VM 具有更好的性能,通常会让 VM 的 vCPU 和 VF 运行在同一个 NUMA Node 中,
可以通过下述指令查看 SR-IOV 的 NUMA 亲和性。
# SR-IOV 网卡 enp129s0f0 属于 NUMA Node 1
$ cat /sys/class/net/enp129s0f0/device/numa_node
1
查看 VM1 的 vCPU 绑定情况:
$ virsh vcpupin VM1_uuid
VF 的网络配置
支持为 VF 配置 MAC 地址、VLAN Tag、混杂模式:
$ ip l |grep 5e:9c
vf 14 MAC fa:16:3e:90:5e:9c, vlan 19, spoof checking on, link-state auto, trust on, query_rss off
KVM 虚拟机的 XML 文件中也记录了 VF 设备的 VLAN ID,如下:
<interface type='hostdev' managed='yes'>
<mac address=' fa:aa:aa:aa:aa:aa '/>
<driver name='kvm'/>
<source>
<address type='pci' domain='0x0000' bus='0x02' slot='0x00' function='0x7'/>
</source>
<vlan>
<tag id='190'/>
</vlan>
<alias name='hostdev0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</interface>
VFs Bonding
在物理服务器中我们经常会将 2 个 Ethernet Ports 进行 Bond 来保证物理链路的高可用和带宽扩展。在 SR-IOV Passthrough 场景中同样可以将一张 SR-IOV 网卡的 2 个 PFs 上的各一个 VF 以 Bond 的方式接入到 VM。前提是这两个 VFs 的 MAC 地址必须配置为一样。
$ /etc/sysconfig/network-scripts/ifcfg-bond0
BONDING_MASTER=yes
BOOTPROTO=none
DEFROUTE=yes
DEVICE=bond0
NAME=bond0
ONBOOT=yes
TYPE=Bond
$ /etc/sysconfig/network-scripts/ifcfg-ens4
DEVICE=ens4
MASTER=bond0
ONBOOT=yes
SLAVE=yes
TYPE=Ethernet
$ /etc/sysconfig/network-scripts/ifcfg-ens5
DEVICE=ens5
MASTER=bond0
ONBOOT=yes
SLAVE=yes
TYPE=Ethernet
SR-IOV 虚拟机的热迁移问题
Passthrough 是 SR-IOV 设备的基本使用方式,使得多台 VMs 可以获得与裸金属主机上相比拟的性能。
值得注意的是,SR-IOV Passthrough 之后的 VM 的可迁移性会受到限制,因为 SR-IOV 的实现依赖 Intel VT-d 技术。当 VF 在 GuestOS 中完成初始化时,就建立了 GVA 和 HPA 之间的地址映射表,这种 “有状态” 的映射表在热迁移的过程中会被丢失掉。迁移时,必须执行 VF 的重挂载(重新建立地址映射表)。
一个实际的的现象就是对 VF Passthrough VM 执行迁移后,需要登录到 GuestOS 上手动的执行 ifup 指令,然后再获取到 IP 地址。在这个过程中,网络流量肯定是断开的。
一种 Workaround 的思路就是使用支持热迁移的 Port 来承接 SR-IOV Port 在迁移过程中产生的流量,具体的操作如下:
- 为 SR-IOV 虚拟机添加一个 normal(OvS)或者 indirect mode SR-IOV(macvtap SR-IOV)的 Port。
- 在 GuestOS 中将原有的 SR-IOV Port 与 Step1 添加的 Port 做一个 Bond。
- 对 SR-IOV 虚拟机执行热迁移。
- 迁移完成后,登录 GuestOS 执行
ifup <vnic>
执行拉起原有的 SR-IOV Port。 - 删除 Step1 中添加的 Port。