如何在Proxmox VE 8上配置使用Mellanox网卡的OVS Hardware Offload

写这个文章主要是因为最近收了一张洋垃圾ConnectX-6 Dx网卡,看文档的时候突然发现这个东西支持一个叫ASAP2的功能,说是网卡的ASIC上面有个embedded switch(下面简称e-switch)可以加速vm的流量转发。听上去就很厉害,于是我试着配置了一下。结果一折腾就是一整个月哈哈😂😂😂,今天回想了一下觉得还挺有意思的,就写一篇文记录下来。

首先说点Disclaimer,本人不是网络工程师也不是专业运维,可能有些地方会说错,还请大家指正。另外就是既然你搜到了这个文章,应该也不会是新手小白,请直接看感兴趣的部分就行😋。

介绍

(上来就盗一张NV的图)

e-switch offload的原理大概就是上面这个样子,网卡通过启动SRIOV虚拟化生成VF(virtual function)分配给虚拟机,然后Host上面的openvswitch(下面简称OVS)或者Linux Bridge通过监听网桥上面的流量,把对应的flow规则写到网卡的ASIC上面,接下来网卡硬件就能根据记下来规则转发封包,不需要Host的网桥软件参与,实现硬件转发。而且因为转发是发生在ASIC上面,vf之间的转发速度上限最后会落到PCIE总线或者内存速度上(看cpu性能还有vm数量),而不是网络接口上。

给大家看一张从Linux Bridge切换到e-switch之后的Server Load对比:

我这台机主要负载是文件服务,可以看到使用了e-switch之后Server Load差不多减少了50%

配置流程

安装MLNX驱动 ==> 启用SRIOV ===> 配置PCI直通 ==> 配置SRIOV ==> 配置OVS ==> 保存最终配置

其实除了最后一步,都能在网络上找到教程或者相关的文档,我会把相应的链接贴到步骤的最后面

安装MLNX驱动

首先去Nvidia官网下载MLNX_EN驱动(Proxmox自带的驱动似乎不行,可能是我太菜🫠):

network.nvidia.com/products/et...

选择最新版,Debian 12,iso或者tgz看你喜欢,我选择tgz

在Proxmox的控制台下载驱动压缩包:

bash 复制代码
wget 'https://www.mellanox.com/downloads/ofed/MLNX_EN-23.10-1.1.9.0/mlnx-en-23.10-1.1.9.0-debian12.1-x86_64.tgz' # 记得把上面的链接换成最新的链接

记得把上面的链接换成最新的链接!

这里插一句题外话,其实我这部机的proxmox 8.10用的是Ubuntu23.10的内核,但是因为系统依赖的关系,Ubuntu版驱动装不上。

解压缩:

bash 复制代码
tar -xf mlnx-en-23.10-1.1.9.0-debian12.1-x86_64.tgz # 同上,记得替换成最新的文件名

安装驱动:

bash 复制代码
cd mlnx-en-23.10-1.1.9.0-debian12.1-x86_64
./install --skip-distro-check # 跳过distro检查,因为proxmox不是debian

(其实装mlnx-en而不是mlnx-ofed一个原因是proxmox上面安装ofed版本驱动会有依赖冲突,另一个原因是我本身只用ethernet)

这里驱动就安装完成了,建议重启一次电脑

配置SRIOV

ConnectX这个系列网卡的SRIOV功能要在固件层面先打开

启动mst并查看网卡路径

bash 复制代码
mst start  # 启动mst
mst status # 查看网卡路径

这里我们复制我高亮出来的网卡路径

查看固件SRIOV状态

bash 复制代码
mlxconfig -d /dev/mst/mt4125_pciconf0 q | grep -e SRIOV_EN -e NUM_OF_VFS

SRIOV_EN是网卡SRIOV功能的状态,我这里是true,就是已启动

NUM_OF_VFS是网卡最多支持的VF数量,就是虚拟网卡的数量,这里是16,就是最多支持16个

启动固件SRIOV

如果查询出来的SRIOV_EN是false或者NUM_OF_VFS是0还是太小的数值的话:

bash 复制代码
mlxconfig -d /dev/mst/mt4125_pciconf0 set SRIOV_EN=1 NUM_OF_VFS=4 # 改成你需要的vf数量

这里要注意vf的数量是够用就好,不是越大越好。

到这里启动SRIOV的部分就完成了,上面的这些固件改动需要电脑重启之后才能生效,没有改动的话也可以不重启

备注

配置固件的方法以NV的文档为准: enterprise-support.nvidia.com/s/article/H...

配置PCI Passthrough

确认主板已启动IOMMU

这里以主板manual为准

启用kernel IOMMU参数

如果用的是默认的grub引导的话

bash 复制代码
vi /etc/default/grub
# 然后在 GRUB_CMDLINE_LINUX_DEFAULT 里面加上 intel_iommu=on iommu=pt
# 或者如果是amd平台的话 amd_iommu=on iommu=pt 如下图

update-grub

如果用的是systemd-boot引导的话(zfs安装是systemd引导)

bash 复制代码
vi /etc/kernel/cmdline
# 然后在最后面加上 intel_iommu=on iommu=pt
# 或者如果是amd平台的话 amd_iommu=on iommu=pt 如下图

proxmox-boot-tool refresh

启用vfio modules

bash 复制代码
vi /etc/modules
# 然后在最后面加上
# vfio
# vfio_iommu_type1
# vfio_pci

update-initramfs -u -k all

重启电脑并验证IOMMU功能

bash 复制代码
journalctl -k | grep -e DMAR -e IOMMU -e AMD-Vi

找一下出来的结果里面有没有这句话:

DMAR: IOMMU enabled

有的话这一步就完成了

备注

这里以proxmox文档为准: pve.proxmox.com/pve-docs/pv...

配置SRIOV

找到你的网卡

bash 复制代码
ip link show

或者直接去proxmox的web ui看,这里我的网卡叫 enp7s0f0np0

切换网卡eswitch模式为 switchdev

bash 复制代码
echo switchdev > /sys/class/net/enp129s0f1/compat/devlink/mode

添加SRIOV VF:

这里先添加两个vf

bash 复制代码
echo 2 > /sys/class/net/enp7s0f0np0/device/sriov_numvfs # enp7s0f0np0 替换成你的网卡

然后你就能看到新建出来两个vf和两个vf representor,见上图(有个vf被我屏蔽了)

enp7s0f0v0 enp7s0f0v1 是vf,注意结尾是v0和v1。

enp7s0f0npf0vf0 enp7s0f0npf0vf1 是vf representor,注意结尾是npf0vf0和npf0vf1,(当然中间不一定是pf0,也可能是pf1什么的,要看vf所属于的pf序号是几)

vf到时候可以分配给vm或者lxc用,vf representor是添加到linux bridge或者ovs里面代表vf用的,这里要注意一点是sysfs的改动在电脑重启之后会被抹除,所以这里我们可以先配着继续配着玩一玩,在确认了最后的网络配置之后,我们再编写具体的配置文件保存配置。

配置OVS

我们可以先把一个vf分配给vm,在web ui上面操作就可以了

接下来可以启动vm,Linux vm基本上是免驱的,自带mlx5_core module.

Windows vm需要去nv官网下载WinOF-2驱动: network.nvidia.com/products/ad...

vm启动之后我们ping一下就会发现没有连上网,这是因为我们还需要把vf representor添加到ovs里面:

创建OVS网桥并添加端口

bash 复制代码
ethtool -K enp7s0f0np0 hw-tc-offload on
ovs-vsctl set Open_vSwitch . other_config:hw-offload=true # 启动硬件卸载
systemctl restart openvswitch.service

ovs-vsctl add-br vmbr2
ovs-vsctl add-port vmbr2 enp7s0f0np0
ovs-vsctl add-port vmbr2 enp7s0f0npf0vf0
ovs-vsctl add-port vmbr2 enp7s0f0npf0vf1

ip link set dev enp7s0f0np0
ip link set dev enp7s0f0npf0vf0
ip link set dev enp7s0f0npf0vf1

这一步做完就会发现已经有网了,接下来可以验证一下hardware offload有没有运作

bash 复制代码
ovs-appctl dpctl/dump-flows type=offloaded

如果跟我一样看到一大堆东西出来就是一切正常了

接下来我们可以随便玩玩,想好接下来的固定配置要配什么。

备注

nv的官方文档: docs.nvidia.com/networking/...

openstack的ovs offload文档: docs.openstack.org/neutron/zed...

intel的switchdev脚本: edc.intel.com/content/www...

保存最终配置

上面我们说到sysfs重启之后就会被清除,而proxmox开机的时候也会删除ovs-db,于是我们现在还需要多一步来保存最后决定的配置

我这里使用udev来保持sriov的状态,用proxmox自带的ifupdown2来保持ovs的配置

配置udev

注意我们首先要获得网卡的mac,用你熟悉的方式就行不赘述

bash 复制代码
cat <<EOF > etc/udev/rules.d/99-sriov.rules
ACTION=="add", SUBSYSTEM=="net", ENV{ID_NET_DRIVER}=="mlx5_core", ATTR{address}=="08:c0:eb:32:98:11", ATTR{compat/devlink/mode}="switchdev"
ACTION=="add", SUBSYSTEM=="net", ENV{ID_NET_DRIVER}=="mlx5_core", ATTR{address}=="08:c0:eb:32:98:11", ATTR{device/sriov_numvfs}="2"
EOF

这里第一句是修改网卡eswitch模式为switchdev,第二句是创建2个vf

注意文件名99-sriov.rules可以改成你喜欢的名字,还有网卡的mac地址要改成你的网卡的地址

配置ifupdown2

bash 复制代码
vi /etc/network/interfaces

这里可以参考我的配置:

bash 复制代码
auto enp7s0f0np0
iface enp7s0f0np0 inet manual
	ovs_type OVSPort
	ovs_bridge vmbr2

auto enp7s0f0npf0vf0
iface enp7s0f0npf0vf0 inet manual
	ovs_type OVSPort
	ovs_bridge vmbr2

auto enp7s0f0npf0vf1
iface enp7s0f0npf0vf1 inet manual
	ovs_type OVSPort
	ovs_bridge vmbr2

auto vmbr2
iface vmbr2 inet static
	address 192.168.1.101/24
	gateway 192.168.1.1
	ovs_type OVSBridge
	ovs_ports enp7s0f0np0 enp7s0f0npf0vf0 enp7s0f0npf0vf1
	pre-up /usr/bin/ovs-vsctl set Open_vSwitch . other_config:hw-offload=true
	pre-up /usr/bin/ovs-vsctl set Open_vSwitch . other_config:max-idle=30000
	pre-up /usr/bin/systemctl restart openvswitch-switch.service
	post-up /usr/sbin/ethtool -K enp7s0f0np0 hw-tc-offload on
	post-up /usr/sbin/ip link set enp7s0f0np0 vf 0 mac BA:DD:AD:DE:AD:30
	post-up /usr/sbin/ip link set enp7s0f0np0 vf 1 mac BA:DD:AD:DE:AD:31

到这里整个这一步就做完了,可以重启一下机器验证一下配置有没有成功啦🎉🎉🎉。

最后

谢谢你能看到这里!🥳

相关推荐
EMTime6 小时前
Docker运行OpenWRT
运维·docker·容器
lolo大魔王7 小时前
Linux 文件系统超全面详解(原理、结构、挂载、分区、inode、日志、管理命令)
linux·运维·服务器
zyl837219 小时前
Docker 使用手册
运维·docker·容器
古月方枘Fry10 小时前
MGRE实验
运维·服务器
stolentime10 小时前
FreeDomain 本地开发环境快速搭建指南
运维·服务器·网络
bush411 小时前
嵌入式linux学习记录四
linux·运维·学习
lihao lihao12 小时前
软硬链接
linux·运维·服务器
TOWE technology13 小时前
智能安防监控系统如何做好防雷?——视频信号SPD综合应用方案解析
运维·服务器·防雷产品·信号保护·信号防雷·spd
楼田莉子13 小时前
Docker学习:Docker介绍及其架构介绍
运维·后端·学习·docker·容器·架构
大明者省13 小时前
IIS 端口绑定正常访问的原理说明与常见误区澄清
运维·服务器·笔记