服务器K8s集群RDMA排错:从故障定位到验证的完整实操指南
在Kubernetes集群中启用RDMA(Remote Direct Memory Access,远程直接内存访问)可以大幅降低节点间通信延迟,但一旦出现Pod无法建立RDMA连接、ibv_devinfo看不到设备或吞吐骤降,排错往往比普通网络更棘手。
这篇文章按零基础也能跟做的顺序,讲清在K8s集群里排查RDMA故障的完整路径:先确认硬件和驱动状态,再检查K8s侧设备插件与Pod配置,最后用实际流量验证,每一步都给出可执行的命令和预期结果。
先判断问题出在硬件、驱动还是K8s层
RDMA排错最忌讳一上来就翻Pod日志。
建议按“物理层→驱动层→K8s调度层→应用层”的顺序缩小范围。
- 物理层:网卡是否被系统识别,端口是否Link up,交换机是否配置了对应的PFC/ECN(RoCE场景)。
- 驱动层:
ibstat、ibv_devinfo能否看到设备,rdma link是否显示活动状态。 - K8s层:RDMA设备插件(如Mellanox的
k8s-rdma-shared-dev-plugin或rdma-device-plugin)是否正常调度,Pod是否申请到rdma/rdma_shared_device_a等资源。 - 应用层:容器内
ibv_devinfo是否可见,应用能否正常创建QP(Queue Pair)。
如果ibstat在宿主机就报ibv_devinfo: command not found,说明rdma-core或ibverbs-utils未安装,属于基础环境缺失,先补装再继续。
宿主机侧必须确认的几个状态
在任意一个RDMA节点上执行以下命令,确认底层可用。
# 查看IB设备状态,重点看State是否为Active,Physical state是否为LinkUp
ibstat
# 查看设备详情,确认端口和固件版本
ibv_devinfo
# 查看RDMA链路状态
rdma link show
若ibstat输出中State: Down,先检查线缆、光模块和交换机端口。
RoCE场景下,还需确认网卡是否加载了mlx5_ib驱动:
lsmod | grep mlx5_ib
没有输出时,用modprobe mlx5_ib加载,并检查/etc/modules-load.d/下是否有持久化配置。
K8s设备插件与Pod资源的核对方法
宿主机正常不代表Pod能用。
RDMA设备通常以扩展资源形式暴露给调度器。
# 查看节点上RDMA资源总量和已分配量
kubectl describe node <节点名> | grep -A5 -i rdma
如果Capacity和Allocatable中没有任何rdma/资源,说明设备插件未运行或未正确注册。
检查插件DaemonSet:
kubectl get pods -n kube-system | grep -i rdma
kubectl logs -n kube-system
常见日志报错no RDMA devices found,多半是插件挂载的/dev/infiniband路径不存在或权限不足。
确认宿主机存在该目录:
ls -l /dev/infiniband/
若目录为空,回到宿主机侧重新检查驱动和rdma-core安装。
在Pod内部验证RDMA是否真正可用
调度成功不等于RDMA可用。
进入目标Pod执行:
kubectl exec -it -- ibv_devinfo
正常应看到至少一个设备,且port状态为PORT_ACTIVE。
如果提示命令不存在,说明容器镜像内缺少ibverbs-utils,需要换用包含rdma-core的镜像,或在镜像构建阶段安装。
两个Pod之间做连通性测试,推荐用ibping或rping:
- 服务端Pod执行
ibping -S或rping -s -a <服务端IP> - 客户端Pod执行
ibping -c 10 -G <设备名> <服务端LID>或rping -c -a <服务端IP>
能收到回复说明RDMA链路在容器网络内已打通。
若超时,重点检查CNI插件是否支持RDMA、Pod是否在同一子网、以及RoCE场景下交换机是否放行对应VLAN和优先级流控。
排错时容易忽略的坑
- 资源名写错:不同设备插件暴露的资源名不同,
rdma/rdma_shared_device_a和rdma/hca_shared_devices_a不能混用,以kubectl describe node输出为准。 - 特权模式滥用:部分教程让Pod加
privileged: true,虽然能临时绕过问题,但会削弱隔离性。优先通过设备插件正确挂载/dev/infiniband。 - 只测宿主机不测Pod:宿主机
ibstat正常但Pod内看不到设备,是设备插件或挂载路径的问题,不要反复重启节点。 - RoCE与IB混淆:RoCE依赖以太网交换机的PFC/ECN配置,IB则依赖Subnet Manager。用错排查方向会浪费大量时间。
- 固件与驱动版本不匹配:
ibstat中显示的固件版本与OFED驱动版本差异过大时,可能出现间歇性断链,建议对照厂商兼容性列表核对。
验证修复效果的可操作清单
完成修复后,按以下顺序复查,避免问题反复:
- 宿主机执行
ibstat,确认State: Active。 - 执行
kubectl describe node <节点名>,确认rdma/资源可分配数量正确。 - 进入测试Pod执行
ibv_devinfo,确认设备可见且端口活跃。 - 两个Pod间运行
ibping或rping,确认收发正常。 - 用
ib_write_bw做一次带宽测试,对比历史基线,确认性能没有异常下降。
如果以上步骤都通过,但应用仍报RDMA错误,需要检查应用自身的QP配置、内存注册(ibv_reg_mr)和MTU设置,必要时抓取dmesg中的mlx5相关日志进一步定位。
常见疑问
宿主机ibstat正常,但Pod里ibv_devinfo提示No IB devices found,怎么办?
优先检查设备插件Pod是否运行、/dev/infiniband是否挂载到容器、以及Pod的resources.limits是否声明了RDMA资源。三者缺一不可。
RoCE环境下ibping能通但带宽很低,可能是什么原因?
检查交换机PFC和ECN是否按网卡厂商建议配置,同时确认MTU是否一致(通常为4096或9000)。MTU不一致会导致分片和重传,吞吐明显下降。
升级内核后RDMA设备消失,如何快速恢复?
先确认rdma-core和厂商驱动是否随内核更新重新编译。执行dkms status查看驱动状态,必要时重新安装OFED或MLNX_OFED驱动包,再modprobe加载模块。
服务器K8s集群RDMA排错的关键是分层验证:宿主机硬件与驱动、设备插件、Pod资源申请、容器内实际连通性,每一步都用命令确认结果,而不是凭感觉猜测。
先按本文顺序走一遍,再根据具体报错微调,大部分RDMA不可用问题都能定位到明确原因。