Docker动手教程5.2:容器单机网络2

内容摘要

容器网络连接特性

Docker DNS

容器共享网络栈

在本节开始前,请使用快照恢复容器环境,回到最初的环境。

在上一节初步讲解了容器的三种自带网络,以及自定义bridge网络,在容器中使用最多的是bridge网络。

下面我们进一步学习bridge网络。

容器网络连接特性

测试前,先查询容器网络相关信息,命令为:

brctl show
ifconfig
Docker动手教程5.2:容器单机网络2

Docker动手教程5.2:容器单机网络2

请注意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
Docker动手教程5.2:容器单机网络2

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动手教程5.2:容器单机网络2

容器运行成功后,查看两个容器的网络信息:

使用 docker inspect network net1:

Docker动手教程5.2:容器单机网络2

可以看到,两个容器的IP地址,以及网关。

下面分别进入两个容器,使用Ping判断是否网络相通:

Docker动手教程5.2:容器单机网络2

可以发现,两个容器是可以互相ping通的。

两个容器处于同一个网段,所以能够互相ping通。

下面测试处于不同网段的容器,能否ping通。

在net2中创建tomcat:jdk8容器:

docker run -d -p 8080 --name tomcat1_net2 --network=net2 tomcat:jdk8
Docker动手教程5.2:容器单机网络2

查看容器网络信息:

Docker动手教程5.2:容器单机网络2

进入tomcat1_net1容器,ping tomat1_net2容器IP地址:172.19.0.2:

Docker动手教程5.2:容器单机网络2

无法ping通,可见处于不同网段的容器无法联通的。

问题:那么docker如何做到不同网段是不同联通的呢?

查看网桥信息:

Docker动手教程5.2:容器单机网络2

可以看到除了 docker0 以外,还有其他两个网桥。

查看iptables信息,使用命令: iptables-save

Docker动手教程5.2:容器单机网络2

可以看到上述3个网桥的配置信息:

DOCKER-ISOLATION 表示网络隔离,后面的配置将3个网桥全部隔离开。

DROP 表示取消, -i 表示输入, -o 表示输出。

这就是为什么处于两个不同网段的容器无法ping通的原因。

问题:那么如何才能让两个处于不同网段的容器网络相通呢?

方法是为其中一容器增加一张网卡,使其IP地址位于另一个容器的网段中, 命令如下:

docker network connect net2 cffaf8166793
Docker动手教程5.2:容器单机网络2

为容器tomcat1_net1增加网卡,该网卡使用net2网络,进入容器中,可以看到新增网卡IP地址,和net2处于同一网段。

在该容器中ping tomcat1_net2容器IP地址:

Docker动手教程5.2:容器单机网络2

可以ping通,说明网络可以相通。

Docker DNS

下面我们做一个测试:

在容器tomcat1_net1中, 使用 ping tomcat2_net1 命令测试下能否联通:

Docker动手教程5.2:容器单机网络2

可以看到,能够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
Docker动手教程5.2:容器单机网络2

进入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
Docker动手教程5.2:容器单机网络2

查看tomcat1_net1容器的网络信息:

Docker动手教程5.2:容器单机网络2

可以看到两个容器具有同样的网络设备。

在busybox容器中可以使用127.0.0.1访问tomcat容器:

Docker动手教程5.2:容器单机网络2

可以看到,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}')


分享到:


相關文章: