本文介绍如何在docker默认bridge网络绑定容器端口。这个bridge网络名称为bridge,是安装docker时自动创建的。
默认下docker容器能连接到外部网络,但外部网络无法连接到容器。由于docker服务器启动时在主机创建的iptables伪装(masquerading)规则,所以容器的每个出站连接显示的来源IP地址是主机自己的IP地址:
- $ sudo iptables -t nat -L -n
- …
- Chain POSTROUTING (policy ACCEPT)
- target prot opt source destination
- MASQUERADE all — 172.17.0.0/16 0.0.0.0/0
- …
docker server创建的masquerade规则使得容器能够连接外部网络的IP地址。
如果你想让容器接收来自外部网络的连接,需要在调用docker run时提供一些指定的参数。有两个方法。
第一个,你可以在docker run命令中提供-P或–publish-all=true|false,这个命令会识别在镜像Dockerfile中的EXPOSE的端口或命令行中的–expose 端口并映射到主机的临时端口范围内的随机端口。可以使用docker port命令来查看创建的端口映射。临时端口范围是在/proc/sys/net/ipv4/ip_local_port_range内核参数配置,一般是32768到61000。
可以使用-p SPEC or –publish=SPEC参数来指定映射的端口。它允许你指定docker server的端口 – 可以是任意的端口而不是在临时端口范围的一个随机端口。
你可以通过iptable的NAT表来查看绑定了哪些端口。
- # What your NAT rules might look like when Docker
- # is finished setting up a -P forward:
- $ iptables -t nat -L -n
- …
- Chain DOCKER (2 references)
- target prot opt source destination
- DNAT tcp — 0.0.0.0/0 0.0.0.0/0 tcp dpt:49153 to:172.17.0.2:80
- # What your NAT rules might look like when Docker
- # is finished setting up a -p 80:80 forward:
- Chain DOCKER (2 references)
- target prot opt source destination
- DNAT tcp — 0.0.0.0/0 0.0.0.0/0 tcp dpt:80 to:172.17.0.2:80
–userland-proxy默认是true,为内部容器间和外部到容器的通信提供了一个用户级的实现。当关闭时,docker使用一个MASQUERADE iptable规则和net.ipv4.route_localnet内核参数允许主机使用常见的loopback地址来连接本地容器暴露的端口。这种方法完全可以代替使用docker-proxy进程对流量转发,性能没有使用iptables转发好。推荐设置–userland-proxy=false。不过由于此参数设置为false时有可能存在一些问题,所以目前还继续保留docker-pxoy并设置此参数为true。