这篇文章讲述了 Docker 如何使用网络命名空间来隔离资源。
- 创建两个网络命名空间: ns1 和 ns2 。
添加两个新的 nanetwork 命名空间:
# ip netns add ns1 # ip netns add ns2
上述命令通过将标志传递给 clone() 系统调用 CLONE_NEWNT 来创建网络空间。
检查新创建的 ns:
# ip netns list ns2 ns1
当 IP 工具创建网络命名空间时,它会在 /var/run/netns/ 下为它创建一个绑定挂载,如下所示:
# ls /var/run/netns/ ns1 ns2
列出新创建的命名空间内可见的接口。
可以看到第一次创建后,lo环回设备down了,路由表为空:
# ip netns exec ns1 ip a 1: lo: [LOOPBACK] mtu 65536 qdisc noop state DOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
# ip netns exec ns2 ip a 1: lo: [LOOPBACK] mtu 65536 qdisc noop state DOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
# ip netns exec ns2 ip route #
- 创建 mydocker0 网桥:
在默认网络命名空间下创建 mydocker0 Linux 网桥:
# brctl addbr mydocker0
# brctl show bridge name bridge id STP enabled interfaces ... mydocker0 8000.000000000000 no ...
# ip a add 172.16.1.254/16 dev mydocker0 # ip link set dev mydocker0 up
# route -n Kernel IP routing table Destination Gateway Genmask Flags Metric Ref Use Iface 0.0.0.0 10.182.64.1 0.0.0.0 UG 100 0 0 enp0s3 10.182.64.0 0.0.0.0 255.255.248.0 U 100 0 0 enp0s3 172.16.0.0 0.0.0.0 255.255.0.0 U 0 0 0 mydocker0 ...
- 创建 VETH 以连接命名空间 ns1 上的网络命名空间:
设置一对虚拟以太网设备veth1&veth1p 连接默认命名空间和命名空间ns1:
# ip link add veth1 type veth peer name veth1p
# ip -d link show |grep veth1 6149: veth1p@veth1: [BROADCAST,MULTICAST,M-DOWN] mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 6150: veth1@veth1p: [BROADCAST,MULTICAST,M-DOWN] mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000
将 veth1 分配给 mydocker0,将 veth1 分配给命名空间 ns1:
# brctl addif mydocker0 veth1 # ip link set veth1 up
# brctl show bridge name bridge id STP enabled interfaces docker0 8000.3a6bde86d9e8 no br0 veth890eaea mydocker0 8000.6efa891a7162 no veth1 >>>>>>>> ...
# ip link set veth1p netns ns1 # ip netns exec ns1 ip a 1: lo: [LOOPBACK] mtu 65536 qdisc noop state DOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 6149: veth1p@if6150: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 2a:3b:ea:e3:63:dd brd ff:ff:ff:ff:ff:ff link-netnsid 0
将 veth1p 的名称更改为 eth0:
# ip netns exec ns1 ip link set veth1p name eth0 # ip netns exec ns1 ip a 1: lo: [LOOPBACK] mtu 65536 qdisc noop state DOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 6149: eth0@if6150: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 2a:3b:ea:e3:63:dd brd ff:ff:ff:ff:ff:ff link-netnsid 0
将 IP 地址分配给命名空间 ns1 中的 eth0:
# ip netns exec ns1 ip link set eth0 up # ip netns exec ns1 ip a add 172.16.1.1/16 dev eth0 # ip netns exec ns1 ip route add default via 172.16.1.254 # ip netns exec ns1 ip route default via 172.16.1.254 dev eth0 172.16.0.0/16 dev eth0 proto kernel scope link src 172.16.1.1
- 在命名空间 ns2 上执行相同的步骤:
# ip link add veth2 type veth peer name veth2p # brctl addif mydocker0 veth2 # ip link set veth2 up # ip link set veth2p netns ns2 # ip netns exec ns2 ip link set veth2p name eth0 # ip netns exec ns2 ip link set eth0 up # ip netns exec ns2 ip addr add 172.16.1.2/16 dev eth0 # ip netns exec ns2 ip route add default via 172.16.1.254
- 测试两个命名空间之间的网络连通性:
# ip netns exec ns1 ping -c 2 172.16.1.2 PING 172.16.1.2 (172.16.1.2) 56(84) bytes of data. 64 bytes from 172.16.1.2: icmp_seq=1 ttl=64 time=0.457 ms 64 bytes from 172.16.1.2: icmp_seq=2 ttl=64 time=0.049 ms --- 172.16.1.2 ping statistics -- 2 packets transmitted, 2 received, 0% packet loss, time 1057ms rtt min/avg/max/mdev = 0.049/0.253/0.457/0.204 ms
# ip netns exec ns2 ping -c 2 172.16.1.1 PING 172.16.1.1 (172.16.1.1) 56(84) bytes of data. 64 bytes from 172.16.1.1: icmp_seq=1 ttl=64 time=0.058 ms 64 bytes from 172.16.1.1: icmp_seq=2 ttl=64 time=0.045 ms --- 172.16.1.1 ping statistics -- 2 packets transmitted, 2 received, 0% packet loss, time 1055ms rtt min/avg/max/mdev = 0.045/0.051/0.058/0.009 ms
日期:2020-09-17 00:16:26 来源:oir作者:oir