容器访问外部世界

  1. root@Wangying:~# ping baidu.com
  2. PING baidu.com (220.181.38.251) 56(84) bytes of data.
  3. 64 bytes from 220.181.38.251 (220.181.38.251): icmp_seq=1 ttl=46 time=42.9 ms
  4. 64 bytes from 220.181.38.251 (220.181.38.251): icmp_seq=2 ttl=46 time=39.0 ms
  5. 64 bytes from 220.181.38.251 (220.181.38.251): icmp_seq=3 ttl=46 time=77.2 ms
  6. ^C
  7. --- baidu.com ping statistics ---
  8. 3 packets transmitted, 3 received, 0% packet loss, time 2093ms
  9. rtt min/avg/max/mdev = 38.953/53.009/77.201/17.180 ms
  10. root@Wangying:~# docker run -it busybox
  11. / # ping baidu.com
  12. PING baidu.com (220.181.38.251): 56 data bytes
  13. 64 bytes from 220.181.38.251: seq=0 ttl=37 time=48.002 ms
  14. 64 bytes from 220.181.38.251: seq=1 ttl=37 time=77.453 ms

可见容器默认能够访问容器网络以外的网络环境。busybox 位于 docker0 这个私有bridge 网络中(172.17.0.0/16),当 busybox 从容器向外 ping 时,数据包是怎样到达 baidu.com 的呢?

如果网桥 docker0 收到来自172.17.0.0/16网段的外出包,把它交给 MASQUERADE 处理。而 MASQUERADE 的处理方式是将包的源地址替换成 host 的地址发送出去,即做了一次网络地址转换(NAT)。
image.png
(1)busybox 发送 ping 包:172.17.0.2 > www.bing.com。

(2)docker0 收到包,发现是发送到外网的,交给 NAT 处理。

(3)NAT 将源地址换成 enp0s3 的 IP :10.0.2.15 > www.bing.com。

(4)ping 包从 enp0s3 发送出去,到达 www.bing.com。通过 NAT, docker 实现了容器对外网的访问。

外部世界访问容器

docker 可将容器对外提供服务的端口映射到 host 的某个端口,外网通过该端口访问容器。容器启动时通过 -p 参数映射端口。
image.png
(1)docker-proxy 监听 host 的32773端口。

(2)当 curl 访问10.0.2.15:32773时,docker-proxy 转发给容器172.17.0.2:80。

(3)httpd 容器响应请求并返回结果。