对于每个 Network Namespace 来说,它会有自己独立的网卡、路由表、ARP 表、iptables 等和网络相关的资源。ip 命令提供了 ip netns exec 子命令可以在对应的 Network Namespace 中执行命令。PS: 也就是 ip netns exec 操作网卡、路由表、ARP 表、iptables 等。也可以打开一个 shell ,后面所有的命令都在这个 Network Namespace 中执行,好处是不用每次执行命令时都要带上 ip netns exec ,缺点是我们无法清楚知道自己当前所在的 shell,容易混淆。

默认情况下,network namespace 是不能和主机网络,或者其他 network namespace 通信的。可以使用 Linux 提供的 veth pair 来完成通信,veth pair 你可以理解为使用网线连接好的两个接口,把两个端口放到两个 namespace 中,那么这两个 namespace 就能打通。

虽然 veth pair 可以实现两个 Network Namespace 之间的通信,但 veth pair 有一个明显的缺陷,就是只能实现两个网络接口之间的通信。如果多个 network namespace 需要进行通信,则需要借助 bridge。


创建一对 veth(Virtual Ethernet)接口,并将它们连接到不同的网络命名空间,然后通过 Linux Bridge 相连

# 创建第一个veth对
ip netns add ns1                  # 创建命名空间 ns1
ip netns exec ns1 ip link set lo up # 在 ns1 中启用 loopback 接口

ip link add veth1 type veth peer name veth2 # 创建 veth1 和 veth2 接口
ip link set veth1 netns ns1       # 将 veth1 接口移动到命名空间 ns1

# 创建第二个veth对
ip netns add ns2                  # 创建命名空间 ns2
ip netns exec ns2 ip link set lo up # 在 ns2 中启用 loopback 接口

ip link set veth2 netns ns2       # 将 veth2 接口移动到命名空间 ns2

# 创建 Linux Bridge
ip link add name br0 type bridge  # 创建一个名为 br0 的 Linux Bridge
ip link set dev br0 up            # 启用 Linux Bridge

# 连接 veth 接口到 Linux Bridge
ip link set veth1 master br0      # 将 veth1 接口连接到 br0
ip link set veth2 master br0      # 将 veth2 接口连接到 br0

为什么要启用 loopback 接口

在配置网络命名空间时,启用 loopback 接口是一个良好的实践。Loopback 接口是一个虚拟接口,用于在本地主机上进行内部通信。它具有以下几个重要作用:

  1. 用于本地主机内部的通信:启用 loopback 接口后,可以在同一主机上的不同命名空间之间进行通信。这对于某些应用程序和服务可能需要在本地主机上进行内部通信的情况非常有用。
  2. 调试和测试:启用 loopback 接口后,可以在命名空间中模拟和测试本地主机上的服务和应用程序。这对于调试和测试网络配置以及应用程序的网络功能非常有帮助。
  3. 兼容性和一致性:启用 loopback 接口可以保持网络配置的一致性。在某些情况下,应用程序可能期望能够通过 loopback 接口进行通信,因此在命名空间中启用该接口可以确保与这些应用程序的兼容性。


ip netns exec ns1 ip addr add 192.168.1.1/24 dev veth1   # 配置 veth1 的IP地址为 192.168.1.1/24
ip netns exec ns1 ip link set veth1 up                   # 启用 veth1 接口

ip netns exec ns2 ip addr add 192.168.1.2/24 dev veth2   # 配置 veth2 的IP地址为 192.168.1.2/24
ip netns exec ns2 ip link set veth2 up                   # 启用 veth2 接口

check

root@Copy-of-VM-U2204:~# ip netns exec ns2 ip r
192.168.1.0/24 dev veth2 proto kernel scope link src 192.168.1.2
root@Copy-of-VM-U2204:~# ip netns exec ns1 ip r
192.168.1.0/24 dev veth1 proto kernel scope link src 192.168.1.1
root@Copy-of-VM-U2204:~# ip netns exec ns2 ping  192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=64 time=0.011 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=64 time=0.009 ms
64 bytes from 192.168.1.1: icmp_seq=3 ttl=64 time=0.010 ms
^C
--- 192.168.1.1 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2029ms
rtt min/avg/max/mdev = 0.009/0.010/0.011/0.000 ms
root@Copy-of-VM-U2204:~# ip netns exec ns2 ping  192.168.1.2
PING 192.168.1.2 (192.168.1.2) 56(84) bytes of data.
64 bytes from 192.168.1.2: icmp_seq=1 ttl=64 time=0.007 ms
64 bytes from 192.168.1.2: icmp_seq=2 ttl=64 time=0.010 ms

借别人一个图

Linux Bridge与veth_命名空间

另外一种方式, 对应上图的逻辑

ip netns add ns1
ip netns add ns2

ip link add veth1 type veth peer name br-veth1
ip link set veth1 netns ns1
ip link set br-veth1 up

ip link add veth2 type veth peer name br-veth2
ip link set veth2 netns ns2
ip link set br-veth2 up

ip link add name br0 type bridge
ip link set br0 up

ip link set br-veth1 master br0
ip link set br-veth2 master br0

ip netns exec ns1 ip link set veth1 up
ip netns exec ns1 ip addr add 192.168.1.1/24 dev veth1

ip netns exec ns2 ip link set veth2 up
ip netns exec ns2 ip addr add 192.168.1.2/24 dev veth2

如果lo是down的状态

Linux Bridge与veth_Ethernet_02

当我们创建一个新的网络命名空间时,它包含一个本地回环接口(lo),但默认情况下,这个接口处于关闭(down)状态。

本地回环接口(loopback interface)是一个特殊类型的网络接口,它用于网络软件组件在同一台主机上进行通讯。它的 IP 地址通常设置为 127.0.0.1,并且也可以绑定其他任意的 IP 地址。

在命名空间 ns1 内部 ping 192.168.1.1 时,其实是在尝试 ping ns1 内部的 veth1 设备。由于 veth1 设备和本地回环接口在同一个网络命名空间内,因此,这个 ICMP ECHO 请求(ping 请求)实际上是在本地回环接口上进行的。

所以,如果本地回环接口处于关闭(down)状态,那么这个 ping 请求就会失败。当执行 ip netns exec ns1 ip link set lo up 命令后,实际上启动了网络命名空间 ns1 内的本地回环接口,因此,可以在 ns1 内部 ping 192.168.1.1

总的来说,这是因为在 Linux 系统中,本地回环接口(lo)是处理本地(即同一网络命名空间内部)的IP通讯的关键设备,所以在网络命名空间内测试本地IP连通性之前,需要保证本地回环接口是启动(up)状态