以下操作仅仅为了说明容器间的互访原理
一、同宿主机容器间通信
1、在同一网桥
创建网桥my_net1,网段172.16.0.0/16
# docker network create --driver bridge --subnet 172.16.0.0/16 --gateway 172.16.0.1 my_net01 启动容器1 # docker run -it --rm --network=my_net01 busybox / # ifconfig eth0 Link encap:Ethernet HWaddr 02:42:AC:10:00:02 inet addr:172.16.0.2 Bcast:172.16.255.255 Mask:255.255.0.0 …… 启动容器2 # docker run -it --rm --network=my_net01 busybox / # ifconfig eth0 Link encap:Ethernet HWaddr 02:42:AC:10:00:03 inet addr:172.16.0.3 Bcast:172.16.255.255 Mask:255.255.0.0 …… 宿主机,可以看到网桥上有两张网卡 # brctl show bridge name bridge id STP enabled interfaces br-443f050b6ca3 8000.0242dee2c26a no vethed8ac3b vethf1258ae 测试连通性 / # ping 172.16.0.3 PING 172.16.0.3 (172.16.0.3): 56 data bytes 64 bytes from 172.16.0.3: seq=0 ttl=64 time=0.904 ms 64 bytes from 172.16.0.3: seq=1 ttl=64 time=0.177 ms
在同一个网桥上的两个容器,分配到的IP地址属于同一网段,是直接就可以互访的
2、在不同网桥
创建网桥my_net2,网段172.18.0.0/16
# docker network create --driver bridge --subnet 172.18.0.0/16 --gateway 172.18.0.1 my_net02
创建容器3 # docker run -it --rm --network=my_net02 busybox / # ifconfig eth0 Link encap:Ethernet HWaddr 02:42:AC:12:00:02 inet addr:172.18.0.2 Bcast:172.18.255.255 Mask:255.255.0.0 …… 宿主机查看网桥信息 # brctl show bridge name bridge id STP enabled interfaces br-443f050b6ca3 8000.0242dee2c26a no vethed8ac3b vethf1258ae br-d32523fc2826 8000.0242594398dd no vetheec7c7a docker0 8000.024244c8bf47 no 开启linux内核的数据转发 # sysctl net.ipv4.ip_forward=1 可以查看到iptable,可以看到默认不同网桥的容器是不允许互相访问的 # iptables -S …… -A FORWARD -j DOCKER-ISOLATION-STAGE-1 …… -A DOCKER-ISOLATION-STAGE-1 -i br-d32523fc2826 ! -o br-d32523fc2826 -j DOCKER-ISOLATION-STAGE-2 -A DOCKER-ISOLATION-STAGE-1 -i br-443f050b6ca3 ! -o br-443f050b6ca3 -j DOCKER-ISOLATION-STAGE-2 …… -A DOCKER-ISOLATION-STAGE-2 -o br-d32523fc2826 -j DROP -A DOCKER-ISOLATION-STAGE-2 -o br-443f050b6ca3 -j DROP …… 我们需要把以下两条规则删除 # iptables -D DOCKER-ISOLATION-STAGE-2 -o br-d32523fc2826 -j DROP # iptables -D DOCKER-ISOLATION-STAGE-2 -o br-443f050b6ca3 -j DROP 容器已经实现互通了 / # ping 172.16.0.2 PING 172.16.0.2 (172.16.0.2): 56 data bytes 64 bytes from 172.16.0.2: seq=497 ttl=63 time=0.615 ms 64 bytes from 172.16.0.2: seq=498 ttl=63 time=0.193 ms 64 bytes from 172.16.0.2: seq=499 ttl=63 time=0.194 ms
数据流程图如下:
二、处于不同宿主机间的容器通信
要实现不同宿主机间容器的通信,需满足如下条件
- 多台宿主机必须要处于同一个局域网,因为需要配置静态路由到对应的宿主机
- 不同的网桥的IP地址段不能冲突
- 开启ip_forward流量转发
- 关闭iptables的nat和禁止访问的规则
数据流程图如下:
节点10.30.20.87
# docker network create --driver bridge --subnet 172.10.0.0/16 --gateway 172.10.0.1 my_net01 # route add -net 172.11.0.0/16 gw 10.30.20.93 # sysctl net.ipv4.ip_forward=1 # docker run -it --network=my_net01 busybox / # ifconfig eth0 Link encap:Ethernet HWaddr 02:42:AC:0A:00:02 inet addr:172.10.0.2 Bcast:172.10.255.255 Mask:255.255.0.0 ……
节点10.30.20.93
# docker network create --driver bridge --subnet 172.11.0.0/16 --gateway 172.11.0.1 my_net02 # route add -net 172.10.0.0/16 gw 10.30.20.87 # sysctl net.ipv4.ip_forward=1 # docker run -it --network=my_net02 busybox / # ifconfig eth0 Link encap:Ethernet HWaddr 02:42:AC:0B:00:02 inet addr:172.11.0.2 Bcast:172.11.255.255 Mask:255.255.0.0 ……
删除nat和配置允许转发的策略
节点10.30.20.87
# iptables -S -t nat …… -A POSTROUTING -s 172.10.0.0/16 ! -o br-a3d2032ddd68 -j MASQUERADE …… # iptables -t nat -D POSTROUTING -s 172.10.0.0/16 ! -o br-a3d2032ddd68 -j MASQUERADE # iptables -A FORWARD -o br-a3d2032ddd68 -j ACCEPT
节点10.30.20.93
# iptables -S -t nat …… -A POSTROUTING -s 172.11.0.0/16 ! -o br-568e8e2a15b4 -j MASQUERADE …… # iptables -t nat -D POSTROUTING -s 172.11.0.0/16 ! -o br-568e8e2a15b4 -j MASQUERADE # iptables -A FORWARD -o br-568e8e2a15b4 -j ACCEPT
测试容器间的互联
/ # ping 172.11.0.2 PING 172.11.0.2 (172.11.0.2): 56 data bytes 64 bytes from 172.11.0.2: seq=0 ttl=62 time=0.883 ms 64 bytes from 172.11.0.2: seq=1 ttl=62 time=0.443 ms 64 bytes from 172.11.0.2: seq=2 ttl=62 time=0.521 ms