免费获取学习方案
ARTICLE DETAIL

资讯详情

深耕编程基础知识与建站技术分享的一线实战洞察。

将 RDMA 引入容器:Soft-RoCE (RXE) 网络命名空间支持深度解析

将 RDMA 引入容器:Soft-RoCE (RXE) 网络命名空间支持深度解析 摘要在云原生与容器化技术普及的背景下Linux 网络命名空间Network Namespace,netns构成了 Docker、Kubernetes 等容器隔离的核心基础。然而Linux 内核中的Soft-RoCE (RXE)基于软件实现的 RoCEv2 协议栈驱动在以往版本中存在严重的“命名空间盲Namespace-Blind”缺陷导致其无法直接运行于隔离的容器环境中。本文基于朱彦军Zhu Yanjun提出的技术修改与补丁集方案RDMA/rxe: Add network namespace support深入分析 RXE 驱动在网络命名空间隔离下的痛点根源、内核重构设计、技术实现细节以及实测场景。一、 背景介绍与核心概念1. Docker 与网络命名空间 (Net Namespace)容器通过 Linux 内核的cgroup资源限制、chroot文件系统隔离以及namespace视图隔离来实现微服务环境。其中网络命名空间Net Namespace为每个容器提供了独立的网络协议栈包括独立的网络设备如eth0、veth、IP 地址、路由表以及 Socket 端口池实现容器间网络流量的严格隔离。2. RDMA 与 RoCEv2 协议传统 TCP/IP 网络协议栈存在多次数据拷贝Memory Copy以及频繁的 CPU 上下文切换。RDMA远程直接内存访问技术通过 Kernel Bypass内核旁路和零拷贝Zero-copy特性大幅降低了网络延迟并减少了 CPU 占用率。RoCEv2Routable RoCE将传统 Infiniband 传输层封装在标准 UDP/IP 数据包中使用系统预留的目标 UDP 端口4791使其具备可路由性被广泛应用于数据中心与云原生环境。3. Soft-RoCE (RXE) 架构Soft-RoCE 是 RoCEv2 的纯软件实现使得不需要专用硬件 RDMA 网卡HCA的普通以太网卡如 Intel E810、Mellanox 等也能运行 RDMA 应用用户空间通过rdma-corelibibverbs提供通用的 Verbs API最终调用 Soft-RoCE 用户态驱动。内核空间rdma_rxe内核模块挂载在普通 NIC 驱动之上接收来自 RDMA 栈的数据后构造skb数据包并放入 UDP 载荷中再递交给系统的 TCP/IP 协议栈发送。二、 核心痛点全局 Socket 导致的隔离阻断1. 问题根源 (Root Cause)在旧版的 RXE 内核实现中当使用modprobe rdma_rxe加载 RXE 模块时驱动会直接在主机的初始网络命名空间init_net中创建一个全局的 UDP Socket并固定监听4791端口。旧版旧架构瓶颈Bottleneck Host (init_net) ----------------------- 全局 RXE Socket | RDMA/rxe Kernel Mod | --- (UDP 端口 4791) ----------------------- ^ | | (访问被隔离墙拒绝!) v | -------------------- -------------------- | Namespace A (NS1) | | Namespace B (NS2) | | [rxe0 Link] | | [rxe1 Link] | -------------------- --------------------2. 产生的后果由于 Linux 内核对不同 Net Namespace 之间的 Socket 访问设置了严格的边界防护运行在独立容器自定义 Net Namespace中的应用进程无法访问宿主机init_net下的全局 Socket。即便在容器内部尝试创建 RXE 链路其数据平面也会因为无法建立 UDP 传输通道而导致通信中断。三、 重构解决方案Per-Namespace 资源管理为了彻底消除这一限制补丁方案将 RXE 驱动从“全局单套接字模型”全面重构为基于每个网络命名空间Per-Namespace独立管理的架构。重构后架构Namespace-Aware Host (init_net) ------------------------------------------------------------- | RDMA/rxe Kernel Module (Namespace-Aware via pernet_ops) | ------------------------------------------------------------- | | v v -------------------- -------------------- | Container A (NS1) | | Container B (NS2) | | [rxe0 Link] | | [rxe1 Link] | | [UDP: 4791 Sock] | | [UDP: 4791 Sock] | -------------------- --------------------1. 代码重构与上下文存储新增rxe_ns.c和rxe_ns.h源文件基于内核的pernet_operations框架实现上下文初始化。引入核心数据结构struct rxe_ns_sock按网络命名空间 ID 保存 IPv4/IPv6 的监听 Socket 句柄/* Per network namespace data */ struct rxe_ns_sock { struct sock __rcu *rxe_sk4; struct sock __rcu *rxe_sk6; };2. Socket 按需动态创建Dynamic Lifecycle模块加载阶段运行modprobe rdma_rxe时驱动不再在 Host 主机上监听 UDP 4791 端口。链路创建阶段只有当用户在该命名空间内执行rdma link add ...命令创建 RXE 链路时驱动才会在当前 Net Namespace 内部动态创建并绑定 UDP 4791 端口。3. 链路销毁与资源回收 (Dellink Support)之前的rdma_link_ops结构体缺乏链路删除的回调函数。补丁补充扩展了struct rdma_link_ops增加了dellink回调并实现了rxe_del_link。当执行rdma link del时能精准回收对应 Namespace 下的 Socket 及相关上下文资源。四、 命令与行为验证1. 宿主机操作表现# 加载 RXE 内核模块此时并不监听 4791 端口 # modprobe -v rdma_rxe # ss -lun | grep 4791 # 在宿主机创建 RXE 链路4791 端口在宿主机被创建并监听 # rdma link add rxe0 type rxe netdev eno1 # ss -lun | grep 4791 UNCONN 0 0 0.0.0.0:4791 0.0.0.0:* UNCONN 0 0 [::]:4791 [::]:*2. 隔离网络命名空间表现# 新建网络命名空间 net0此时内部没有 4791 端口 # ip netns add net0 # ip netns exec net0 ss -lun | grep 4791 # 在 net0 中创建 RXE 链路UDP 4791 端口成功在此 namespace 内单独监听 # ip netns exec net0 rdma link add rxe1 type rxe netdev lo # ip netns exec net0 ss -lun | grep 4791 UNCONN 0 0 0.0.0.0:4791 0.0.0.0:* UNCONN 0 0 [::]:4791 [::]:*3. 删除链路验证# 执行 link del成功释放 4791 端口 # rdma link del rxe0 # ss -lun | grep 4791 # (输出为空说明端口与套接字资源已正确关闭)五、 典型容器网络拓扑验证重构后的驱动针对以下常用容器拓扑结构进行了详细的rping数据传输验证Host 到 Container 场景宿主机与独立容器之间通过veth pair打通分别创建 RXE 链路并进行 RDMA 通信。Container 到 Container 对等场景两个 Net Namespacetest1与test2通过veth pair直连两端分别运行rping -s服务端与rping -c客户端。多容器虚拟网桥 (Bridge) 场景模拟 Docker / K8s 的经典网桥拓扑。创建多个 Namespaceone,two,three通过各自的veth接入宿主机的virtual-bridge中并在不同容器间成功执行 RDMA Ping 测试。六、 总结通过引入pernet_operations与动态 Socket 绑定机制该改进使得 Soft-RoCE (RXE) 彻底脱离了宿主机限制使 RDMA 能够在隔离的容器环境中作为“一等公民”平滑运行。这为云原生研发人员在纯软件定义的搭建环境中部署、调试以及验证复杂的容器化 RDMA 应用奠定了堅实的基础。
返回列表