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介绍
▷ 传统方式的瓶颈: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
在bios里开启sriov,如图所示
注:即使bios里开启全局sriov,网卡也依然可以当作普通网卡使用
需要在bios里开启vt-d
grub配置iommu
1
|
iommu=pt intel_iommu=on |
4. 生成vf
1
2
3
4
5
6
7
8
9
10
11
|
# 启动网卡 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段落里加入
1
2
3
4
5
6
7
8
9
|
< 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 > |
上面<source>中address的地址,可以根据“lshw -c network -businfo”来配置,比如
1
|
pci@0000:41:10.0 p1p1_0 |
▷ 方法2(hostdev):在devices段落里加入
1
2
3
4
5
|
< hostdev mode = 'subsystem' type = 'pci' managed = 'yes' > < source > < address domain = '0x0000' bus = '0x41' slot = '0x10' function = '0x0' /> </ source > </ hostdev > |
上面<source>中address的地址,也是根据“lshw -c network -businfo”来配置
▷ 方法3(net-pool)
为每个pf网卡定义一个net-pool,即分别编辑一个xml文件。这里仅展示一个pf,编辑sriov-int.xml
1
2
3
4
5
6
|
< network > < name >sriov-int</ name > < forward mode = 'hostdev' managed = 'yes' > < pf dev = 'p1p1' /> </ forward > </ network > |
加入到libvirt net-pool、激活、并设置开机启动
1
2
3
|
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里增加如下内容来确保启动
1
2
3
|
ip link set p1p2 up echo 63 > /sys/bus/pci/devices/0000:41:00.0/sriov_numvfs virsh net-start sriov-int |
然后,在vm的xml里增加
1
2
3
4
5
6
7
|
< 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. 带宽限速
只能限制出站带宽,无法限制入站带宽
1
|
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过滤
1
|
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关机和开机情况下都可以改):
1
|
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绑定
▷ 开启大页
测试结果:
测试结论:
使用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. 运维命令
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
# 查看网卡支持的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驱动
1
|
echo "blacklist ixgbevf" >> /etc/modprobe.d/blacklist.conf |
表示当物理机启动时候,默认不加载ixgbevf驱动,但是如果手动modprobe ixgbevf,则也会加载驱动。
如果当前已经加载了ixgbevf,想卸载,则需要如下步骤
1
2
3
|
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包
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
|
#!/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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
# 固定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
线速
http://netoptimizer.blogspot.tw/2014/05/the-calculations-10gbits-wirespeed.html
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:https://blog.51cto.com/cyent/2444012