Docker 本身的技术依赖于 Linux 内核虚拟化技术的发展。所以 Docker 对 Linux 内核的特性有很强的依赖。
其中 Docker 使用到的与 Linux 网络有关的技术分别有:网络名称空间、Veth、Iptables、网桥、路由。
为了支持网络协议栈的多个实例,Linux 在网络协议栈中引入了网络名称空间(Network Namespace),这些 独立的协议栈被隔离到不同的命名空间中。处于不同的命名空间的网络协议栈是完全隔离的,彼此之间无法进行 网络通信,就好像两个“平行宇宙”。通过这种对网络资源的隔离,就能在一个宿主机上虚拟多个不同的网络环 境,而 Docker 正是利用这种网络名称空间的特性,实现了不同容器之间的网络隔离。在 Linux 的网络命名空间 内可以有自己独立的 Iptables 来转发、NAT 及 IP 包过滤等功能。
Linux 的网络协议栈是十分复杂的,为了支持独立的协议栈,相关的这些全局变量都必须修改为协议栈私有。 最好的办法就是让这些全局变量成为一个 Net Namespace 变量的成员,然后为了协议栈的函数调用加入一个 Namespace 参数。这就是 Linux 网络名称空间的核心。所以的网络设备都只能属于一个网络名称空间。当然, 通常的物理网络设备只能关联到 root 这个命名空间中。虚拟网络设备则可以被创建并关联到一个给定的命名空 间中,而且可以在这些名称空间之间移动。
[root@master ~]# ip netns add test01 [root@master ~]# ip netns add test02 [root@master ~]# ip netns ls test02 test01
1.2 Veth 设备
引入 Veth 设备对是为了在不同的网络名称空间之间进行通信,利用它可以直接将两个网络名称空间链接起 来。由于要连接的两个网络命名空间,所以 Veth 设备是成对出现的,很像一对以太网卡,并且中间有一根直连 的网线。既然是一对网卡,那么我们将其中一端称为另一端的 peer。在 Veth 设备的一端发送数据时,它会将数 据直接发送到另一端,并触发另一端的接收操作。
![image](https://www.www.zyiz.net/i/l/?n=20&i=blog/2472448/202108/2472448-20210817194426152-1588
684150.png)
[root@master ~]# ip link add veth type veth peer name veth001 [root@master ~]# ip link show 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP mode DEFAULT group default qlen 1000 link/ether 00:0c:29:ab:0f:3a brd ff:ff:ff:ff:ff:ff 3: veth001@veth: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 4e:a2:0c:f2:4d:4a brd ff:ff:ff:ff:ff:ff 4: veth@veth001: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 6e:c4:53:7e:28:f8 brd ff:ff:ff:ff:ff:ff
生成了两个虚拟网卡 veth、veth001设备, 互为对方的 peer。
[root@master ~]# ip link set veth001 netns test01 [root@master ~]# ip link show | grep veth 5: veth3bab2ee@if4: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP mode DEFAULT group default 7: veth@if6: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 ## ##已经查看不到veth001,当我们进入 test01 命名空间之后,就可以查看到 [root@master ~]# ip netns exec test01 ip link 1: lo: <LOOPBACK> mtu 65536 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 3: veth001@if4: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN mode DEFAULT group default qlen 1000 link/ether 4e:a2:0c:f2:4d:4a brd ff:ff:ff:ff:ff:ff link-netnsid 0
#设置IP [root@master ~]# ip netns exec test01 ip addr add 172.16.0.111/20 dev veth001 #启用veth001网卡 [root@master ~]# ip netns exec test01 ip link set dev veth001 up #查看 [root@master ~]# ip netns exec test01 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 6: veth001@if7: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state LOWERLAYERDOWN group default qlen 1000 link/ether 6a:87:71:9d:b9:2b brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.16.0.111/20 scope global veth001 valid_lft forever preferred_lft forever
这个时候双方就通了。
[root@master ~]# ip netns exec test01 ethtool -S veth001 NIC statistics: peer_ifindex: 4 [root@master ~]# ip a | grep 4 [root@master ~]# ip a | grep 4 inet 10.0.0.90/24 brd 10.0.0.255 scope global eth0 inet6 fe80::20c:29ff:feab:f3a/64 scope link 4: veth@if3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN group default qlen 1000 link/ether 6e:c4:53:7e:28:f8 brd ff:ff:ff:ff:ff:ff link-netnsid 0
[root@master ~]# ip addr add 172.16.0.112/20 dev veth [root@master ~]# ip link set dev veth down [root@master ~]# ip link set dev veth up [root@master ~]# ping 172.16.0.111 PING 172.16.0.111 (172.16.0.111) 56(84) bytes of data. 64 bytes from 172.16.0.111: icmp_seq=1 ttl=64 time=0.174 ms 64 bytes from 172.16.0.111: icmp_seq=2 ttl=64 time=0.047 ms 64 bytes from 172.16.0.111: icmp_seq=3 ttl=64 time=0.068 ms 64 bytes from 172.16.0.111: icmp_seq=4 ttl=64 time=0.050 ms ^C --- 172.16.0.111 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 3016ms rtt min/avg/max/mdev = 0.047/0.084/0.174/0.053 ms
主机和网络名称空间互通