我在一台 Linux 机器上有两个以太网接口。它们都有以下 IP 地址:接口 A:10.0.1.5/24 接口 B:10.0.2.5/24
两个接口都连接到在两个网络之间路由的路由器。
现在我想启动 iperf3 测量,将服务器绑定到接口 A,将客户端绑定到接口 B。
问题是流量不会离开物理接口,而是只流经内核,从而导致在链路上不可能达到的速度。
我该怎么做才能强制流量通过物理接口?ip_forward 已被禁用。
谢谢。
答案1
这会非常困难(但是不是不可能) 让 Linux 系统使用单个路由堆栈,在不使用接口的情况下对从其自身到其自身的数据包执行多宿主路由lo
。
但在 Linux 上创建额外的网络堆栈来在一个系统内模拟多个系统非常容易:通过使用网络命名空间。
在这里,可以将两个 NIC 中的一个交给新的网络命名空间,该网络命名空间将是初始(主机)网络命名空间的对等体。它们不会直接通信,而只能通过外部路由器通信。我们假设接口确实名为A
并且B
路由器使用地址10.0.1.1/24
+ 10.0.2.1/24
。
使用时创建一个新的网络命名空间,并提供额外的便利管理iproute2工具(在底层,命名空间伪文件被安装以在没有进程的情况下保持资源不变,等等)。
ip netns add sideB
将接口移动
B
到新的网络命名空间:ip link set dev B netns sideB
注意:无线接口需要使用
iw
命令。配置新的网络命名空间:
当接口更改命名空间时,其所有网络设置都将丢失(在接口消失、触发地址消失、触发路由消失的主机上以及在新的网络命名空间上):
ip -n sideB link set dev B up ip -n sideB address add 10.0.2.5/24 dev B
不需要,但万一 iperf3 出现混淆,有一个功能齐全的环回接口:
ip -n sideB link set lo up
配置双方之间的路由(初始/主机命名空间可能已经通过默认路由,但让我们明确一点)
ip route add 10.0.2.0/24 via 10.0.1.1 dev A ip -n sideB route add 10.0.1.0/24 via 10.0.2.1 dev B
现在可以运行(在两个终端):
iperf3 -s
ip netns exec sideB iperf3 -c 10.0.1.5
客户端在新的网络命名空间中运行。
测量结束后,删除网络命名空间会将 NIC 返回到主机命名空间。但如果任何进程错误地使用了此网络命名空间(例如ip netns exec side B setsid sleep 9999
),则ip netns delete sideB
下面的操作只会从主机视图中删除命名空间iproute2工具,但直到进程结束才真正删除命名空间,导致 NIC 难以恢复。所以最好先将其移回:
ip -n sideB link set dev B netns 1
ip netns delete sideB
其中1
表示 PID 1 的网络命名空间:初始/主机命名空间。此外,这允许在已分配物理 NIC 的容器内执行实验(因为1
网络命名空间是容器的命名空间,而不是实际主机的命名空间),否则如果无法访问主机,物理 NIC 将重新出现在主机上,并且将永远丢失在容器中。
如果没有工具(如 udev +下拉如果网络管理器allow-hotplug
(NetworkManager) 检测到 NIC 的出现,则在其返回时必须再次进行配置。