虚拟化技术 — SR-IOV 单根 I/O 虚拟化

目录

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 个核心功能的支持:

  1. BAR 基地址映射:将 VF 的 PCIe BAR 映射到 PF 的 PCIe BAR,从而实现通过 VF 对 PF 硬件资源的访问。
  2. 虚拟 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 点:

  1. 同主机 VM 之间的东西向流量不经过集成了网络流量采集协议的 TOR 等设备。
  2. VM 流出主机的流量不携带任何可采集的标识信息。

所以,解决这些问题的办法对应有 2 点:

  1. 强制 VM 的流量必须经过采集点。
  2. 强制 VM 的流量必须携带采集标识。

这就是所谓的虚拟机流量感知技术,目前主要有 2 大流派:

  1. 思科和 VMware 主推的是 VN-Tag 技术,标准为 802.1Qbh BPE(Bridge Port Extension,端口扩展设备):尝试从接入层到汇聚层提供一个完整的虚拟化网络解决方案,尽可能达到软件定义一个可控网络的目的。它扩展了传统的网络协议,因此需要新的网络设备支持,成本较高。

  2. 惠普、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 的网卡。反之亦然。

如下图,多通道技术可组合出多种方案:

  1. 管理员通过多通道技术解决 VEB 与 VEPA 共享一个外部网络(网卡)的需求,多个 VEB 或 VEPA 共享同一个物理网卡。管理员可以为特定的虚拟机使用 VEB,以获得较好的交换性能;也可以为其他虚拟机使用 VEPA,以获得更好的网络控制策略可实施性和流量可视性。

  2. 直接将一个虚拟机映射到物理网卡上(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:

  1. 查看 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
...
  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>
  1. Shut down the guest.

  2. 根据上述设备信息编写 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>
  1. 将 VF 到 VM。
$ virsh attach-device VM1 /tmp/new-device.xml --live --config
Device attached successfully
  1. 查看 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>
  1. 启动虚拟机
virsh start MyGuest
  1. 进入 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
  1. 卸载 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 在迁移过程中产生的流量,具体的操作如下:

  1. 为 SR-IOV 虚拟机添加一个 normal(OvS)或者 indirect mode SR-IOV(macvtap SR-IOV)的 Port。
  2. 在 GuestOS 中将原有的 SR-IOV Port 与 Step1 添加的 Port 做一个 Bond。
  3. 对 SR-IOV 虚拟机执行热迁移。
  4. 迁移完成后,登录 GuestOS 执行 ifup <vnic> 执行拉起原有的 SR-IOV Port。
  5. 删除 Step1 中添加的 Port。

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/Jmilk/article/details/130253170