Docker允许通过外部访问容器或容器互联的方式来提供网络服务。
当Docker启动时,会在主机上创建一个 docker0虚拟网桥,实际上是Linux的一个bridge,可以理解为一个软件交换机。它会在挂载到它的网口之间进行转发。
容器之间访问
容器之间相互访问,需要两方面的支持:
1.容器的网络拓扑图是否互联。默认情况下,所有容器都会被连接到docker0网桥上。
2.本地系统的防火墙软件-- iptables是否允许通过。
访问所有端口:
当容器启动的时候,默认会添加一条转发策略到iptables的forward链上。策略为通过(accept)还是禁止(drop)取决于配置--icc=true(缺省值)还是 -icc=false。
可见默认情况下,不同容器之间是允许网络互通的。如果为了安全考虑,可以在/etc/default/docker 文件配置中 docker opts=--icc=false来禁止。
访问指定端口
在通过-icc=false关闭网络访问后,还可以通过--link=container_name:alias 选项来访问容器的开放端口。
docker提供了 --link:容器名:别名来指定要和哪个容器通信。docker会在iptable中为两个容器分别添加一条accept,允许访问开放的端口(取决于Docfile中的expose指令)。
映射容器端口到宿主机的实现
容器访问外部网络
在Linux系统中,检查转发是否打开。
执行: sysctl net.ipv4.ip_forward
输出: net.ipv4.ip_forward = 1 ,如果为0,说明没有开启转发,需要手动打开。执行 sysctl -w net.ipv4.ip_forward=1。如果在启动docker服务的时候设定 --ip-forward=true,Docker就会自动设定系统的ip_forward参数为1。
在宿主机执行 docker inspect kibana,查看运行容器的ip
然后在宿主机ping容器的IP ping 172.18.0.1,发现在宿主机可以ping通容器。反之在容器内也可以ping通宿主机。(容器内安装ping工具包 apt-get install iputils-ping)。 由此可以,默认情况下主机和容器是互通的。 容器的ip在启动的时候分配,不过在容器重新启动之后,ip会发生变化。
在相同主机直接的容器也是可以相互通信的。
外部访问容器实现
容器允许外部访问,可以在docker run的时候通过 -p 或者-P参数来启用。不管用那种方式,其实也是在本地的iptables的nat表中添加相应的规则.
使用 -p 6379:6379 时: iptables -t nat -nL
Chain DOCKER (2 references)
target prot opt source destination
RETURN all -- 0.0.0.0/0 0.0.0.0/0
DNAT tcp -- 0.0.0.0/0 0.0.0.0/0 tcp dpt:6379 to:172.18.0.2:6379
这里规则映射了0.0.0.0,意味着将接受主机来自所有接口的流量。用户可以通过 -p IP:host_port:container_port或者 -ip IP::port 来制定允许访问容器的主机上的IP,接口等。