[Docker]不同网络的容器之间互相访问

/ docker / 没有评论 / 1434浏览

[Docker]不同网络的容器之间互相访问

按照Docker官方文档Docker and iptables说明,使用iptables进行网络隔离,使得默认情况下不同子网的容器之间是无法互相访问的。如果需要不同子网的容器之间互相访问时怎么办呢?文档给出了两种方法

禁止iptables

最直接的方法是在/etc/docker/daemon.json把iptables设置为false来直接禁用。这样所有的网络都没有隔离,但是这样做可能会破坏容器的网络。

使用DOCKER-USER链

可以通过iptables在DOCKER-USER链上添加规则以达到使用的目的。验证以下如何添加规则。

添加测试环境

创建测试网络

$ docker network create --subnet=172.5.1.0/24 net1
$ docker network create --subnet=172.5.2.0/24 net2

创建容器分别使用两个不同的网络。 创建第一个容器,并安装网络工具

$ docker run -it --net net1 -ip 172.5.1.2 centos:7 bash
> yum install -y net-tools telnet nc

创建第二个容器,并安装网络工具,并测试访问第一个容器

$ docker run -it --net net2 -ip 172.5.2.2 centos:7 bash
> yum install -y net-tools telnet nc
> ping 172.5.1.2

以上操作会一直卡着。下面添加规则。再打开一个可以执行iptables的容器

$ docker run -it --net host --privileged centos:7 bash
> yum install -y net-tools iptables
> ifconfig | grep -E -B2 '172.5.1|172.5.2'
> br-3bed419583c5: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500  inet 172.5.2.1  netmask 255.255.255.0  broadcast 172.5.2.255
> br-787e52a81bb4: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500  inet 172.5.1.1  netmask 255.255.255.0  broadcast 172.5.1.255

通过以上命令可以查看到两个子网对应的网络接口分别是br-3bed419583c5和br-787e52a81bb4,然后通过iptables使得两个网络接口可以互相方法

$ iptables -I DOCKER-USER -i br-3bed419583c5 -o br-787e52a81bb4 -j ACCEPT
$ iptables -I DOCKER-USER -i br-787e52a81bb4 -o br-3bed419583c5 -j ACCEPT

切换到172.5.1.2和172.5.2.2两个容器进行互相访问。 从172.5.1.2访问172.5.2.2

$ ping 172.5.2.2
PING 172.5.2.2 (172.5.2.2) 56(84) bytes of data.
64 bytes from 172.5.2.2: icmp_seq=1 ttl=63 time=0.164 ms
64 bytes from 172.5.2.2: icmp_seq=2 ttl=63 time=0.150 ms

从172.5.2.2访问172.5.1.2

$ ping 172.5.1.2
PING 172.5.1.2 (172.5.1.2) 56(84) bytes of data.
64 bytes from 172.5.1.2: icmp_seq=786 ttl=63 time=0.162 ms
64 bytes from 172.5.1.2: icmp_seq=787 ttl=63 time=0.151 ms

使用telnet和nc等工具测试都可以正常互相访问