Single root input/output virtualization(SR-IOV), 是一种先进的虚拟化技术,以网卡为例,它可以在一个物理功能PF(一个网口)上开出多个虚拟功能(虚拟网卡)。
为了令虚拟机与外界的连接高效可靠,往往会采用直通网卡(PCIE Passthrough)的方法,但若是物理机中存在较多的虚拟机,这一方法便不再可行。此外,采取直通网卡的诸多虚拟机之间,并没有网络连接。
SR-IOV针对性的解决了以上两个问题,开启SR-IOV之后,物理网口PF与虚拟网口VFs(可以存在多个)间会建立一个虚拟交换机,这个虚拟交换机具有很好的性能,往往还支持RDMA等高级功能。倘若将VF直通进入虚拟机,这一虚拟机就会与外界、与其他挂在同一PF下的虚拟机,建立高效的连接。这些连接是绕过宿主机内核的,这将带来极好的网络性能。
Proxmox VE(PVE)是常用的虚拟化平台,本文将讨论,如何在PVE中打开SR-IOV。
1. 配置BIOS
在BIOS中打开下面这些选项
Vd-t, IO-MMU, SR-IOV
2. 开启iommu
修改grub文件
# vi /etc/default/grub在GRUB_CMDLINE_LINUX_DEFAULT项末尾加上下面的内容
# intel_iommu=on iommu=pt
检查IOMMO功能是否开启
dmesg | grep -e DMAR -e IOMMU -e AMD-Vi

显示 IOMMU enabled表示已开启
如果没有出现,那么在/etc/modprobe.d/的任意一个.conf下增加这些内容:
options vfio_iommu_type1 allow_unsafe_interrupts=1
然后
update-initramfs -u -k all
reboot查看支持多少个虚拟网卡:
| 1 | cat/sys/class/net/eno1/device/sriov_totalvfs |
开启虚拟数量:
| 1 | echo 7 > /sys/class/net/eno1/device/sriov_numvfs |
关启虚拟数量(修改数量必须先将虚拟数量改为0后才能开启):
echo 0 > /sys/class/net/eno1/device/sriov_numvfs
3. 编写service,在开机过程中打开SR-IOV VFs
# cd /etc/init.d
# vi net-sriov查看网卡名称与pci地址对应:
| 1 | ls-l /sys/class/net/ |

下面是示例内容,可根据具体情况修改
注册系统服务
cd /etc/systemd/system
vi sriov.service
填入内容
[Unit]
Description=Script to enable SR-IOV on boot
[Service]
Type=simple
#start SR-IOV
ExecStartPre=/usr/bin/bash -c '/usr/bin/echo 12 > /sys/class/net/enp1s0f0/device/sriov_numvfs'
#[echo 12 ]中的12为需要虚拟的网卡数量 [enp1s0f0]为需要虚拟的网卡
#set VF MAC
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set dev enp1s0f0 vf 0 mac 00:54:00:00:00:00'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set dev enp1s0f0 vf 1 mac 00:54:00:00:00:01'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set dev enp1s0f0 vf 2 mac 00:54:00:00:00:02'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set dev enp1s0f0 vf 3 mac 00:54:00:00:00:03'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set dev enp1s0f0 vf 4 mac 00:54:00:00:00:04'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set dev enp1s0f0 vf 5 mac 00:54:00:00:00:05'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set dev enp1s0f0 vf 6 mac 00:54:00:00:00:06'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set dev enp1s0f0 vf 7 mac 00:54:00:00:00:07'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set dev enp1s0f0 vf 8 mac 00:54:00:00:00:08'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set dev enp1s0f0 vf 9 mac 00:54:00:00:00:09'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set dev enp1s0f0 vf 10 mac 00:54:00:00:00:10'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set dev enp1s0f0 vf 11 mac 00:54:00:00:00:11'
#set PF up
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set enp1s0f0 up'
#set VF up
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set enp1s0f0v0 up'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set enp1s0f0v1 up'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set enp1s0f0v2 up'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set enp1s0f0v3 up'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set enp1s0f0v4 up'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set enp1s0f0v5 up'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set enp1s0f0v6 up'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set enp1s0f0v7 up'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set enp1s0f0v8 up'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set enp1s0f0v9 up'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set enp1s0f0v10 up'
ExecStartPre=/usr/bin/bash -c '/usr/bin/ip link set enp1s0f0v11 up'
ExecStart=/usr/bin/bash -c '/usr/bin/ip link set enp1s0f0v11 up'
Restart=on-failure
[Install]
WantedBy=multi-user.target
保存
按“ESC”键,然后输入":wq"
注册开机启动服务
systemctl daemon-reload
systemctl enable sriov.service
重启
reboot
case $1 in
start)
start
;;
stop | force-stop)
stop
;;
*)
echo "Usage: $0 {start|stop}" >&2
exit 1
;;
esac
exit 0之后启用服务,重启PVE,就能看到Sriov开出来的VF了
# chmod +x /etc/init.d/net-sriov
# systemctl enable net-sriov
# update-initramfs -u -k all
# update-grub
# reboot4. 创建VM
在VM的Hardware栏中进行有关配置
Add->Pci Device,可以看到Sriov功能开出的VF

在Hardware中,进行一些配置,值得注意的是,需要将内存设置为 “balloon=0”

另外,可以在Options栏中,设置Startup delay,保证SR-IOV服务开启后,再启动虚拟机。
2. 效果
经过这些设置,SR-IOV就成功开启啦,在虚拟机中可以看到VF被成功识别,并且MAC地址与我们在前面的配置相符。

需要说明的是,经过测试,SR-IOV所开出的VF,不能被加入Linux Bridge或者OVS-Bridge,只能作为基本的网络端口使用。
Ubuntu、CentOS这些系统用于虚拟机,都能直接使用VF,但常用的软路由系统,”OpenWRT”,则需要重新编译网卡驱动才能启用。这部分的内容可以参照我的Github网页,在release部分有已经编译好的固件可供使用。