阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

基于KVM的SRIOV直通配置及性能测试

332次阅读
没有评论

共计 8030 个字符,预计需要花费 21 分钟才能阅读完成。

基于 KVM 的 SRIOV 直通配置及性能测试

SRIOV 介绍、VF 直通配置,以及包转发率性能测试

目录

▪ 1. SRIOV 介绍
▪ 2. 环境说明
▪ 3. 开启 SRIOV
▪ 4. 生成 VF
▪ 5. VF 直通
▪ 6. 开启 irqbalance
▪ 7. VM 迁移
▪ 8. 带宽限速
▪ 9. 安全
▪ 10. 其他使用限制
▪ 11. 性能测试
▪ 12. windows 虚拟机使用 VF
▪ 13. 运维命令
▪ 14. 宿主屏蔽 VF 驱动
▪ 附. 包转发率测试方法
▪ 附. 参考文档


1. SRIOV 介绍

基于 KVM 的 SRIOV 直通配置及性能测试

传统方式的瓶颈 :qemu 的网卡,传统方式是使用 tap 网卡,桥接到宿主的 bridge 上,但性能很差,尤其是包转发率很低,难以满足对性能要求比较高的场景。性能差的主要原因是路径太长,经过的内核设备太多,根本原因在于 linux/unix 内核本身就不是为高性能而设计的,linux/unix 更适合做控制平面,而不是转发平面。
解决思路:减少中间路径,最简单有效的方法就是 bypass 内核。SRIOV 的作用就是 bypass 宿主内核。
PF 和 VF:每个物理网卡(比如 p1p1)就是一个 PF,在开启 SRIOV 后,每个 PF 可以生成固定数量的 VF,每个 VF 都可以在宿主上作为一张网卡直接使用,或者直通到 QEMU 虚拟机里作为虚拟机里的网卡使用,这就实现了 bypass 宿主内核。

先给出性能测试的结论,SRIOV VF 直通相比传统 tap+bridge 方案,性能提升:

▷ 发包转发率提高: 677%
▷ 收包转发率提高: 171%


2. 环境说明

机型:Dell PowerEdge R620
网卡:Intel X520(82599ES)
宿主 OS:CentOS 7
VM OS:CentOS 7


3. 开启 SRIOV

1️⃣ 在 BIOS 里开启 SRIOV,如图所示

基于 KVM 的 SRIOV 直通配置及性能测试

注:即使 BIOS 里开启全局 SRIOV,网卡也依然可以当作普通网卡使用

2️⃣ 需要在 BIOS 里开启 VT-d

3️⃣ grub 配置 iommu

iommu=pt intel_iommu=on

4. 生成 VF

# 启动网卡
ip link set p1p1 up

# 查看 pf 的 pci 编号
lshw -c network -businfo

# 查看网卡支持的 vf 数量
cat /sys/bus/pci/devices/0000:41:00.0/sriov_totalvfs

# 生成 vf,建议加入开机启动
echo 63 > /sys/bus/pci/devices/0000:41:00.0/sriov_numvfs

注意:若没有屏蔽宿主的 VF 驱动,则在生成 vf 后还必须等待一会时间才能在宿主上看到所有命名完成的网卡(否则会看到一堆 ethX 网卡),vf 数量越多需要等待时间越长,63 个 vf,差不多需要 10 秒


5. VF 直通

如果 qemu 是通过 libvirt 管理的,有 3 种配置方法:

方法 1(interface):在 devices 段落里加入

<interface type='hostdev' managed='yes'>
  <mac address='52:54:00:ad:ef:8d'/>
  <source>
    <address type='pci' domain='0x0000' bus='0x41' slot='0x10' function='0x0'/>
  </source>
  <vlan>
    <tag id='4010'/>
  </vlan>
</interface>

上面 中 address 的地址,可以根据“lshw -c network -businfo”来配置,比如

pci@0000:41:10.0 p1p1_0

方法 2(hostdev):在 devices 段落里加入

<hostdev mode='subsystem' type='pci' managed='yes'>
  <source>
    <address domain='0x0000' bus='0x41' slot='0x10' function='0x0'/>
  </source>
</hostdev>

上面 中 address 的地址,也是根据“lshw -c network -businfo”来配置

方法 3(net-pool)

为每个 PF 网卡定义一个 net-pool,即分别编辑一个 xml 文件。这里仅展示一个 PF,编辑 sriov-int.xml

<network>
  <name>sriov-int</name>
  <forward mode='hostdev' managed='yes'>
    <pf dev='p1p1'/>
  </forward>
</network>

加入到 libvirt net-pool、激活、并设置开机启动

virsh net-define sriov-int.xml
virsh net-start sriov-int
virsh net-autostart sriov-int

虽然配置了 net-autostart,但并不管用,因为物理机启动时候,经常会在启动生成 vf(假设在 rc.local 里生成 vf)之前就启动 libvirt,而这个 net-pool(sriov-int)本应该在 vf 生成后才能启动,因此建议在 rc.local 里增加如下内容来确保启动

ip link set p1p2 up
echo 63 > /sys/bus/pci/devices/0000:41:00.0/sriov_numvfs
virsh net-start sriov-int

然后,在 vm 的 xml 里增加

<interface type='network'>
  <mac address='52:54:00:ad:ef:8d'/>
  <source network='sriov-int'/>
  <vlan>
    <tag id='4010'/>
  </vlan>
</interface>

3 种方法如何选择

▷ 方法 1:功能多,可以配置 mac 和 vlan
▷ 方法 2:mac 和 vlan 需要自己在宿主上敲 ip 命令设置
▷ 方法 3:有 2 个问题
▪ 存在一个 bug,当本宿主所有 vm 使用某个 PF 的 VF 总数超过 VF 上限后,不会报错,也能启动,但是可能会有异常,并且 vm 如果被 destroy 关机,那么对应的 VF 就会出问题,比如使用 ip link set p1p1 vf 0 mac 00:00:00:00:00:00 来做重置时候,会提示“RTNETLINK answers: Cannot allocate memory”,而且难以修复,即使修复,也不知道有没有看不见的异常存在。
▪ 没有办法知道某个 vm 使用的是哪个 vf,因此如果要对 vf 设置限速或者开关 spoofchk 时候,只能先在宿主上通过“ip link show dev p1p1 | grep MAC 地址”方式来获得 vf 号,然后才能设置限速等操作

综上所述:使用方法 3 最便捷,但是存在 bug,因此需要做好逻辑来防止 vm 使用 vf 总数超过上限的情况。


6. 开启 irqbalance

x520 是 2 队列,x710 是 4 队列,需要在 vm 里启动中断平衡服务(irqbalance),否则只会有一个 cpu 来处理数据包。

另外,这与宿主上 vf 的 query_rss 无关。


7. VM 迁移

直通网卡属于 PCI 设备,而 libvirt 和 qemu 却不支持带有非 USB 的 PCI 设备的 vm 做迁移,包括冷迁移和热迁移。因此热迁移无法实现。

冷迁移,有 2 种方案:

▷ detach 掉 vf 网卡,然后使用 libvirt 做迁移,迁移过去后,再在新宿主上 attach vf 网卡
▷ undefine vm,然后在新宿主上重新渲染并 define vm

注意:不能在 vm 关机时候用 libvirt 的迁移功能,有时候会导致虚拟机消失掉,包括原宿主和新宿主


8. 带宽限速

只能限制出站带宽,无法限制入站带宽

ip link set p1p1 vf 0 max_tx_rate 100

表示出站带宽限速 100Mbps,不同网卡有差别:

▷ x520 网卡最小限速 11Mbps,最大限速 10000Mbps,设为 0 表示不限速。若小于 11 或大于 10000 则会报错
▷ x710 网卡最小限速 50Mbps,最大限速 10000Mbps,设为 0 表示不限速。 若小于 50 则自动设为 50,若大于 10000 则会报错

注意:vm 关机后 vf 的带宽限速不会复位


9. 安全

仅支持源 mac 过滤和网卡 mac 防篡改,不支持其他安全防护(防 arp 欺骗就无法实现)

源 mac 过滤

ip link set p1p1 vf 0 spoofchk on

表示 vm 里发出的包,如果源 mac 不是指定 mac,那么数据包不允许通过。注意:vm 关机后 vf 的 spoofchk 不会复位

网卡 mac 防篡改

▷ 在宿主上修改 mac,vm 里的 mac 不会跟着改;在 vm 里修改 mac,在宿主上可以看到变化
▷ 如果在 vm 关机状态下改了 mac 地址,那么当 vm 开机后会改为 vm 的 mac,当 vm 又关机后,又回改为原先改的 mac
▷ 只有在宿主上看到的当前 vf 的 mac 为全 0,才能在 vm 里修改 mac 地址,即使 vf 的 spoofchk 为 off。但有一种例外,若使用上面方法 2 来配置 xml,虽然宿主上看到的 vf 的 mac 不为 0,但 vm 里可以修改
▷ 当在宿主上设置了 mac 后,虚拟机里的 mac 就无法篡改了
▪ 方法 1(interface)来配置 xml,估计 vm 启动时候就自动帮忙在宿主上设置了 mac,所以就直接实现了防篡改功能
▪ 方法 2(hostdev)来配置 xml,需要在宿主上手动再设置一次 mac 地址才能实现防篡改

在宿主上手动修改 mac 方法(vm 关机和开机情况下都可以改):

ip link set p1p1 vf 0 mac aa:bb:cc:dd:ee:ff

建议:

▷ 在 vm 启动前对 vf 做一次重置
▷ 在 vm undefine 后对 vf 做一次重置


10. 其他使用限制

▷ 直通到 vm 里的 vf 网卡里无法桥接到 vm 里的 linux bridge,这也导致 ebtables 无法使用,iptables 可以使用
▷ 直通到 vm 里的 vf 网卡可以加入 ovs 桥接
▷ 一个 vm 最多只能支持 32 个 vf,超过数量会报错


11. 性能测试

测试方法:

▷ 多台 vm 同时发包,一台 vm 收包,分别观察发包性能和收包性能
▷ 发包 vm 在同一台宿主上,收包 vm 在另一台宿主上
▷ 测试工具:modprobe pktgen
▷ 测试包大小: udp 包,size 为 64 bytes

配置:

▷ vm 配置均为 4 核 8G
▷ 物理网卡均为 x520(vf 队列默认为 2)
▷ 宿主和 vm 均开启 irqbalance、均关闭 numad
▷ 不配置 cpu 绑定、不配置 numa 绑定
▷ 开启大页

测试结果:

基于 KVM 的 SRIOV 直通配置及性能测试

测试结论:

使用 SR-IOV+VF 直通方式可以明显提升包转发率,1 对 1 的测试结果看到kernel 态发包可以达到 3.5Mpps,收包可以达到 1.9Mpps

▷ 发包比 vxlan 提高: 1196%,比 vlan 提高: 677%。此结果参考 1 对 1(1 个发包 vm,1 个收包 vm)
▷ 收包比 vxlan 提高: 363%,比 vlan 提高: 171%。此结果参考 3 对 1(3 个发包 vm,1 个收包 vm)

说明:

▷ kernel 态单核数据包 (64B) 处理能力为 2Mpps
▷ 2Mpps 是因为 kernel 态瓶颈是 2Mpps,如果通过 dpdk 走用户态,则可以大于 2M,原因:收包端要将数据包中断平衡到不同的 cpu 上,方法:可以通过多队列方式,把每个队列分配到单独 cpu 上(irqbalance 会自动均衡),然后 source ip 不一样,就会对应到不同队列,也就是不同的中断上。即 1 个 VF,2 个队列,VM 有至少 2 核,那么当符合负载均衡条件(mac、ip 不同),则理论上最大可以达到 4Mpps

更多测试结果:

以下测试使用的 packet 大小为 64B

▷ kernel 态,3 层转发性能: 发包器使用不同的 source ip

▪ BCM57800:2Mpps
▪ Intel X520:10Mpps
▪ Intel X710:12Mpps

▷ kernel 态,2 层转发性能: 发包器使用不同的 source mac

▪ BCM57800:2Mpps
▪ Intel X520:7.3Mpps
▪ Intel X710:7.8Mpps

▷ kernel 态下 vxlan 封装能力

▪ vxlan 内层使用不同的 source ip 发包
▪ 收包在:1.1-1.2Mpps

▷ dpdk 用户态,2 层转发性能: 发包器使用不同的 source ip

▪ BCM57800: 不支持
▪ Intel X520:14.8Mpps
▪ Intel X710:14.8Mpps

▷ SR-IOV 模式

▪ X520 总量 11.2Mpps,每 vm 为 11.2Mpps/vm 总数(即 VF 数)

总结:

▷ kernel 态下的中断平衡的依据因素:2 层依据 source mac,3 层依据 source ip
▷ kernel 态下使用传统中断模式的单核转发能力极限 2Mpps

注意:

▷ kernel 态下,利用多队列 RSS 中断平衡提升吞吐率,会导致 cpu 非常高
▷ 用户态下即使 source mac 或 source ip 固定,吞吐率基本接近限速 14.8Mpps
▷ vxlan 不能利用多核来提升吞吐,主要原因为外层 source ip 不够多


12. windows 虚拟机使用 VF

到网卡官网下载对应驱动并安装,经测试,win2012 默认就有 82599(x520)驱动,但版本旧


13. 运维命令

# 查看网卡支持的 vf 数量
cat /sys/bus/pci/devices/0000:41:00.0/sriov_totalvfs

# 宿主屏蔽 VF 驱动后查看 vf 和 pf 的对应
https://github.com/intel/SDN-NFV-Hands-on-Samples/blob/master/SR-IOV_Network_Virtual_Functions_in_KVM/listvfs_by_pf.sh
载下来后执行./listvfs_by_pf.sh 即可

# 宿主屏蔽 VF 后查看哪些 VF 正在被使用
yum install dpdk-tools
dpdk-devbind --status

# 查看网卡对应哪个 socket
lstopo-no-graphics

# lspci 查看网卡信息
lspci -Dvmm|grep -B 1 -A 4 Ethernet

# 宿主上查看具体 VF 流量(仅支持 x520,x710 查不到)ethtool -S p1p1 | grep VF

14. 宿主屏蔽 VF 驱动

echo "blacklist ixgbevf" >> /etc/modprobe.d/blacklist.conf

表示当物理机启动时候,默认不加载 ixgbevf 驱动,但是如果手动 modprobe ixgbevf,则也会加载驱动。

如果当前已经加载了 ixgbevf,想卸载,则需要如下步骤

echo 0 > /sys/bus/pci/devices/0000:41:00.0/sriov_numvfs
rmmod ixgbevf
echo 63 > /sys/bus/pci/devices/0000:41:00.0/sriov_numvfs

附. 包转发率测试方法

modprobe pktgen:发包通过 pktgen 来发,收包通过 sar -n DEV 来看,发的是 udp 包

#!/bin/bash

NIC="eth1"
DST_IP="192.168.1.2"
DST_MAC="52:54:00:43:99:65"

modprobe pktgen

pg() {
    echo inject > $PGDEV
    cat $PGDEV
}

pgset() {
    local result
    echo $1 > $PGDEV

    result=`cat $PGDEV | fgrep "Result: OK:"`
    if ["$result" = ""]; then
         cat $PGDEV | fgrep Result:
    fi
}
# Config Start Here -----------------------------------------------------------

# thread config
# Each CPU has own thread. Two CPU exammple. We add ens7, eth2 respectivly.

PGDEV=/proc/net/pktgen/kpktgend_0
echo "Removing all devices"
pgset "rem_device_all"
echo "Adding ${NIC}"
pgset "add_device ${NIC}"

# device config
# delay 0 means maximum speed.

CLONE_SKB="clone_skb 1000000"
# NIC adds 4 bytes CRC
PKT_SIZE="pkt_size 64"

# COUNT 0 means forever
COUNT="count 0"
DELAY="delay 0"

PGDEV=/proc/net/pktgen/${NIC}
echo "Configuring $PGDEV"
pgset "$COUNT"
pgset "$CLONE_SKB"
pgset "$PKT_SIZE"
pgset "$DELAY"
pgset "dst ${DST_IP}"
pgset "dst_mac ${DST_MAC}"

# Time to run
PGDEV=/proc/net/pktgen/pgctrl

echo "Running... ctrl^C to stop"
pgset "start"
echo "Done"

# Result can be vieved in /proc/net/pktgen/eth[3,4]

▷ 将脚本开头的 eth1 改为发包对应的网卡
▷ 将脚本开头的 192.168.1.2 改为目标 ip
▷ 将脚本开头的 52:54:00:43:99:65 改为目标 mac

pktgen-dpdk

# 固定 ip 固定 mac
set 0 dst ip 192.168.10.240
set 0 src ip 192.168.10.245/24
set 0 dst mac c8:1f:66:d7:58:ba
set 0 src mac a0:36:9f:ec:4a:28


# 可变 source ip 可变 source mac
stop 0
range 0 src ip 192.168.0.1 192.168.0.1 192.168.200.200 0.0.0.1
range 0 dst ip 10.1.1.241 10.1.1.241 10.1.1.241 0.0.0.0
range 0 dst mac c8:1f:66:d7:58:ba c8:1f:66:d7:58:ba c8:1f:66:d7:58:ba 00:00:00:00:00:00
range 0 src mac a0:36:9f:ec:4a:28 a0:36:9f:ec:4a:28 a0:36:9f:ec:ff:ff 00:00:00:00:01:01
range 0 src port 100 100 65530 1
range 0 dst port 100 100 65530 1
range 0 size 64 64 64 0
enable 0 range
enable 0 latency
start 0


# 按 50% 的速率发包
set 0 rate 50

附. 参考文档

# openstack 关于 sriov 的限制
https://docs.openstack.org/mitaka/networking-guide/config-sriov.html

# 迁移
https://wenku.baidu.com/view/d949db67998fcc22bcd10dfd.html
https://www.chenyudong.com/archives/live-migrate-with-pci-pass-through-fail-with-libvirt-and-qemu.html

# sriov 配置
https://access.RedHat.com/documentation/en-us/red_hat_enterprise_linux/6/html/virtualization_host_configuration_and_guest_installation_guide/sect-virtualization_host_configuration_and_guest_installation_guide-sr_iov-how_sr_iov_libvirt_works

# 线速
http://netoptimizer.blogspot.tw/2014/05/the-calculations-10gbits-wirespeed.html

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计8030字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中