GPU 算力拉满了,网络却成了瓶颈?在大模型训练和推理场景中,传统 TCP/IP 网络的延迟和 CPU 开销正在严重制约集群性能。RDMA 技术通过绕过内核直接访问内存,降低网络延迟。本文将手把手教你在 Kubernetes 中启用 RDMA 能力,从 Device Plugin 部署到性能验证,让你的 AI 集群真正发挥出硬件的全部潜力。
1. 基本概念
RDMA (Remote Direct Memory Access) 是一种高性能网络通信技术,允许网络中的计算机直接从另一台计算机的内存中读取或写入数据,而无需涉及两台计算机的操作系统内核或 CPU。
1.1 核心特性
Zero Copy (零拷贝) :应用程序可以直接将数据传输到网络适配器,无需在内核空间和用户空间之间复制数据。Kernel Bypass (内核旁路) :应用程序可以直接向硬件发送命令,绕过操作系统内核,从而显著降低延迟。CPU Offload (CPU 卸载) :网络传输逻辑由网卡硬件处理,释放 CPU 资源用于计算任务。1.2 网络协议
RDMA 支持多种网络传输协议,常见的包括:
InfiniBand (IB) :专为高性能计算设计的网络标准。 提供极高的吞吐量和极低的延迟。 需要专用的 IB 交换机和网卡,成本较高,但性能最好。 采用基于信用的流控机制,保证无损传输。 RoCE (RDMA over Converged Ethernet) :允许在以太网上运行 RDMA 协议。 RoCE v1 :基于以太网链路层协议,只能在同一个二层广播域内通信,不可路由。RoCE v2 :基于 UDP/IP 协议,可以跨三层网络路由,是目前数据中心的主流选择。需要交换机支持 PFC (Priority Flow Control) 和 ECN (Explicit Congestion Notification) 以保证无损传输。iWARP (Internet Wide Area RDMA Protocol) :基于 TCP/IP 协议栈实现 RDMA。 利用 TCP 的可靠传输机制,对网络设备要求较低(普通以太网交换机即可)。 由于 TCP 协议栈的复杂性,性能通常低于 IB 和 RoCE。 在 Kubernetes 环境中,我们通常关注如何将这些高性能网络能力暴露给 Pod 使用。
2. 背景与目标
随着大模型(LLM)训练和推理需求的爆发式增长,分布式计算集群对网络带宽和延迟提出了极高的要求。在传统的 TCP/IP 网络架构中,数据传输需要经过操作系统内核的多次上下文切换和内存拷贝,这在高带宽(如 100Gbps+)场景下会消耗大量的 CPU 资源,并引入不可忽视的延迟,成为制约 GPU 集群性能的瓶颈。
为了解决这一问题,RDMA (Remote Direct Memory Access) 技术被广泛应用。它允许应用程序直接访问远程节点的内存,绕过内核网络栈,从而实现高吞吐、低延迟和低 CPU 占用。
然而,Kubernetes 原生并不直接支持 RDMA 设备的管理和调度。为了在 Kubernetes 集群中充分利用 RDMA 硬件能力,我们需要解决以下关键问题:
设备发现与管理 :如何将物理节点的 RDMA 设备(如 IB 卡、RoCE 网卡)暴露给 Kubernetes 调度器。Pod 配置 :如何将 RDMA 设备挂载到 Pod 内部,使其能够使用 IB Verbs API 进行通信。网络方案选择 :在复杂的网络环境中,是否需要引入 Multus CNI 等多网卡方案。性能验证 :如何验证 RDMA 功能是否正常开启,并测试实际带宽是否达标。本文将基于 Mellanox 提供的 k8s-rdma-shared-dev-plugin,详细介绍在 Kubernetes 中启用原生 RDMA 的完整流程与最佳实践。
3. 部署 device-plugin
推荐使用由 Mellanox 官方维护的 DevicePlugin:k8s-rdma-shared-device-plugin
3.1 驱动安装
确保节点已安装对应版本的 MOFED/OFED 驱动及用户态库(libibverbs、rdmacm 等)。驱动安装方式本文不赘述。
3.2 获取部署模板
先 clone 项目:
1
git clone https://github.com/Mellanox/k8s-rdma-shared-dev-plugin.git
3.3 部署 Device Plugin
1
2
cd deployment/k8s/base
kubectl apply -k .
部署成功后 kube-system 中会出现 rdma-shared-dp-ds DaemonSet,它会在每个节点挂载 RDMA 设备并注册可调度资源。
1
2
3
root@GB200-POD2-F06-Node05:~# kubectl -n kube-system get po| grep rdma
rdma-shared-dp-ds-vrswv 1/1 Running 1 ( 27h ago) 31h
rdma-shared-dp-ds-zg242 1/1 Running 1 ( 27h ago) 31h
3.4 配置
Device Plugin 的核心是 ConfigMap。默认配置可参考:configmap.yaml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion : v1
kind : ConfigMap
metadata :
name : rdma-devices
namespace : kube-system
data :
config.json : |
{
"periodicUpdateInterval": 300,
"configList": [
{
"resourceName": "hca_shared_devices_a",
"rdmaHcaMax": 1000,
"selectors": {
"vendors": ["15b3"],
"deviceIDs": ["1021"],
"ifNames": ["ibp3s0"]
}
}
]
}
关键字段:
resourceName:Pod 申请资源写的名字,建议自定义如 rdma/ibrdmaHcaMax:单卡允许共享的 Pod 数量,默认 1000selectors:定义哪些物理网卡由 device plugin 接管,是配置的关键vendors:设备厂商 ID,例如 Mellanox 为 15b3 deviceIDs:设备 ID,和 IB 卡有关,例如 ConnectX-7为 1021 ifNames:设备接口名称。 接下来介绍如何收集所需信息。
4. 采集 RDMA 设备信息
4.1 列出 IB 设备
1
2
ls /sys/class/infiniband
mlx5_0 mlx5_1 mlx5_2 mlx5_3 mlx5_4 mlx5_5 mlx5_6 mlx5_7
4.2 关联网络接口
1
2
3
4
5
6
7
8
9
ibdev2netdev
mlx5_0 port 1 == > ibp3s0 ( Up)
mlx5_1 port 1 == > ibP2p3s0 ( Up)
mlx5_2 port 1 == > enP6p3s0f0np0 ( Up)
mlx5_3 port 1 == > bond0 ( Up)
mlx5_4 port 1 == > ibP16p3s0 ( Up)
mlx5_5 port 1 == > ibP18p3s0 ( Up)
mlx5_6 port 1 == > enP22p3s0f0np0 ( Up)
mlx5_7 port 1 == > bond0 ( Up)
这里可以看到 IB 卡对应的接口名称,例如 mlx5_0 的接口名称为 ibp3s0。
这里可以获取到配置中需要的 ifNames 参数。
4.3 获取 PCI 信息
mst status -v 可以列出所有 UP 状态网卡及其 PCI ID:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
root@GB200-POD2-F06-Node05:~/lixd/rdma# mst status -v
MST modules:
------------
MST PCI module loaded
MST PCI configuration module loaded
PCI devices:
------------
DEVICE_TYPE MST PCI RDMA NET NUMA
ConnectX7( rev:0) /dev/mst/mt4129_pciconf0 0000:03:00.0 mlx5_0 net-ibp3s0 0
ConnectX7( rev:0) /dev/mst/mt4129_pciconf1 0002:03:00.0 mlx5_1 net-ibP2p3s0 0
ConnectX7( rev:0) /dev/mst/mt4129_pciconf2 0010:03:00.0 mlx5_4 net-ibP16p3s0 1
ConnectX7( rev:0) /dev/mst/mt4129_pciconf3 0012:03:00.0 mlx5_5 net-ibP18p3s0 1
BlueField3( rev:1) /dev/mst/mt41692_pciconf0 0006:03:00.0 mlx5_2 net-enP6p3s0f0np0 0
BlueField3( rev:1) /dev/mst/mt41692_pciconf0.1 0006:03:00.1 mlx5_3 net-bond0 0
BlueField3( rev:1) /dev/mst/mt41692_pciconf1 0016:03:00.0 mlx5_6 net-enP22p3s0f0np0 1
BlueField3( rev:1) /dev/mst/mt41692_pciconf1.1 0016:03:00.1 mlx5_7 net-bond0 1
GB100( rev:0) /dev/mst/mt10561_pciconf0 0008:01:00.0 0
GB100( rev:0) /dev/mst/mt10561_pci_cr0 0008:01:00.0 0
GB100( rev:0) /dev/mst/mt10561_pciconf1 0009:01:00.0 0
GB100( rev:0) /dev/mst/mt10561_pci_cr1 0009:01:00.0 0
GB100( rev:0) /dev/mst/mt10561_pciconf2 0018:01:00.0 1
GB100( rev:0) /dev/mst/mt10561_pci_cr2 0018:01:00.0 1
GB100( rev:0) /dev/mst/mt10561_pciconf3 0019:01:00.0 1
GB100( rev:0) /dev/mst/mt10561_pci_cr3 0019:01:00.0 1
示例中 mlx5_0 的 PCI ID 为 0000:03:00.0。
4.4 查询厂商/设备 ID
根据上一步获取到的 PCI ID 查询:
1
2
lspci -n | grep 0000:03:00.0
0000:03:00.0 0207: 15b3:1021
15b3:Mellanox/NVIDIA 厂商 ID1021:具体设备 ID这里可以获取到配置中需要的 vendors、deviceIDs 参数。
4.5 生成 selectors
汇总以上信息即可写出 selectors,示例如下(可配置多块网卡):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion : v1
kind : ConfigMap
metadata :
name : rdma-devices
namespace : kube-system
data :
config.json : |
{
"periodicUpdateInterval": 300,
"configList": [
{
"resourceName": "hca_shared_devices_a",
"rdmaHcaMax": 1000,
"selectors": {
"vendors": ["15b3"],
"deviceIDs": ["1021"],
"ifNames": ["ibp3s0"]
}
}
]
}
更新 ConfigMap 后重启 Device Plugin:
1
kubectl -n kube-system rollout restart ds rdma-shared-dp-ds
5. 验证
5.1 Node 资源验证
1
kk describe node gb200-pod2-f06-node05 | grep Capacity -A 9
已经能在 Node 上看到 rdma/hca_shared_devices_a 资源了。
5.2 构建测试镜像
基于 Ubuntu 安装 ibv_devices、ibv_devinfo、ibstat、ibstatus 等工具构建一个用于测试的镜像。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
FROM ubuntu:22.04
RUN apt-get update && \
apt-get install -y --no-install-recommends \
perftest \
ibverbs-utils \
ibverbs-providers \
libibumad3 \
libibverbs1 \
librdmacm1 \
infiniband-diags \
iproute2 && \
rm -rf /var/lib/apt/lists/*
ENTRYPOINT [ "sleep" , "infinity" ]
构建镜像:
1
docker build -t rdma-test:v1 .
已经推送到 dockerhub:lixd96/rdma-test:latest
5.3 Pod 申请资源
启动一个 Pod 申请 RDMA 资源:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion : v1
kind : Pod
metadata :
name : mofed-test-pod
spec :
restartPolicy : OnFailure
containers :
- image : rdma-test:v1
name : mofed-test-ctr
securityContext :
capabilities :
add : [ "IPC_LOCK" ]
resources :
limits :
rdma/hca_shared_devices_a : 1
command :
- sh
- -c
- |
ls -l /dev/infiniband /sys/class/infiniband /sys/class/net
sleep 1000000
进入 Pod,使用 ibv_devices 和 ibv_devinfo 查看 IB 卡信息:
1
2
ibv_devices
ibv_devinfo
可以看到 Pod 内已经识别到 mlx5_0 等 RDMA 设备。
例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
root@mofed-test-pod:/# ibv_devices
device node GUID
------ ----------------
mlx5_0 7c8c090300c3cfee
root@mofed-test-pod:/# ibv_devinfo
hca_id: mlx5_0
transport: InfiniBand ( 0)
fw_ver: 28.44.2524
node_guid: 7c8c:0903:00c3:cfee
sys_image_guid: 7c8c:0903:00c3:cfee
vendor_id: 0x02c9
vendor_part_id: 4129
hw_ver: 0x0
board_id: NVD0000000054
phys_port_cnt: 1
port: 1
state: PORT_ACTIVE ( 4)
max_mtu: 4096 ( 5)
active_mtu: 4096 ( 5)
sm_lid: 1
port_lid: 1336
port_lmc: 0x00
link_layer: InfiniBand
5.4 性能验证
为了全面验证 RDMA 的性能,我们需要启动两个 Pod 进行带宽和延迟测试。
Pod 1 (Server) :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion : v1
kind : Pod
metadata :
name : rdma-server
spec :
restartPolicy : OnFailure
containers :
- image : rdma-test:v1
name : mofed-test-ctr
securityContext :
capabilities :
add : [ "IPC_LOCK" ]
resources :
limits :
rdma/hca_shared_devices_a : 1
command :
- sh
- -c
- |
ls -l /dev/infiniband /sys/class/infiniband /sys/class/net
sleep 1000000
Pod 2 (Client) :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
apiVersion : v1
kind : Pod
metadata :
name : rdma-client
spec :
restartPolicy : OnFailure
containers :
- image : rdma-test:v1
name : mofed-test-ctr
securityContext :
capabilities :
add : [ "IPC_LOCK" ]
resources :
limits :
rdma/hca_shared_devices_a : 1
command :
- sh
- -c
- |
ls -l /dev/infiniband /sys/class/infiniband /sys/class/net
sleep 1000000
部署后查看 Pod 状态:
1
2
rdma-server 1/1 Running 0 7m18s 172.25.114.16 gb200-pod2-f06-node05
rdma-client 1/1 Running 0 5m24s 172.25.114.38 gb200-pod2-f06-node05
进入 Pod,使用 ibv_devices 和 ibv_devinfo 查看 IB 卡信息:
1
2
ibv_devices
ibv_devinfo
可以看到 Pod 内已经识别到 mlx5_0 等 RDMA 设备。
例如:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
root@mofed-test-pod:/# ibv_devices
device node GUID
------ ----------------
mlx5_0 7c8c090300c3cfee
root@mofed-test-pod:/# ibv_devinfo
hca_id: mlx5_0
transport: InfiniBand ( 0)
fw_ver: 28.44.2524
node_guid: 7c8c:0903:00c3:cfee
sys_image_guid: 7c8c:0903:00c3:cfee
vendor_id: 0x02c9
vendor_part_id: 4129
hw_ver: 0x0
board_id: NVD0000000054
phys_port_cnt: 1
port: 1
state: PORT_ACTIVE ( 4)
max_mtu: 4096 ( 5)
active_mtu: 4096 ( 5)
sm_lid: 1
port_lid: 1336
port_lmc: 0x00
link_layer: InfiniBand
5.4.1 带宽测试
使用 ib_write_bw 工具测试 RDMA 带宽性能。
进入 rdma-server 启动 server:
1
ib_write_bw -d mlx5_0 -i 1
进入 rdma-client 启动 Client:
1
2
# 其中 172.25.114.16 为 rdma-server 的 IP
ib_write_bw -d mlx5_0 -i 1 172.25.114.16
结果如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
root@rdma-server:/# ib_write_bw -d mlx5_0 -i 1
************************************
* Waiting for client to connect... *
************************************
---------------------------------------------------------------------------------------
RDMA_Write BW Test
Dual-port : OFF Device : mlx5_0
Number of qps : 1 Transport type : IB
Connection type : RC Using SRQ : OFF
PCIe relax order: ON
ibv_wr* API : ON
CQ Moderation : 1
Mtu : 4096[ B]
Link type : IB
Max inline data : 0[ B]
rdma_cm QPs : OFF
Data ex. method : Ethernet
---------------------------------------------------------------------------------------
local address: LID 0x538 QPN 0x0171 PSN 0x7ef7d8 RKey 0x1fff00 VAddr 0x00aaaaaab00000
remote address: LID 0x451 QPN 0x0165 PSN 0xac1c4 RKey 0x1fff00 VAddr 0x00aaaaaab80000
---------------------------------------------------------------------------------------
#bytes #iterations BW peak[MB/sec] BW average[MB/sec] MsgRate[Mpps]
65536 5000 46711.55 45733.81 0.731741
---------------------------------------------------------------------------------------
测试结果为 46 GB/s 带宽,IB 卡为 400Gb/s,理论带宽为 50GB/s,该结果已经接近 IB 带宽上限,说明 RDMA 已能正常使用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
root@rdma-server:/# ibstat
CA 'mlx5_0'
CA type: MT4129
Number of ports: 1
Firmware version: 28.44.2524
Hardware version: 0
Node GUID: 0x7c8c090300c3a7ae
System image GUID: 0x7c8c090300c3a7ae
Port 1:
State: Active
Physical state: LinkUp
Rate: 400
Base lid: 1105
LMC: 0
SM lid: 1
Capability mask: 0xa751e848
Port GUID: 0x7c8c090300c3a7ae
Link layer: InfiniBand
5.4.2 延迟测试
除了带宽,延迟也是 RDMA 的重要性能指标。使用 ib_write_lat 测试延迟:
在 rdma-server 中启动:
1
ib_write_lat -d mlx5_0 -i 1
在 rdma-client 中连接:
1
ib_write_lat -d mlx5_0 -i 1 172.25.114.16
测试结果示例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
---------------------------------------------------------------------------------------
RDMA_Write Latency Test
Dual-port : OFF Device : mlx5_0
Number of qps : 1 Transport type : IB
Connection type : RC Using SRQ : OFF
PCIe relax order: OFF
ibv_wr* API : ON
TX depth : 1
Mtu : 4096[ B]
Link type : IB
Max inline data : 220[ B]
rdma_cm QPs : OFF
Data ex. method : Ethernet
---------------------------------------------------------------------------------------
local address: LID 0x451 QPN 0x0167 PSN 0xca7dd8 RKey 0x1ffbba VAddr 0x00aaaaaab00000
remote address: LID 0x538 QPN 0x0173 PSN 0x66403f RKey 0x1fecab VAddr 0x00aaaaaab00000
---------------------------------------------------------------------------------------
#bytes #iterations t_min[usec] t_max[usec] t_typical[usec] t_avg[usec] t_stdev[usec]
2 100 2.62 3.84 2.74 2.73 0.04
测试结果显示,RDMA 的单向延迟约为 2.73 微秒 ,相比传统 TCP/IP 网络(通常 50-100 微秒),延迟降低了 20-40 倍 。同时标准差仅为 0.04 微秒,说明延迟非常稳定,充分体现了 RDMA 的低延迟优势。
6. 是否需要 Multus CNI?
在 Kubernetes RDMA 方案中,是否引入 Multus CNI 取决于具体的应用场景和网络需求。
6.1 不需要 Multus CNI 的场景
如果你的需求满足以下条件,通常不需要 Multus CNI:
仅需要 IB Verbs API :应用(如 vLLM、NCCL)直接调用 RDMA 接口,不依赖 IP 协议进行通信(或者仅用于控制面)。使用 Shared Device Plugin :本文介绍的 k8s-rdma-shared-dev-plugin 可以在不改变 Pod 网络命名空间结构的情况下,将 RDMA 设备文件(/dev/infiniband/*)暴露给 Pod。扁平网络架构 :RDMA 网卡和 Kubernetes 管理网卡处于同一网络平面,或者你能够接受 Pod 沿用 Host 网络的部分特性。在这种模式下,Pod 依然使用默认 CNI(如 Calico、Flannel)分配的 IP 进行常规通信,同时拥有了访问 RDMA 硬件的能力。这是最简单、维护成本最低的方案。
6.2 需要 Multus CNI 的场景
如果存在以下需求,则建议 引入 Multus CNI:
网络隔离 :需要将 RDMA 流量与 Kubernetes 管理/业务流量完全物理隔离。独立 IP 地址 :需要为 RDMA 网卡分配独立的 IP 地址(例如使用 IPoIB 或 RoCEv2 路由模式),以便应用通过特定 IP 进行绑定。SR-IOV 场景 :如果使用 sriov-cni 将物理网卡虚拟化为 VF 直接透传给 Pod,通常需要 Multus 来管理这个额外的网络接口。6.3 结论
对于大多数基于 k8s-rdma-shared-dev-plugin 的分布式推理和训练任务,不需要 额外部署 Multus CNI。直接通过 Device Plugin 暴露设备,配合应用层的 RDMA 库即可实现高性能通信。引入 Multus 会显著增加网络配置的复杂度,应仅在确有必要(如强隔离、SR-IOV)时使用。
7. 小结
本文系统性地梳理了在 Kubernetes 集群中落地 RDMA 技术的完整路径。从基础概念的认知,到硬件环境的准备,再到 Device Plugin 的部署与配置,最后通过实际的性能压测验证了 RDMA 性能的优越性。
核心要点回顾:
技术价值 :RDMA 通过零拷贝和内核旁路技术,解决了 TCP/IP 网络在高带宽场景下的 CPU 瓶颈和延迟问题,是释放 GPU 集群算力的关键基础设施。部署策略 :对于大多数 AI 推理和训练场景,使用 k8s-rdma-shared-dev-plugin 配合 Shared 模式是最轻量级的方案。它无需复杂的网络改造,即可让 Pod 获得原生 RDMA 能力。架构决策 :在引入 Multus CNI 之前应审慎评估。如果不需要物理隔离或独立 IP,直接复用 Host 网络栈(通过 Device Plugin 暴露设备)往往能带来更低的操作复杂度和更高的稳定性。随着云原生 AI 的持续演进,底层网络设施的性能优化将变得愈发重要。掌握 RDMA 在 Kubernetes 中的配置与管理,将成为构建高性能 AI 平台的必备技能。未来,我们还可以进一步探索 GPUDirect RDMA、SR-IOV 等进阶技术,以应对更大规模、更低延迟的计算挑战。