前面咱們已經解決了容器間通訊的問題,接下來討論容器如何與外部世界通訊。這裏涉及兩個方向:docker
容器訪問外部世界網絡
外部世界訪問容器tcp
在咱們當前的實驗環境下,docker host 是能夠訪問外網的。spa
咱們看一下容器是否也能訪問外網呢?code
可見,容器默認就能訪問外網。ip
請注意:這裏外網指的是容器網絡之外的網絡環境,並不是特指 internet。路由
現象很簡單,但更重要的:咱們應該理解現象下的本質。table
在上面的例子中,busybox 位於 docker0
這個私有 bridge 網絡中(172.17.0.0/16),當 busybox 從容器向外 ping 時,數據包是怎樣到達 bing.com 的呢?容器
這裏的關鍵就是 NAT。咱們查看一下 docker host 上的 iptables 規則:監控
在 NAT 表中,有這麼一條規則:
-A POSTROUTING -s 172.17.0.0/16 ! -o docker0 -j MASQUERADE
其含義是:若是網橋 docker0
收到來自 172.17.0.0/16 網段的外出包,把它交給 MASQUERADE 處理。而 MASQUERADE 的處理方式是將包的源地址替換成 host 的地址發送出去,即作了一次網絡地址轉換(NAT)。
下面咱們經過 tcpdump 查看地址是如何轉換的。先查看 docker host 的路由表:
默認路由經過 enp0s3 發出去,因此咱們要同時監控 enp0s3 和 docker0 上的 icmp(ping)數據包。
當 busybox ping bing.com 時,tcpdump 輸出以下:
docker0 收到 busybox 的 ping 包,源地址爲容器 IP 172.17.0.2,這沒問題,交給 MASQUERADE 處理。這時,在 enp0s3 上咱們看到了變化:
ping 包的源地址變成了 enp0s3 的 IP 10.0.2.15
這就是 iptable NAT 規則處理的結果,從而保證數據包可以到達外網。下面用一張圖來講明這個過程:
busybox 發送 ping 包:172.17.0.2 > www.bing.com。
docker0 收到包,發現是發送到外網的,交給 NAT 處理。
NAT 將源地址換成 enp0s3 的 IP:10.0.2.15 > www.bing.com。
ping 包從 enp0s3 發送出去,到達 www.bing.com。
經過 NAT,docker 實現了容器對外網的訪問。
下一節咱們討論另外一個方向的流量:外部世界如何訪問容器。