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

1️⃣ 在BIOS里开启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绑定

▷ 开启大页

测试结果:

测试结论:

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

kvm直通sata_基于KVM的SRIOV直通配置及性能测试相关推荐

  1. 【KVM系列04】KVM的I/O 设备直接分配和SR-IOV

    第四章 I/O 设备直接分配和 SR-IOV 1. PCI/PCI-E 设备直接分配给虚机 (PCI Pass-through) 1.1 PCI/PCIe Pass-through 原理 1.2 在 ...

  2. 基于KVM的虚拟化研究及应用

    引言 虚拟化技术是IBM在20世纪70年代首先应用在IBM/370大型机上,这项技术极大地提高了大型机资源利用率.随着软硬件技术的迅速发展,这项属于大型机及专利的技术开始在普通X86计算机上应用并成为 ...

  3. B S架构 服务器虚拟化,基于KVM的B/S架构虚拟化管理系统

    云计算的提出为信息技术学术界和产业界的发展提供了一个全新的思路.虚拟化作为云计算Iaas层的关键技术,近年来也得到了迅速发展.20世纪60年代,IBM就开始研究虚拟化技术,使得大型机的资源能得被多用户 ...

  4. 为什么使用基于KVM的VPS服务器?

    KVM技术是一个开源的虚拟化平台,可以让同一台物理服务器同时运行多个操作系统.目前,这种基于KVM技术的VPS服务器已经成为了传统网络托管解决方案的绝佳替代品.它为网站业务提供了更多的灵活性和控制力, ...

  5. 构建基于KVM私有云平台(Nano)

    基于KVM虚拟化快速构建 官网 https://nanos.cloud/ 今天我推荐一款更加轻量的虚拟机管理平台,那就是Nano Nano是基于KVM技术,使用Go语言开发,简单易学的虚拟机管理软件, ...

  6. 【KVM系列01】KVM简介及安装

    第一章 KVM简介及安装 1. KVM 介绍 1.0 虚拟化简史 1.1 KVM 架构 2. KVM 的功能列表 3. KVM 工具集合 4. RedHat Linux KVM 安装 4.1 在安装  ...

  7. 【KVM系列03】KVM的I/O 全虚拟化和准虚拟化

    第三章 I/O 全虚拟化和准虚拟化 1. 全虚拟化 I/O 设备 1.1 原理 1.2 QEMU 模拟网卡的实现 1.3 RedHat Linux 6 中提供的模拟设备 1.4 qemu-kvm 关于 ...

  8. 【KVM系列02】KVM的CPU 和内存虚拟化

    第二章 KVM的CPU 和内存虚拟化 1. 为什么需要 CPU 虚拟化 1.1 基于二进制翻译的全虚拟化(Full Virtualization with Binary Translation) 1. ...

  9. linux 中添加kvm虚拟化,一文告诉你Linux如何配置KVM虚拟化--安装篇

    KVM全称"Kernel-based Virtual Machine",即基于内核的虚拟机,在linux内启用kvm需要硬件,内核和软件(qemu)支持,这篇文章教你如何配置并安装 ...

最新文章

  1. 如何使用Nsight Compute?
  2. PCL滤波介绍(3)
  3. 海思3559A上编译OpenCV4.1.0源码操作步骤
  4. 使用Java代码在应用层获取Android系统属性
  5. 高并发编程-线程通信_使用wait和notify进行线程间的通信
  6. html列表穿插广告怎么实现,基于innerHTML中的script广告实现代码[广告全部放在一个js里面]...
  7. Swift之字符串String的常规操作和处理
  8. 基于RTMP的实时流媒体的QoE分析
  9. 计算机网络管理员适用单位,计算机网络管理员软考理论复习题(附答案).(40页)-原创力文档...
  10. 美团点评Docker容器管理平台
  11. Java工作笔记-生成及解析Json字符串
  12. 百度SEO站群易优CMS 聚合关键词seo插件(上权重神器)
  13. javascript函数式_JavaScript中的函数式编程—结合实际示例(第2部分)
  14. (34)System Verilog引用包中定义的类(失败)
  15. IOS中延时执行的几种方式的比较
  16. C# 获取CPU序列号、MAC地址、硬盘ID等系统信息
  17. Atiitt 自我学习法流程 1.预先阶段 1.1.目标搜索 资料搜索 1.2. 1.3.通过关联关键词 抽象 等领域 拓展拓宽体系树 1.4. 2.分析整理阶段 2.1.找出重点 压缩要学会
  18. php手册 mac版,PHP中文手册for mac-PHP中文手册Mac版下载 V1.0.2-PC6苹果网
  19. 路由器实验要求之配置实验、直连路由验证、静态路由
  20. 利用CaaS控制虚拟机蔓延

热门文章

  1. wxWidgets:wxDataViewEvent类用法
  2. boost::test模块类属性工具的单元测试
  3. boost::mpi::cartesian_communicator相关用法的测试程序
  4. boost::phoenix::arg_names::arg1用法的测试程序
  5. hana::detail::variadic::foldr1用法的测试程序
  6. boost::geometry:::detail::overlay::get_clusters用法的测试程序
  7. boost::geometry模块使用 Karney 的直接方法
  8. Boost::context模块callcc的jump_void测试程序
  9. boost的chrono模块线程时钟的测试程序
  10. boost的chrono模块特殊值的测试程序