容器访问外部世界
方法:NAT
当前,docker host 是可以访问外网的
容器呢?
容器也可以访问外网。注意:这里的外网是指容器网络以外的网络环境,并非特指Internet。
busybox位于docker0这个私有的bridge网络中(172.17.0.0/16),当busybox从容器向外ping时,数据包是怎么达到baidu.com的呢?
这里关键就是NAT,我们查看一下docker host上的iptables规则:
在NAT表中有这么一条规则
-A POSTROUTING -s 172.16.17.0/24 ! -o docker0 -j MASQUERADE
其含义是:如果网桥docker0收到来自172.17.0.0/16网段的外出包,把它交给MASQUERADE处理。而MASQUERADE的处理方式是将包的源地址替换成host的地址发送出去,即做了一次网络地址转换(NAT)。
下面通过tcpdump查看地址是如何转换的。先查看docker host路由表:
默认路由是通过wlp58s0 proto dhcp等发出去,我们先同时监控wlp58s0和docker0上的icmp(ping)数据包。
当busybox ping www.baidu.com时,tcpdump输出如下:
docker0收到busybox的ping包,源地址为容器IP172.16.17.12,交给MASQUERADE处理。这时,在wls58s0上我们看到了变化。
ping包的源地址变成了wlp58s0的IP(192.168.10.103)
这就是iptable NAT规则处理结果,可以保证数据包能到达外网。
外部世界访问容器
方法:端口映射
docker可将容器对外提供服务的端口映射到host的某个端口,外网通过该端口访问容器。容器启动时通过-p参数映射端口。
httpd容器的80端口被映射到了host主机的32768端口,这样可以通过:<32768>访问容器的web服务了
除了映射动态端口外,也可在-p中指定映射到host某个特定端口,例如将80端口映射到主机的8088端口:
每映射一个端口,host都会启动一个docker-proxy进程来处理访问容器的流量: