本文共 2871 字,大约阅读时间需要 9 分钟。
一个Docker容器实例,无论使用哪个类型的网络驱动器(包括定制的网络插件),从容器内部来说网络都是透明的,即不区分自己是在哪种类型的网络中。而只知道自己的网络信息,如IP, Gateway, iptalbes, DNS等。
默认创建的容器实例,不会对网络外暴露任何端口,只能供同属一个网络中的其他容器实例访问。创建容器时,可以通过-p|--publish暴露指定端口,如-p 8080:80表示将宿主机的8080映射到容器实例的80端口,如-p 80表示将宿主机的一个随机端口(30000以上)映射到容器实例的80端口。
创建容器实例时,默认只能加入到一个网络中。但是创建后,还可以通过docker network connect命令将一个容器实例加入到其他网络中,即一个容器实例可以同时连入到多个网络。这样容器实例就有多个虚拟网卡,分别连接到不同的网络,分别拥有不同的IP。
容器实例的hostname默认即容器的ID,也可以通过--hostname设置其他的容器hostname。当一个容器实例加入到一个新的网络中,还可以通过--alias设置在该网络中的hostname。
1. 同一个Docker宿主机上的同一个网络中的容器实例之间的通信
首先可以明确,在一个Docker宿主机上,默认创建的容器实例都加入到Docker启动即默认创建的bridge网络中,以docker0为网关,所以这些容器实例之间默认是可以直接通信的,是可以ping通的。
而容器实例之间的通信,实际上是由Docker宿主机的Linux操作系统控制的。有2个因素影响:
1) 容器实例是否加入到同一个网络上。
例如,对于未指定--network创建的容器实例,其默认都加入到bridge网络,即都连接到了docker0为网桥的网络。查看容器实例的网络信息即可了解其所属的网络。
docker inspect c1 docker inspect c22) Docker宿主机的iptables中的Chain FORWARD
如果dockerd启动时采用默认参数--iptables=true,--icc=true,则Docker Engine启动后,会在iptables中的Chain FORWARD插入默认ACCEPT的路由规则,如下:
> iptables -L -nChain FORWARD (policy ACCEPT)target prot opt source destination ACCEPT all -- anywhere anywhere
如果dockerd启动时改变了默认参数--iptables=true,--icc=false,则Docker Engine启动后,会在iptables中的Chain FORWARD插入默认DROP的路由规则,如下:
> iptables -L -nChain FORWARD (policy ACCEPT)target prot opt source destination DROP all -- anywhere anywhere
2. 同一个Docker宿主机上的不同网络中的容器实例之间的通信,以及容器实例与Docker宿主机之间的通信
首先必须明确,在一个Docker宿主机上,默认创建的容器实例是可以通过docker0网关访问Docker宿主机的,但是从Docker宿主机是无法访问容器实例的。所以要求容器实例通过-p|--publish参数开放端口,从Docker宿主机才能够访问容器实例。
这实际上也是由Docker宿主机的Linux操作系统控制的。有2个因素约束:
1) Docker宿主机是否转发容器实例的IP包(--network=host的容器实例不受此因素影响)
这是由dockerd的启动参数--ip-forward决定的。默认--ip-forward=true,即net.ipv4.ip_forward=1,这时Docker宿主机支持转发容器实例的IP包。
当然,Docker宿主机是否支持转发容器实例的IP包,最终受到Linux系统的配置的影响,如果Linux系统设置了--ip-forward=true,则忽略dockerd的启动参数。查看及设置的Linux命令如下:
sysctl net.ipv4.conf.all.forwarding sysctl net.ipv4.conf.all.forwarding=12) 宿主机的iptables能够允许与外部的连接
Docker启动后,默认任何外部source IP都被允许转发,从而能够从该source IP连接到宿主机上的任何Docker容器实例。
首先查看dockerd的启动参数,确保--iptables=true(默认即为true)。
其次查看iptables的Chain FORWARD是否有ACCEPT路由规则,如下:
> iptables -L -nChain FORWARD (policy ACCEPT)target prot opt source destination DOCKER all -- anywhere anywhere DOCKER-ISOLATION all -- anywhere anywhere ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
3. 不同Docker宿主机上的容器实例之间的通信
在宿主机的iptables中,默认DROP其他宿主机的IP包,即默认跨宿主机的容器实例之间无法通信。要使得两个Docker宿主机上的容器实例之间能够通信,需要在每个Docker宿主机上为FORWARD chain设置默认ACCEPT如下:
iptables -P FORWARD ACCEPT
参考链接:
https://docs.docker.com/config/containers/container-networking/
https://docs.docker.com/v17.09/engine/userguide/networking/ https://docs.docker.com/v17.09/engine/userguide/networking/default_network/container-communication/转载地址:http://qqlai.baihongyu.com/