ib网卡隔离配置记录
背景
在一台 Ubuntu 24.04 服务器上,机器插入了两张高速网卡,每张网卡提供两个光模块口,因此一共有四个可配置的高速网口。计划为四个网口分别配置如下 IP 地址:
| 网口 | IP 地址 | 隔离命名空间 |
|---|---|---|
ens3f0np0 |
10.0.0.101/24 |
ns101 |
ens3f1np1 |
10.0.0.102/24 |
ns102 |
ens6f0np0 |
10.0.0.103/24 |
ns103 |
ens6f1np1 |
10.0.0.104/24 |
ns104 |
最终目标是将四个光口都接入交换机,并让这些 IP 之间的访问必须经过物理网口出到交换机,再由交换机转发回来,而不是被 Linux 本机网络栈直接在机内转发。
在正式接交换机之前,先用两根光纤做点对点连通性测试:
1 | ens3f0np0 <----光纤----> ens3f1np1 |
也就是:
1 | ns101 / 10.0.0.101 <----> ns102 / 10.0.0.102 |
为什么需要隔离
如果直接把 10.0.0.101、10.0.0.102、10.0.0.103、10.0.0.104 都配置在同一个 Linux 默认网络命名空间里,Linux 会把这些地址都认为是本机地址。
此时从 10.0.0.101 访问 10.0.0.102,流量很可能不会真的从物理光口发出,而是直接走 Linux 内核的本地路由表完成本机交付。
这显然不符合测试目标。我们希望把四个网口模拟成四台独立主机,因此使用 network namespace 将四个物理网口分别隔离到四个独立网络栈中。
隔离后的逻辑结构如下:
1 | 默认 namespace |
这样一来,每个 IP 都处于不同的网络命名空间中,访问其他 IP 时必须从自身所在 namespace 的物理网口发出。
网口信息确认
初始状态下,四个目标网口分别为:
1 | ens3f0np0 |
另外机器上还存在管理口或其他网口,例如:
1 | enx0a94efbb254b |
配置过程中需要注意,尽量不要通过目标实验网口 SSH 登录服务器。因为一旦把目标网口移动到 namespace 中,默认 namespace 将无法继续直接使用这些网口,远程连接可能中断。
清理默认命名空间中的网口配置
先清理四个实验网口上的旧地址:
1 | sudo ip addr flush dev ens3f0np0 |
然后将四个网口临时关闭:
1 | sudo ip link set ens3f0np0 down |
查看默认命名空间中的网口:
1 | ip link |
此时四个实验口仍能在默认 namespace 中看到,但已经没有 IPv4 地址。
创建 network namespace
创建四个独立 namespace:
1 | sudo ip netns add ns101 |
将四个物理网口分别移动到对应 namespace:
1 | sudo ip link set ens3f0np0 netns ns101 |
移动完成后,在默认 namespace 下执行:
1 | ip link |
此时应该已经看不到以下四个网口:
1 | ens3f0np0 |
这说明它们已经从默认 namespace 中移走,进入各自的 network namespace。
配置 namespace 内部地址
启动每个 namespace 中的 loopback:
1 | sudo ip netns exec ns101 ip link set lo up |
配置 IPv4 地址:
1 | sudo ip netns exec ns101 ip addr add 10.0.0.101/24 dev ens3f0np0 |
启动网口:
1 | sudo ip netns exec ns101 ip link set ens3f0np0 up |
检查地址配置:
1 | sudo ip netns exec ns101 ip -br addr |
预期结果类似:
1 | lo UNKNOWN 127.0.0.1/8 ::1/128 |
查看路由:
1 | sudo ip netns exec ns101 ip route |
预期每个 namespace 中都有一条直连路由:
1 | 10.0.0.0/24 dev ens3f0np0 proto kernel scope link src 10.0.0.101 |
这里保留 /24 是因为后续四个网口会接入同一个交换机 VLAN。如果只是永久点对点直连,也可以考虑 /32 + peer route,但本次场景不需要。
隔离状态检查
默认 namespace 中执行:
1 | ip link |
此时只应看到管理网口和其他未隔离网口,例如:
1 | lo |
看不到四个实验口,说明隔离已经生效。
进一步检查默认 namespace 是否还有 10.0.0.x 地址:
1 | ip addr | grep 10.0.0 |
正常情况下不应有输出。
在 namespace 内部查看访问路径:
1 | sudo ip netns exec ns101 ip route get 10.0.0.102 |
预期类似:
1 | 10.0.0.102 dev ens3f0np0 src 10.0.0.101 |
说明 ns101 访问 10.0.0.102 会从 ens3f0np0 发出,而不是走默认 namespace 的本地路由。
点对点连通性测试
当前临时拓扑是两根光纤两两直连,因此只测试两组对应关系:
1 | 10.0.0.101 <-> 10.0.0.102 |
测试第一组:
1 | sudo ip netns exec ns101 ping -I 10.0.0.101 10.0.0.102 |
测试第二组:
1 | sudo ip netns exec ns103 ping -I 10.0.0.103 10.0.0.104 |
实际测试中,两组链路均能正常 ping 通,丢包率为 0%,延迟在亚毫秒级。
需要注意的是,在当前点对点连接方式下,不应该期待 10.0.0.101 直接 ping 通 10.0.0.103 或 10.0.0.104。因为这几组 IP 之间没有交换机,也没有直接光纤链路。等四个网口全部接入交换机后,才应该测试任意两两互通。
光口链路状态检查
使用 ethtool 检查四个口链路状态:
1 | sudo ip netns exec ns101 ethtool ens3f0np0 | grep -E "Speed|Duplex|Link detected" |
实际结果四个端口均为:
1 | Speed: 100000Mb/s |
说明四个光口均已经以 100G 全双工状态正常连接。
抓包测试
抓包可以用于确认流量确实从 namespace 内的物理网口发出。
第一组链路抓包:
1 | sudo ip netns exec ns101 tcpdump -i ens3f0np0 -nn -e 'arp or icmp' |
另一个终端执行:
1 | sudo ip netns exec ns101 ping -I 10.0.0.101 10.0.0.102 |
如果抓包中可以看到 ARP 和 ICMP 报文,说明流量确实经过 ens3f0np0。
保存抓包文件:
1 | sudo ip netns exec ns101 tcpdump -i ens3f0np0 -nn -s 0 -w ns101_to_ns102.pcap 'arp or icmp' |
第二组链路类似:
1 | sudo ip netns exec ns103 tcpdump -i ens6f0np0 -nn -e 'arp or icmp' |
保存抓包文件:
1 | sudo ip netns exec ns103 tcpdump -i ens6f0np0 -nn -s 0 -w ns103_to_ns104.pcap 'arp or icmp' |
查看抓包文件:
1 | tcpdump -nn -r ns101_to_ns102.pcap |
TCP 测速
可以使用 iperf3 做普通 TCP 带宽测试。
安装工具:
1 | sudo apt update |
第一组链路中,ns102 作为服务端:
1 | sudo ip netns exec ns102 iperf3 -s -B 10.0.0.102 |
ns101 作为客户端:
1 | sudo ip netns exec ns101 iperf3 -c 10.0.0.102 -B 10.0.0.101 -P 8 -t 30 |
反向测试:
1 | sudo ip netns exec ns101 iperf3 -c 10.0.0.102 -B 10.0.0.101 -P 8 -t 30 -R |
双向测试:
1 | sudo ip netns exec ns101 iperf3 -c 10.0.0.102 -B 10.0.0.101 -P 8 -t 30 --bidir |
第二组链路中,ns104 作为服务端:
1 | sudo ip netns exec ns104 iperf3 -s -B 10.0.0.104 |
ns103 作为客户端:
1 | sudo ip netns exec ns103 iperf3 -c 10.0.0.104 -B 10.0.0.103 -P 8 -t 30 |
100G 网卡下,单 TCP 流通常很难跑满链路,所以建议使用 -P 8、-P 16 或 -P 32 多流测试。若多流数量增加后吞吐明显上升,说明瓶颈可能在单流 CPU、TCP 栈、队列或中断调度上。
测速过程中可以查看实时接口速率:
1 | sudo ip netns exec ns101 ifstat -i ens3f0np0 1 |
也可以查看网卡硬件统计:
1 | sudo ip netns exec ns101 ethtool -S ens3f0np0 | grep -Ei 'rx|tx|err|drop|discard|crc' |
RDMA 与 IB 设备映射
在进行 IB/RDMA 打流之前,需要确认 RDMA 设备号和 Linux 网口之间的对应关系。
在 namespace 中执行:
1 | sudo ip netns exec ns101 ibdev2netdev |
示例对应关系:
1 | ns101: ens3f0np0 -> mlx5_2 -> 10.0.0.101 |
本次测试中,第一组使用:
1 | ens3f0np0 -> mlx5_2 |
第二组需要根据 ibdev2netdev 的实际输出确认设备号。
查看 namespace 内 IP 地址:
1 | sudo ip netns exec ns101 ip a |
查看 RDMA 设备:
1 | sudo ip netns exec ns101 ibv_devices |
查看设备状态:
1 | sudo ip netns exec ns101 ibv_devinfo -d mlx5_2 |
重点关注:
1 | state: PORT_ACTIVE |
如果是 RoCE 场景,link_layer 通常为 Ethernet。
RC 模式 IB 打流测试
安装测试工具:
1 | sudo apt update |
第一组链路中,ns101 作为 server:
1 | sudo ip netns exec ns101 ib_send_bw -d mlx5_2 -i 1 -p 65531 --report_gbits --run_infinitely |
ns102 作为 client:
1 | sudo ip netns exec ns102 ib_send_bw -d mlx5_3 -i 1 10.0.0.101 -p 65531 --report_gbits --run_infinitely |
这里的流量方向是:
1 | ns102 / mlx5_3 / 10.0.0.102 -> ns101 / mlx5_2 / 10.0.0.101 |
如果只需要跑固定时间,例如 30 秒,可以使用:
1 | sudo ip netns exec ns101 ib_send_bw -d mlx5_2 -i 1 -p 65531 --report_gbits -D 30 |
client 端:
1 | sudo ip netns exec ns102 ib_send_bw -d mlx5_3 -i 1 10.0.0.101 -p 65531 --report_gbits -D 30 |
反向测试时,交换 server 和 client:
1 | sudo ip netns exec ns102 ib_send_bw -d mlx5_3 -i 1 -p 65531 --report_gbits -D 30 |
1 | sudo ip netns exec ns101 ib_send_bw -d mlx5_2 -i 1 10.0.0.102 -p 65531 --report_gbits -D 30 |
第二组链路的测试方式相同,只需要把设备名和 IP 替换为对应关系。例如假设:
1 | ens6f0np0 -> mlx5_4 |
则可以使用:
1 | sudo ip netns exec ns103 ib_send_bw -d mlx5_4 -i 1 -p 65532 --report_gbits -D 30 |
1 | sudo ip netns exec ns104 ib_send_bw -d mlx5_5 -i 1 10.0.0.103 -p 65532 --report_gbits -D 30 |
这里第二组使用 65532,主要是为了并发测试时区分端口和日志。
提高 RDMA 打流压力
如果默认参数无法打满 100G,可以尝试增大消息大小:
1 | -s 65536 |
或者增加 QP 数量:
1 | -q 4 |
示例:
1 | sudo ip netns exec ns101 ib_send_bw -d mlx5_2 -i 1 -p 65531 --report_gbits -s 65536 -q 4 -D 30 |
client 端:
1 | sudo ip netns exec ns102 ib_send_bw -d mlx5_3 -i 1 10.0.0.101 -p 65531 --report_gbits -s 65536 -q 4 -D 30 |
可以按如下顺序逐步增加压力:
1 | -q 1 |
不要一开始就设置过大的 QP 数量,否则不利于判断瓶颈来源。
RoCE 抓包观察
在 RoCEv2 场景下,普通 tcpdump 可以看到 ARP、TCP 控制连接以及 UDP 4791 相关报文。
第一组链路抓包:
1 | sudo ip netns exec ns101 tcpdump -i ens3f0np0 -nn -e 'arp or icmp or udp port 4791 or tcp port 65531' |
保存抓包文件:
1 | sudo ip netns exec ns101 tcpdump -i ens3f0np0 -nn -s 0 -w ib_ns101_ns102.pcap 'arp or udp port 4791 or tcp port 65531' |
第二组链路抓包:
1 | sudo ip netns exec ns103 tcpdump -i ens6f0np0 -nn -s 0 -w ib_ns103_ns104.pcap 'arp or udp port 4791 or tcp port 65532' |
如果只能看到 TCP 控制连接,但看不到 UDP 4791,可能需要进一步检查 GID index、RoCE 模式、设备映射或 RDMA 数据路径。
GID index 检查
RoCE 测试中,经常需要指定 GID index。可以查看 GID:
1 | sudo ip netns exec ns101 show_gids |
如果查到 IPv4 地址对应的 GID index 是 3,则 ib_send_bw 命令中加入:
1 | -x 3 |
示例:
1 | sudo ip netns exec ns101 ib_send_bw -d mlx5_2 -i 1 -x 3 -p 65531 --report_gbits -D 30 |
client 端同样加入 -x 3:
1 | sudo ip netns exec ns102 ib_send_bw -d mlx5_3 -i 1 -x 3 10.0.0.101 -p 65531 --report_gbits -D 30 |
如果不确定 GID index,可以先不加 -x 测试;如果报 GID、route、connection 或 RDMA_CM 相关错误,再根据 show_gids 结果指定。
常见问题排查
MTU设置
MTU 是 Maximum Transmission Unit,中文通常叫 最大传输单元。它表示一个网络接口在一次二层链路传输中,能够承载的最大三层数据包大小,单位是字节。
在 100G RoCE/RDMA 打流测试中,MTU 是影响性能的重要因素之一。如果网口仍然使用默认 1500 MTU,可能导致包率压力较大,RDMA active_mtu 也可能偏小,从而影响 ib_send_bw 或 ib_write_bw 的测试结果。
建议将四个隔离后的物理网口 MTU 设置为 9000,也就是开启 Jumbo Frame。
当前四个 namespace 对应关系为:
1 | ns101 -> ens3f0np0 -> 10.0.0.101 |
设置 MTU:
1 | sudo ip netns exec ns101 ip link set dev ens3f0np0 mtu 9000 |
检查是否生效:
1 | sudo ip netns exec ns101 ip -br link show ens3f0np0 |
预期可以看到 mtu 9000。
如果当前是两根光纤点对点直连,可以使用大包 ping 验证 MTU。MTU 为 9000 时,IPv4 ICMP payload 通常使用 8972 测试:
1 | sudo ip netns exec ns101 ping -M do -s 8972 -c 3 -I 10.0.0.101 10.0.0.102 |
第二组:
1 | sudo ip netns exec ns103 ping -M do -s 8972 -c 3 -I 10.0.0.103 10.0.0.104 |
如果能够正常返回,说明链路两端的 9000 MTU 基本可用。
后续接交换机后的测试思路
当前只是两根光纤点对点互联,用于确认网口隔离、链路状态、基础通信和 RDMA 打流能力。
后续四个网口接入交换机后,应确保交换机侧满足:
1 | 四个端口在同一个 VLAN |
接入交换机后,需要测试任意两两互通:
1 | sudo ip netns exec ns101 ping -I 10.0.0.101 10.0.0.102 |
并通过抓包确认流量从物理口出去:
1 | sudo ip netns exec ns101 tcpdump -i ens3f0np0 -nn -e 'arp or icmp' |
如果 ns101 访问 10.0.0.103 时,ens3f0np0 上能看到 ARP 和 ICMP 报文,就可以确认流量确实经过物理口出到交换机,而不是走机内 local route。
小结
本次配置的核心思路是:不要把四个高速网口的 IP 放在同一个 Linux 默认网络栈中,而是将每个物理网口分别放入独立的 network namespace。
最终形成的隔离关系为:
1 | ens3f0np0 -> ns101 -> 10.0.0.101/24 |
当前验证结果表明:
1 | 四个网口已经从默认 namespace 中移走 |
这套方式适合在单台服务器上模拟多台独立主机的高速网卡通信行为,也适合后续接入交换机测试二层转发、RoCE/RDMA 打流、链路隔离和多端口并发吞吐。





