NET_FAILOVER

概述

net_failover 驱动程序通过 API 提供自动故障转移机制,用于创建和销毁故障转移主 netdev,并管理通过通用故障转移基础设施注册的主和备用从 netdev。

故障转移 netdev 充当主设备并控制 2 个从设备。 原始半虚拟化接口注册为“备用”从 netdev,并且具有相同 MAC 的 passthru/vf 设备注册为“主”从 netdev。“备用”和“故障转移”netdev 都与相同的“pci”设备相关联。 用户通过“故障转移”netdev 访问网络接口。 当“故障转移”netdev 可用且链路启动并运行时,它选择“主”netdev 作为默认的传输设备。

半虚拟化驱动程序可以使用此功能来启用备用的低延迟数据路径。 当 VF 被拔出时,它还可以通过故障转移到半虚拟化数据路径,从而实现虚拟机直接连接 VF 的虚拟机监控程序控制的实时迁移。

virtio-net 加速数据路径:STANDBY 模式

net_failover 以透明的方式为启用 virtio-net 的虚拟机启用虚拟机监控程序控制的加速数据路径,而无需/最小化访客用户空间更改。

为了支持这一点,虚拟机监控程序需要在 virtio-net 接口上启用 VIRTIO_NET_F_STANDBY 功能,并将相同的 MAC 地址分配给 virtio-net 和 VF 接口。

这是一个 libvirt XML 片段示例,显示了此类配置

<interface type='network'>
  <mac address='52:54:00:00:12:53'/>
  <source network='enp66s0f0_br'/>
  <target dev='tap01'/>
  <model type='virtio'/>
  <driver name='vhost' queues='4'/>
  <link state='down'/>
  <teaming type='persistent'/>
  <alias name='ua-backup0'/>
</interface>
<interface type='hostdev' managed='yes'>
  <mac address='52:54:00:00:12:53'/>
  <source>
    <address type='pci' domain='0x0000' bus='0x42' slot='0x02' function='0x5'/>
  </source>
  <teaming type='transient' persistent='ua-backup0'/>
</interface>

在此配置中,第一个设备定义用于 virtio-net 接口,它充当“持久”设备,指示此接口将始终插入。 这是通过“teaming”标记指定的,该标记的必需属性 type 具有值“persistent”。 virtio-net 设备的链路状态设置为“down”,以确保“故障转移”netdev 首选 VF 直通设备用于正常通信。 virtio-net 设备将在实时迁移期间启动,以允许不间断的通信。

第二个设备定义用于 VF 直通接口。 此处提供了带有类型“transient”的“teaming”标记,指示该设备可能会定期拔出。 提供了第二个属性“persistent”,并指向为 virtio-net 设备声明的别名。

使用上述配置引导 VM 将导致在 VM 中创建以下 3 个接口

4: ens10: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default qlen 1000
    link/ether 52:54:00:00:12:53 brd ff:ff:ff:ff:ff:ff
    inet 192.168.12.53/24 brd 192.168.12.255 scope global dynamic ens10
       valid_lft 42482sec preferred_lft 42482sec
    inet6 fe80::97d8:db2:8c10:b6d6/64 scope link
       valid_lft forever preferred_lft forever
5: ens10nsby: <BROADCAST,MULTICAST> mtu 1500 qdisc fq_codel master ens10 state DOWN group default qlen 1000
    link/ether 52:54:00:00:12:53 brd ff:ff:ff:ff:ff:ff
7: ens11: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq master ens10 state UP group default qlen 1000
    link/ether 52:54:00:00:12:53 brd ff:ff:ff:ff:ff:ff

在此,ens10 是“故障转移”主接口,ens10nsby 是从属“备用”virtio-net 接口,而 ens11 是从属“主”VF 直通接口。

这里要注意的一点是,一些用户空间网络配置守护程序,如 systemd-networkd、ifupdown 等,不理解“net_failover”设备; 并且在第一次启动时,VM 最终可能会从 DHCP 服务器获得“故障转移”设备和 VF 的 IP 地址(相同或不同)。 这将导致与 VM 失去连接。 因此,可能需要对这些网络配置守护程序进行一些调整,以确保仅在“故障转移”设备上收到 IP。

以下是与 Debian 云映像上找到的“cloud-ifupdown-helper”脚本一起使用的补丁片段

::
@@ -27,6 +27,8 @@ do_setup() {

local working=”$cfgdir/.$INTERFACE” local final=”$cfgdir/$INTERFACE”

  • if [ -d “/sys/class/net/${INTERFACE}/master” ]; then exit 0; fi

  • if ifup --no-act “$INTERFACE” > /dev/null 2>&1; then

    # interface is already known to ifupdown, no need to generate cfg log “Skipping configuration generation for $INTERFACE”

具有 SR-IOV VF 和 virtio-net 的 VM 在 STANDBY 模式下的实时迁移

net_failover 还通过在 VF 拔出时自动故障转移到半虚拟化数据路径,从而支持虚拟机监控程序控制的实时迁移到具有直接连接 SR-IOV VF 设备的 VM。

这是一个示例脚本,显示了从源虚拟机监控程序启动实时迁移的步骤。 注意:假定 VM 连接到软件桥“br0”,该桥具有连接到它的单个 VF 以及 VM 的 vnet 设备。 这不是传递给 VM 的 VF(在 vf.xml 文件中看到)。

# cat vf.xml
<interface type='hostdev' managed='yes'>
  <mac address='52:54:00:00:12:53'/>
  <source>
    <address type='pci' domain='0x0000' bus='0x42' slot='0x02' function='0x5'/>
  </source>
  <teaming type='transient' persistent='ua-backup0'/>
</interface>

# Source Hypervisor migrate.sh
#!/bin/bash

DOMAIN=vm-01
PF=ens6np0
VF=ens6v1             # VF attached to the bridge.
VF_NUM=1
TAP_IF=vmtap01        # virtio-net interface in the VM.
VF_XML=vf.xml

MAC=52:54:00:00:12:53
ZERO_MAC=00:00:00:00:00:00

# Set the virtio-net interface up.
virsh domif-setlink $DOMAIN $TAP_IF up

# Remove the VF that was passthrough'd to the VM.
virsh detach-device --live --config $DOMAIN $VF_XML

ip link set $PF vf $VF_NUM mac $ZERO_MAC

# Add FDB entry for traffic to continue going to the VM via
# the VF -> br0 -> vnet interface path.
bridge fdb add $MAC dev $VF
bridge fdb add $MAC dev $TAP_IF master

# Migrate the VM
virsh migrate --live --persistent $DOMAIN qemu+ssh://$REMOTE_HOST/system

# Clean up FDB entries after migration completes.
bridge fdb del $MAC dev $VF
bridge fdb del $MAC dev $TAP_IF master

在目标虚拟机监控程序上,在迁移开始之前创建共享桥“br0”,并将来自目标 PF 的 VF 添加到该桥。 类似地,添加了适当的 FDB 条目。

以下脚本在迁移完成后在目标虚拟机监控程序上执行,它将 VF 重新连接到 VM 并关闭 virtio-net 接口。

::

# reattach-vf.sh #!/bin/bash

bridge fdb del 52:54:00:00:12:53 dev ens36v0 bridge fdb del 52:54:00:00:12:53 dev vmtap01 master virsh attach-device --config --live vm01 vf.xml virsh domif-setlink vm01 vmtap01 down