我们接着盗图,如下:

两个容器ping 两个容器中间连通_docker

在这张图上,可以看到,如果两个容器使用同一个bridge,那么两个容器之间是互相能通的

两个容器ping 两个容器中间连通_docker_02

两个容器ping 两个容器中间连通_DNS_03

两个容器ping 两个容器中间连通_docker_04

可以看到两个容器在同一个bridge下是可以互相ping通的

 

两个容器ping 两个容器中间连通_操作系统_05

当两个容器在不同的bridge的时候,容器之间是不能ping通的,(但是不同bridge的容器为什么能ping通不同bridge的网关呢?)和拓扑图是一样的

 

 

 

如何让两个不同的网段之间能够ping通呢?

1.增加路由

如果host上对每个网络都有一个路由,同时操作系统上打开了ip forwarding,host就成了一个路由,挂在不同的网桥上的网络就能够互相ping通

我们可以看一下host上是否满足这个条件

ip r查看路由表

两个容器ping 两个容器中间连通_docker_06

我们可以看到这些网段的路由表都定义好了,那我们再看一下ip forwarding

/proc/sys/net/ipv4/ip_forward,这里面本来是0,我们将他改成1

两个容器ping 两个容器中间连通_docker_07

两个容器ping 两个容器中间连通_两个容器ping_08

我们开启路由转发后不同bridge之间是否能通信呢?

两个容器ping 两个容器中间连通_运维_09

可以看到ping向其他bridge的ip还是不能通,但是ping到网关是能通的

两个容器ping 两个容器中间连通_两个容器ping_10

2.为什么已经开启了路由转发,还是不能互相通信啊?是不是因为防火墙?但是我的firewalld 和selinux都已经全部关闭了啊

但是linux内核还有个iptables,我们看一下iptables规则

两个容器ping 两个容器中间连通_docker_11

可以看到bridge被iptables给DROP掉了,从命名规则 DOCKER-ISOLATION可知:docker 在设计上就是要隔离不同的network

那是不是我们更改一下iptables的规则就可以实现不同bridge容器间的通信呢,答案是肯定的(由于本人iptables特别不好,所以这里就不讨论了)

 3.我们还可以通过docker另外的增加网卡的办法来解决:

使用docker network connect给容器增加一块新的网卡

两个容器ping 两个容器中间连通_DNS_12

 

 可以看到我们通过docker network connect 这个命令给容器添加网卡eth1,并让这个网卡使用另外的bridge,现在不同bridge之间的容器建可以进行通信

 

 

 

容器间的通信方式其实有三种:

1.IP通信:

上面我们讨论的相同bridge的容器间的通信与不同的bridge之间的通过docker network connect增加网卡使容器间通信,都属于基于IP方式的通信

2.docker dns server:

我们在部署应用之前可能无法确定IP,部署之后在指定IP可能比较麻烦,docker 自带的DNS 服务可以解决这个问题

docker 从1.10版本开始,docker daemon实现了一个内嵌的DNS server,使容器可以直接通过容器名进行通信,

方法也很简单,只要在运行容器的时候通过--name指定容器名,就可以了

两个容器ping 两个容器中间连通_DNS_13

 

两个容器ping 两个容器中间连通_docker_14

 运行了两个容器名字为name1和name2,为什么我用name2去pingname1时,不能ping通呢?

因为,这个DNS server通信的方式只适用于user-defined的网络

两个容器ping 两个容器中间连通_docker_15

 

两个容器ping 两个容器中间连通_DNS_16

试验结果为:确实是需要user-defined的网络,才能实现dns server的通信方式

两个容器ping 两个容器中间连通_运维_17

但是不同bridge之间的容器通过DNS的通信方式还是不能实现

 

 

3.joined通信方式

joined容器非常特别,它可以使两个或两个以上的容器共享一个网络栈,共享网卡和配置信息,joined容器可以使容器之间可以通过127.0.0.1直接进行通信

两个容器ping 两个容器中间连通_DNS_18

 

两个容器ping 两个容器中间连通_运维_19

 通过--nemwork=container:name5的方式将一个新建的容器加入另外一个容器后,两个容器间就有了相同的mac和ip,他们共享了相同的网络栈

两个容器ping 两个容器中间连通_运维_20

name5可以直接通过127.0.0.1直接访问新建httpd容器的http服务

joined通信方式非常适合一下场景:

1.不同容器的程序希望通过loopback高效快速通信,比如web server与app server

2.希望监控其他容器的流量,比如运行在独立的容器中的网络监控程序