内容摘要
容器网络连接特性
Docker DNS
容器共享网络栈
在本节开始前,请使用快照恢复容器环境,回到最初的环境。
在上一节初步讲解了容器的三种自带网络,以及自定义bridge网络,在容器中使用最多的是bridge网络。
下面我们进一步学习bridge网络。
容器网络连接特性
测试前,先查询容器网络相关信息,命令为:
brctl show ifconfig
请注意Subnet和Gateway信息。
创建两个自定义bridge网络,名为:net1,net2
docker network create --driver bridge --subnet 172.18.0.0/16 --gateway 172.18.0.1 net1 docker network create --driver bridge --subnet 172.19.0.0/16 --gateway 172.19.0.1 net2
net1和net2处于不同网段,网关也不一样。
在net1中创建两个tomcat:jdk8容器,名称分别为:tomcat1_net1, tomcat2_net1:
docker run -d -p 8080 --name tomcat1_net1 --network=net1 tomcat:jdk8 docker run -d -p 8080 --name tomcat2_net1 --network=net1 tomcat:jdk8
容器运行成功后,查看两个容器的网络信息:
使用 docker inspect network net1:
可以看到,两个容器的IP地址,以及网关。
下面分别进入两个容器,使用Ping判断是否网络相通:
可以发现,两个容器是可以互相ping通的。
两个容器处于同一个网段,所以能够互相ping通。
下面测试处于不同网段的容器,能否ping通。
在net2中创建tomcat:jdk8容器:
docker run -d -p 8080 --name tomcat1_net2 --network=net2 tomcat:jdk8
查看容器网络信息:
进入tomcat1_net1容器,ping tomat1_net2容器IP地址:172.19.0.2:
无法ping通,可见处于不同网段的容器无法联通的。
问题:那么docker如何做到不同网段是不同联通的呢?
查看网桥信息:
可以看到除了 docker0 以外,还有其他两个网桥。
查看iptables信息,使用命令: iptables-save
可以看到上述3个网桥的配置信息:
DOCKER-ISOLATION 表示网络隔离,后面的配置将3个网桥全部隔离开。
DROP 表示取消, -i 表示输入, -o 表示输出。
这就是为什么处于两个不同网段的容器无法ping通的原因。
问题:那么如何才能让两个处于不同网段的容器网络相通呢?
方法是为其中一容器增加一张网卡,使其IP地址位于另一个容器的网段中, 命令如下:
docker network connect net2 cffaf8166793
为容器tomcat1_net1增加网卡,该网卡使用net2网络,进入容器中,可以看到新增网卡IP地址,和net2处于同一网段。
在该容器中ping tomcat1_net2容器IP地址:
可以ping通,说明网络可以相通。
Docker DNS
下面我们做一个测试:
在容器tomcat1_net1中, 使用 ping tomcat2_net1 命令测试下能否联通:
可以看到,能够ping通,其原因在于docker 自带一个DNS服务器,能够解析容器名称。
但是,请注意上面能够ping通的条件是:不能使用docker默认初始化的容器网络bridge,只能使用自己创建的bridge网络。
测试如下:
运行两个tomcat容器,使用bridge网络:
docker run -d -p 8080 --name tomcat1_bridge --network=bridge tomcat:jdk8 docker run -d -p 8080 --name tomcat2_bridge --network=bridge tomcat:jdk8
进入tomcat1_bridge容器,ping tomcat2_bridge容器,结果是ping不通,报错为: tomcat2_bridge: Name of service not known,识别不了该名称,说明DNS没有支持。
容器共享网络栈
两个容器可以拥有同样的IP地址,具有相同的网络栈。 测试如下:
创建busybox容器, 使用tomcat1_net1容器的网络栈,命令如下:
docker run -it --network=container:tomcat1_net1 busybox
查看tomcat1_net1容器的网络信息:
可以看到两个容器具有同样的网络设备。
在busybox容器中可以使用127.0.0.1访问tomcat容器:
可以看到,busybox可以像访问本机一样访问tomcat容器。
这种通信方式性能非常好, 在一些特殊的场景下很适用。
两个容器共享数据时就可以使用这种方式, 比如两个容器A和B,B容器需要获取A容器的日志,那么就可以使用这种网络。
再比如web程序,可以将静态网页单独放在一个容器,同时该容器具有和server同样的网络栈,server就可以直接使用网页数据。
容器之间的网络联接就讲到这里。
实验
处于同一网段的容器是否能够联通
处于不同网段的容器是否能够相同
测试DockerDNS
创建共享网络栈的容器,并测试容器之前是否相通
常用命令
sudo docker rm -f $(sudo docker ps -a | awk 'NR == 1 {next} {print $1}')
sudo docker rmi -f $(sudo docker images | awk 'NR == 1 {next} {print $3}')