热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

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

SRIOV介绍、VF直通配置,以及包转发率性能测试小慢哥的原创文章,欢迎转载目录?1.SRIOV介绍?2.环境说明?3.开启SRIOV?4.生成VF?5.VF

基于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段落里加入











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


pci@0000:41:10.0 p1p1_0

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







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


方法3(net-pool)


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



sriov-int




加入到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里增加









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="eth2"
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, eth3 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]

▷ 将脚本开头的eth2改为发包对应的网卡
▷ 将脚本开头的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


推荐阅读
  • PyCharm下载与安装指南
    本文详细介绍如何从官方渠道下载并安装PyCharm集成开发环境(IDE),涵盖Windows、macOS和Linux系统,同时提供详细的安装步骤及配置建议。 ... [详细]
  • 深入探讨CPU虚拟化与KVM内存管理
    本文详细介绍了现代服务器架构中的CPU虚拟化技术,包括SMP、NUMA和MPP三种多处理器结构,并深入探讨了KVM的内存虚拟化机制。通过对比不同架构的特点和应用场景,帮助读者理解如何选择最适合的架构以优化性能。 ... [详细]
  • 开发笔记:2020 BJDCTF Re encode
    开发笔记:2020 BJDCTF Re encode ... [详细]
  • 本文详细介绍了如何在Linux系统上安装和配置Smokeping,以实现对网络链路质量的实时监控。通过详细的步骤和必要的依赖包安装,确保用户能够顺利完成部署并优化其网络性能监控。 ... [详细]
  • CentOS7源码编译安装MySQL5.6
    2019独角兽企业重金招聘Python工程师标准一、先在cmake官网下个最新的cmake源码包cmake官网:https:www.cmake.org如此时最新 ... [详细]
  • 本文详细介绍了 Dockerfile 的编写方法及其在网络配置中的应用,涵盖基础指令、镜像构建与发布流程,并深入探讨了 Docker 的默认网络、容器互联及自定义网络的实现。 ... [详细]
  • 解决Linux系统中pygraphviz安装问题
    本文探讨了在Linux环境下安装pygraphviz时遇到的常见问题,并提供了详细的解决方案和最佳实践。 ... [详细]
  • 本文介绍了一款用于自动化部署 Linux 服务的 Bash 脚本。该脚本不仅涵盖了基本的文件复制和目录创建,还处理了系统服务的配置和启动,确保在多种 Linux 发行版上都能顺利运行。 ... [详细]
  • 在Linux系统中配置并启动ActiveMQ
    本文详细介绍了如何在Linux环境中安装和配置ActiveMQ,包括端口开放及防火墙设置。通过本文,您可以掌握完整的ActiveMQ部署流程,确保其在网络环境中正常运行。 ... [详细]
  • 在Ubuntu 16.04 LTS上配置Qt Creator开发环境
    本文详细介绍了如何在Ubuntu 16.04 LTS系统中安装和配置Qt Creator,涵盖了从下载到安装的全过程,并提供了常见问题的解决方案。 ... [详细]
  • 本文详细介绍了如何在 Linux 平台上安装和配置 PostgreSQL 数据库。通过访问官方资源并遵循特定的操作步骤,用户可以在不同发行版(如 Ubuntu 和 Red Hat)上顺利完成 PostgreSQL 的安装。 ... [详细]
  • 探讨如何真正掌握Java EE,包括所需技能、工具和实践经验。资深软件教学总监李刚分享了对毕业生简历中常见问题的看法,并提供了详尽的标准。 ... [详细]
  • 作者:守望者1028链接:https:www.nowcoder.comdiscuss55353来源:牛客网面试高频题:校招过程中参考过牛客诸位大佬的面经,但是具体哪一块是参考谁的我 ... [详细]
  • FinOps 与 Serverless 的结合:破解云成本难题
    本文探讨了如何通过 FinOps 实践优化 Serverless 应用的成本管理,提出了首个 Serverless 函数总成本估计模型,并分享了多种有效的成本优化策略。 ... [详细]
  • 本文深入探讨了HTTP请求和响应对象的使用,详细介绍了如何通过响应对象向客户端发送数据、处理中文乱码问题以及常见的HTTP状态码。此外,还涵盖了文件下载、请求重定向、请求转发等高级功能。 ... [详细]
author-avatar
Levenmamatq_267
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有