☰
InfiniBand网卡安全驱动与虚拟化部署实战
2026/10/21 11:56:16 网站建设 项目流程

部署过 InfiniBand 的人都知道,链路速率从 100Gb/s 往上爬的时候,最让人心里没底的根本不是网卡性能,而是驱动安全和虚拟化这两个环节。插上光模块、ibstatus 能看到 ACTIVE 只是第一关,真正麻烦的是后面:主板开了 Secure Boot,内核模块加载被拒;虚拟化平台里把 HCA 透传给虚拟机,结果客户机里看到设备却起不来驱动。IB 网卡和普通以太网卡不一样,它走的是 RDMA 直通内存的路径,DMA 能力太强,所以安全驱动和虚拟化流程这两件事做得越扎实,生产环境才越稳。这篇就把我在这条路上踩过的坑和梳理出来的流程完整写一遍,希望能让后来的人少走几趟弯路。

1. IB 网卡安全驱动:为什么高速网络反而对驱动要求最苛刻

IB(InfiniBand)网卡的定位从来不是“一块普通网卡”,而是一块拥有 DMA 能力的 HCA(Host Channel Adapter)。它可以让应用绕过操作系统内核和 CPU,直接对远端内存发起读写。这种设计带来了极低的延迟和极高的带宽,但代价就是:一旦驱动被恶意替换、固件被篡改,攻击面极大。网卡本身能直接读写物理内存,驱动如果落到了不可信的人手里,机器上的数据基本等于裸奔。

1.1 安全启动链路下的 IB 驱动加载逻辑

从主板通电到 IB 网卡驱动真正接管设备,中间隔了好几道校验关卡。最前面是 UEFI 固件,它会验证 Option ROM 和 UEFI 驱动的签名;系统启动后,内核根据 Secure Boot 策略加载模块,所有外部编译的 .ko 文件必须带有效签名;再往上是用户态的 libibverbs 和 rdma-core 库,它们虽然不由内核验签,但如果版本和内核模块不匹配,轻则功能缺失,重则直接报错退出。

普通以太网卡的驱动如果在 Secure Boot 环境下没签名,内核会拒绝加载,这个错误很直观,大家基本都认识。IB 网卡的驱动问题更隐蔽:因为 OFED(OpenFabrics Enterprise Distribution)驱动和内核版本强绑定,生产环境里经常要通过 DKMS 重新编译模块。问题来了——DKMS 编译出来的新 .ko 文件默认是没有签名的,如果系统开着 Secure Boot,新模块装好之后根本起不来,而且报错信息很不直观,常常只是 dmesg 里一行signature check failed,不仔细翻日志根本发现不了。

注意:我自己踩过这个坑之后,总结了一条经验——凡是 IB 网卡所在的主机,建议把驱动签名流程做成标准操作的一部分,每次通过 DKMS 重编模块后,必须检查模块签名状态,不能只看到模块编译成功就认为万事大吉。

1.2 驱动签名验证的完整操作链路

基于常见实践,这里给出一个完整的 IB 网卡安全驱动配置流程,适用于 RHEL/CentOS/Ubuntu 等主流发行版:

  1. 生成内核模块签名用的密钥对。很多环境里直接用mokutil生成新密钥,并把公钥导入到 MOK(Machine Owner Key)列表中。命令大致是这样:
# 生成签名密钥(仅首次需要) openssl req -new -x509 -newkey rsa:2048 -keyout MOK.priv \ -outform DER -out MOK.der -nodes -days 3650 \ -subj "/CN=IB Module Signing Key/" # 将公钥导入 MOK sudo mokutil --import MOK.der # 重启后按提示完成 MOK 登记 sudo reboot
  1. 配置 DKMS 签名。OFED 驱动安装包自带的 dkms.conf 往往没有签名参数,需要手工在/etc/dkms/对应模块目录下的配置里追加签名字段,或者直接修改源码包里dkms.conf的POST_BUILD指令。

  2. 签名并验证。模块编译完成后,执行签名脚本:

sudo /usr/src/kernels/$(uname -r)/scripts/sign-file sha256 \ MOK.priv MOK.der \ $(modinfo -n mlx5_core)

之后用modinfo mlx5_core | grep sig查看签名标记,确认出现signer: IB Module Signing Key等信息。

这个流程看起来不复杂,但实际推进时会卡在几个地方。比如 MOK 登记之后,如果证书过期或者被吊销,所有依赖它的模块会集体签名失效;再比如某些国产 Linux 发行版对/etc/dkms的目录规范有自己的一套,原来 RedHat 系的配置不能直接搬。这些细节都是不实际跑一遍根本不会知道的。

签名校验失败时的典型现象排查方法和建议
模块加载报required key not available检查 MOK 公钥是否导入成功,用mokutil --list-enrolled确认
dmesg 报module verification failed: signature and/or required key missing重新执行 sign-file,并确认签名密钥与 MOK 中的公钥一致
DKMS 重编后新模块无签名修改 dkms.conf 增加签名流程,或者手动对编译产物统一签名
密钥过期导致所有模块验签失败生成新密钥,重新导入 MOK,并重新签名所有已安装的 IB 模块

2. 虚拟化场景下 IB 网卡部署:SR-IOV 和 PCIe passthrough 怎么选

IB 网卡进虚拟化环境,方案其实就两条主流路子——PCIe passthrough(VFIO 透传)和 SR-IOV(单根输入输出虚拟化)。很多人一上来就想选性能最好的,但 IB 的场景里性能只是第一个考量点,后面还跟着隔离性、可维护性和 RDMA 语义能不能保得住这些更实际的问题。

2.1 两条路线的性能边界和数据面差异

PCIe passthrough 的逻辑很简单:把整块物理网卡直接挂给一台虚拟机,中间不经过宿主机虚拟交换层。这种方式性能损耗最小,应用在虚拟机里看到的设备基本等同于物理机。但缺点也很明显——一台网卡只能归一台虚拟机用,物理资源利用率上不去。很多测试环境里把 IB 卡直接透传给 GPU 计算节点,跑 NCCL 集合通信效果很好,但生产环境里不可能每个虚拟机都配一块物理 IB 卡。

SR-IOV 则是在物理网卡(PF)的基础上,通过硬件虚拟化能力分出多个虚拟功能(VF),每个虚拟机分配一个或多个 VF。这种方式兼顾了性能和多租户。IB 网卡的 SR-IOV 和普通以太网卡有个显著区别:SR-IOV 场景下 IB 的 RDMA 数据面能不能完整保留,取决于网卡型号和驱动支持。早期很多 IB 网卡在 VF 环境下只支持 IPoIB 但不支持完整的 verbs 语义,跑大数据应用时会有明显阉割感。现在主流厂商(如 NVIDIA/MLNX)的 ConnectX 系列在支持 SR-IOV 时已经能对不同 VF 做 QoS 隔离,但具体型号之间的能力差异依然不小。

对比项PCIe passthrough / VFIOSR-IOV
性能表现接近物理机,几乎没有损耗有少量损耗,但现代网卡已做得很好
资源利用率整卡只能给一台虚拟机一张卡可拆成多个 VF,支持多租户
配置复杂度相对简单,主要是 BIOS 和 IOMMU 设置需要 PF/VF 管理、QoS 配置,复杂度更高
虚拟机迁移基本不支持热迁移(除非有专门方案)迁移限制依然存在,但灵活性稍好
适用场景GPU 计算节点、低延迟高频交易、数据库场景云环境多租户、大规模 HPC 集群、容器网络

2.2 虚拟化依赖的底层前置条件

不管选哪条路线,宿主机 BIOS 和固件层面的功能开关是绕不开的。CPU 虚拟化扩展(Intel VT-x / AMD-V)和 IOMMU(Intel VT-d / AMD IOMMU)必须处于开启状态。尤其是 IOMMU,它负责把设备发起的 DMA 请求做地址翻译和隔离,没有它,VFIO 根本没法把设备安全地透传给虚拟机。很多人一上来就modprobe vfio-pci,结果设备绑定时报错,最后发现 BIOS 里 VT-d 压根没开。

进入系统后建议先跑两条命令确认:

# 查看 CPU 虚拟化扩展是否开启 lscpu | grep -E "vmx|svm" # 查看 IOMMU 状态 dmesg | grep -i -e DMAR -e IOMMU

有输出且没有报错,才说明 IOMMU 是可用的。另外要注意,某些服务器主板的 BIOS 里 VT-d 和 SR-IOV 是分开的两个开关,很多人只开了 VT-d 忘了 SR-IOV,结果宿主机上lspci里能看到 IB 卡,但/sys/class/infiniband/下面只有 PF 没有 VF,虚拟机里自然什么也拿不到。这个检查点一定要放在前面,后面才能少折腾。

3. 一次完整的 IB 网卡虚拟化实操记录

理论说完,分享一次我最近做的实际部署。场景是这样的:一台双路服务器,上面跑 KVM 虚拟化,客户机是 Ubuntu 22.04,需要一个 IB 端口用来跑分布式训练的数据面通信。因为整台机器只规划了这一个计算型虚拟机,IB 网卡决定直接走 VFIO 透传,省去 SR-IOV 的配置开销。

3.1 宿主机侧设备绑定与 VFIO 配置

开始之前先确认网卡在 PCIe 总线上的位置:

lspci | grep -i mellanox

查到类似03:00.0 InfiniBand controller: Mellanox Technologies MT2892 Family [ConnectX-6 Dx]的输出,记下03:00.0这个 BDF 编号。接下来要把这个设备从原驱动解绑,挂到 vfio-pci 上:

# 查看当前驱动 lspci -ks 03:00.0 # 解绑原驱动 echo "0000:03:00.0" | sudo tee /sys/bus/pci/drivers/mlx5_core/unbind # 挂载 vfio-pci 驱动(如果还没有模块先加载) sudo modprobe vfio-pci echo "0000:03:00.0" | sudo tee /sys/bus/pci/drivers/vfio-pci/bind

这里有个细节:现代内核有 driver_override 机制,比直接手动解绑更持久。推荐按下面的方式操作:

# 永久指定 vfio-pci 作为该设备的驱动 echo "vfio-pci" | sudo tee /sys/bus/pci/devices/0000:03:00.0/driver_override echo "0000:03:00.0" | sudo tee /sys/bus/pci/drivers/vfio-pci/bind

然后要确认这个设备所在的 IOMMU group 里没有其他设备混杂在一起。如果同一个 group 里还有其他设备,透传时会全部一起给到虚拟机,宿主机反而会失去那些设备,这是 IOMMU 分组规则决定的。检查命令:

ls /sys/kernel/iommu_groups/*/devices/

只要03:00.0所在的 group 里没有别的设备,就可以放心往下走了。

3.2 QEMU/KVM 启动参数与客户机驱动验证

宿主机准备工作做好之后,用 virt-install 或者直接手写 QEMU 命令行都可以。这里提供一个最小化的 XML 片段,适用于 libvirt 管理的 KVM 环境:

<hostdev mode='subsystem' type='pci' managed='yes'> <source> <address domain='0x0000' bus='0x03' slot='0x00' function='0x0'/> </source> </hostdev>

这段配置的核心作用是让 libvirt 在虚拟机启动时自动完成 VFIO 绑定,不用手工去处理设备归属,管理起来会省心很多。启动虚拟机后,进入客户机执行lspci,如果看到 IB 设备出现在 PCI 设备列表里,说明透传成功。

接下来是真正的关键:客户机内安装 OFED 驱动。我习惯先装发行版自带的rdma-core包和ibutils,然后看需求再决定要不要装完整的 MLNX_OFED。测试环境里,直接用apt install rdma-core infiniband-diags perftest就够了,生产环境再考虑完整 OFED 的版本锁定问题。

驱动加载完成后,验证链路状态:

# 确认 IB 设备已识别 ibstat # 查看端口状态 ibstatus

正常输出应该能看到端口状态是Active,物理状态是LinkUp。如果状态是Down,大概率是子网管理器(Subnet Manager)没有正常工作。IB 网络里必须有一个 SM,可以是硬件交换机内置的,也可以通过软件方式跑一个opensm来做。没有 SM,链路能亮但端口永远起不来,这是第一次玩 IB 最容易忽略的事情。

性能验证方面,用 perftest 工具集的ib_write_bw和ib_read_lat做一轮冒烟测试:

# 在一端启动服务端 ib_write_bw -d mlx5_0 -x 3 -D 10 # 在另一端启动客户端 ib_write_bw -d mlx5_0 -x 3 192.168.1.10 -D 10

其中-x 3是指定使用 RoCE 传输模式,如果是 InfiniBand 模式需要按实际 GID 索引调整。正常跑 EDR(100Gb/s)的链路,写带宽应该能到 90Gb/s 以上,延迟在微秒级别。如果带宽大幅缩水,建议优先检查端口速率协商结果和 MTU 设置。

3.3 国产化虚拟化平台的适配要点

热搜词里出现了“麒麟天逸终端虚拟化”“天逸终端虚拟化软件”这些关键字,我顺手提一下国产化平台下的适配经验。天逸终端虚拟化这类基于 KVM 改造的虚拟化平台,底层其实也是 VFIO 和 vhost 一脉,所以 IB 透传的基本思路是一样的。但由于商业产品封装了管理面,很多底层操作不直接暴露,需要留意:

  • 设备透传功能是否在管理界面开放,部分平台把“PCIe 设备直通”列为高级特性,需要管理员手动开启;
  • 客户机内的驱动和宿主机上的内核版本匹配问题,建议提前确认好 OFED 版本与操作系统的兼容矩阵;
  • 某些国产系统默认开启了额外的安全策略(比如强制访问控制),这些策略可能拦截 IB 设备在客户机内的初始化动作,遇到问题优先查审计日志。

另外,飞牛虚拟机这类面向个人用户的平台,对 IB 卡的支持通常没有企业级虚拟化那么完整,尤其是“网卡混杂模式”这类虚拟化网络功能,对 RDMA 数据面的影响还不明确,不太建议在生产训练场景里使用。

4. 从热词里提炼的故障排查链路

这一节我把最近大家搜索频次比较高的问题串起来,相当于一份现场排障手册。很多问题表面上毫无关联,实际排查起来都指向同几个根因。

4.1 网卡“代码 56”和“无法启动”类故障的定位顺序

Windows 客户机里 IB 网卡出现“该设备无法启动(代码 56)”是虚拟化场景下的高频问题。代码 56 的含义是驱动已经加载,但设备初始化时没有拿到正确资源。在透传环境里,按下面的顺序排查基本能覆盖 90% 的原因:

  1. 先确认宿主机侧 VFIO 是否绑定成功,有没有其他驱动抢占了设备。用lspci -ks <BDF>查看驱动归属;
  2. 然后查看客户机里的 PCI 设备State是否为Driver is "mlx5_core",如果不是,说明驱动没装或者加载顺序不对;
  3. 再看 Windows 事件查看器里e2fexpr或mlx5相关错误日志,判断是设备资源冲突还是固件版本不兼容;
  4. 最后检查 BIOS 里的 SR-IOV 开关,有些网卡虽然走 VFIO 但固件初始化阶段也依赖 SR-IOV 能力,关掉就出问题。

Windows 系统还有一个额外的干扰项:基于虚拟化的安全(VBS/HVCI)机制开启时,驱动加载路径会多一层隔离和校验,一些老版本 IB 驱动在这种环境下会初始化失败。这可能就是“运行工具关闭基于虚拟化的安全”这类搜索出现的原因。但关闭安全功能是企业级环境里比较敏感的操作,正确的做法是优先升级驱动到签名兼容的版本,其次才是结合安全策略评估是否要调整 VBS 配置,不建议一上来就关。

4.2 混杂模式与监听模式的正确理解

热搜词里有“网卡监听模式”和“飞牛虚拟机网卡混杂”。混杂模式(promiscuous mode)是一种网络技术模式,当网卡处于这种模式时,会接收所有经过它的数据包,而不仅是发给自己的数据包。在虚拟化平台里,开启混杂模式主要解决的问题是虚拟交换机(vSwitch)二层转发需要看到所有的广播和组播流量。IB 网络本身和以太网的混杂模式略有差别,IB 使用 LID(Local Identifier)寻址,并没有完全对等的机制,但 IPoIB 链路在虚拟化场景下设置混杂模式的需求是存在的。

需要留意的是,在共享的虚拟网络里开启混杂模式,意味着这台虚拟机可以看到该虚拟交换机上的其他广播流量。这在排障和抓包时很有用,但也意味着网络隔离性下降。生产环境里开启混杂模式需要走变更流程,不能悄悄打开,否则出了问题定位起来很难受。

4.3 多 IP、网卡名漂移和开机自启

这几个问题虽然不只在 IB 场景出现,但 IB 网卡在这种问题上的破坏力更大,因为 RDMA 通信高度依赖 IP 地址和路径的稳定性。

Windows 里“网卡出现有两个 IP”的情况,多见于 DHCP 和静态 IP 配置同时存在,或者虚拟机模板部署后网卡 GUID 冲突,导致系统生成了多余的网络配置。手工清理注册表里的网络配置项,或者直接在 PowerShell 里重置网卡是最快的解法:

Get-NetAdapter | Reset-NetAdapter

Linux 里网卡名漂移(比如从 ib0 变成 ib1)是因为 udev 规则绑定了旧的 MAC 地址,换网卡或换 PCIe 槽位之后系统重新分配了名字。可以通过配置/etc/systemd/network/下的 link 文件,固定 MAC 和名字的对应关系:

[Match] MACAddress=xx:xx:xx:xx:xx:xx [Link] Name=ib0

“Linux 网卡开机自启”的问题也很常见。IB 网卡在部分发行版里默认不会随系统启动自动拉起,需要把网络配置里的ONBOOT设为yes(ifcfg 风格),或者在 NetworkManager 里把连接设为“自动连接”。对于 IPoIB 的配置,还要额外确保CONNECTED_MODE=yes和MTU设置正确,否则插着线开完机,端口还是 Down 的状态。

5. 驱动版本锁定、证书管理与监控体系

IB 网卡的安全驱动和虚拟化流程都跑通之后,真正的长期运维挑战才刚开始。IB 驱动的版本锁定比其他网卡严格得多,因为它和内核、固件、用户态库三方深度绑定,任何一个版本不匹配都可能带来隐蔽问题。

5.1 版本锁定与签名证书生命周期

OFED 驱动的每个大版本都是针对特定内核版本和固件版本验证过的,升级时最好整体变更,不要只单独升级某个模块。生产环境建议遵循“锁版本+统一证书+定期演练”的原则:

  • 锁版本:在/etc/yum.repos.d/或 apt 源里锁定 OFED 版本,避免yum update顺手把内核和驱动的兼容性破坏掉;
  • 统一证书:所有 IB 主机的 MOK 密钥保持一致,方便统一轮换。我见过有些环境每台机器自己生成一套密钥,后面做证书轮换时工作量巨大,而且容易出现漏更新的机器;
  • 定期演练:每半年选一台测试机完整走一遍“密钥更换+驱动重签+重启加载”的流程,确保证书过期时不至于手足无措。

签名证书的管理往往是被忽略的重灾区。MOK 证书和普通的 TLS 证书一样有有效期,过期之后所有依赖它的模块都会拒载。我自己遇到过最尴尬的一次是现场操作时发现仓库里所有 IB 驱动模块都无法加载,查了半天才发现是 MOK 证书上周过期了。这个教训之后,我把证书有效期设成了 10 年,并把证书过期时间写进了监控系统。

5.2 监控与告警体系的落地建议

IB 网络的监控指标和以太网有很大的不同。除了常规的丢包和重传之外,还需要关注:

  • 端口物理状态和逻辑状态(ibstat / ibstatus)
  • 链路速率降级(比如从 100Gb/s 掉到 40Gb/s)
  • 符号错误计数(Symbol Error Counter)和链路误码率
  • VF 数量与租户分配的对应关系
  • 驱动加载日志和签名校验异常

工具层面,ibmonitor可以看实时流量,ibdiagnet可以做全链路健康检查,sysdig也能抓 RDMA 相关的系统调用。另外,强烈建议把/var/log/messages和dmesg里关于签名校验失败的日志接入告警,这往往比端口状态告警更早暴露问题——驱动签名出问题通常发生在内核升级之后,如果能在升级后自动检查一遍模块签名状态,很多事故都能拦在发生之前。

我在实际部署中最大的感受是:IB 网卡的安全驱动和虚拟化流程,本质上是一套“信任链”的构建。主板信任固件,固件信任驱动,驱动信任用户态库,虚拟化平台信任 IOMMU 的设备隔离——任何一环断裂,最终表现都是网络不通或者性能暴跌。把这些环节提前梳理清楚,后面才不会被各种诡异现象折磨。

最后分享一个小技巧:每次给 IB 主机升级内核之前,花两分钟检查一下dkms status,确认所有 IB 模块都处于installed状态,并且用modinfo验证签名是否有效。这两分钟能避免绝大多数“升级完系统就丢网卡”的悲剧。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询