小知识:详解基于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

在bios里开启sriov,如图所示

%小知识:详解基于KVM的SRIOV直通配置及性能测试-1猿站网-插图

注:即使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绑定

▷ 开启大页

测试结果:

%小知识:详解基于KVM的SRIOV直通配置及性能测试-2猿站网-插图

测试结论:

使用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

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.51cto.com/cyent/2444012

声明: 猿站网有关资源均来自网络搜集与网友提供,任何涉及商业盈利目的的均不得使用,否则产生的一切后果将由您自己承担! 本平台资源仅供个人学习交流、测试使用 所有内容请在下载后24小时内删除,制止非法恶意传播,不对任何下载或转载者造成的危害负任何法律责任!也请大家支持、购置正版! 。本站一律禁止以任何方式发布或转载任何违法的相关信息访客发现请向站长举报,会员发帖仅代表会员个人观点,并不代表本站赞同其观点和对其真实性负责。本网站的资源部分来源于网络,如有侵权烦请发送邮件至:2697268773@qq.com进行处理。
建站知识

小知识:Docker安装ELK并实现JSON格式日志分析的方法

2023-4-1 13:37:20

建站知识

小知识:服务器UDIMM、LRDIMM、RDIMM三种内存的区别

2023-4-1 13:52:18

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索