1. 程式人生 > >容器如何訪問外部世界?- 每天5分鐘玩轉 Docker 容器技術(36)

容器如何訪問外部世界?- 每天5分鐘玩轉 Docker 容器技術(36)

docker 教程 容器

前面我們已經解決了容器間通信的問題,接下來討論容器如何與外部世界通信。這裏涉及兩個方向:

  1. 容器訪問外部世界

  2. 外部世界訪問容器

容器訪問外部世界

在我們當前的實驗環境下,docker host 是可以訪問外網的。

技術分享

我們看一下容器是否也能訪問外網呢?

技術分享

可見,容器默認就能訪問外網

請註意:這裏外網指的是容器網絡以外的網絡環境,並非特指 internet。

現象很簡單,但更重要的:我們應該理解現象下的本質。

在上面的例子中,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 規則處理的結果,從而保證數據包能夠到達外網。下面用一張圖來說明這個過程:

技術分享

  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 實現了容器對外網的訪問。

下一節我們討論另一個方向的流量:外部世界如何訪問容器。

技術分享

容器如何訪問外部世界?- 每天5分鐘玩轉 Docker 容器技術(36)