〖Docker 指南⑥〗快速入門 Docker 的五種網路模式

語言: CN / TW / HK

一、Docker 網路實現的原理

Docker 使用 Linux bridge 技術,當 Docker server 啟動時,會在主機上建立一個名為 docker0 的虛擬網橋,此主機上啟動的 Docker 容器會連線到這個虛擬網橋上。虛擬網橋的工作方式和物理交換機類似,這樣主機上的所有容器就通過交換機連在了一個二層網路中。

接下來就要為容器分配 IP 了,Docker 會從 RFC1918 所定義的私有 IP 網段中,選擇一個和宿主機不同的 IP 地址(Container-IP)和子網(每個容器的預設閘道器)分配給 docker0,連線到 docker0 的容器就從這個子網中選擇一個未佔用的 IP 使用。

如一般 Docker 會使用 172.17.0.0/16 這個網段,並將 172.17.0.1/16 分配給 docker0 網橋(在主機上使用 ifconfig 命令是可以看到 docker0 的,可以認為它是網橋的管理介面,在宿主機上作為一塊虛擬網絡卡使用)。

因為在同一宿主機內的容器都接入同一個網橋,這樣容器之間就能夠通過容器的 Container-IP 直接通訊。Docker 網橋是宿主機虛擬出來的,並不是真實存在的網路裝置,外部網路時無法定址到的,這也意味著外部網路無法直接通過 Container-IP 訪問到容器。

如果容器希望外部訪問能夠訪問到,可以通過對映容器埠到宿主機(埠對映),即 docker run 建立容器的時候通過-p 或-P 引數來啟用,訪問容器的時候就通過[宿主機 IP]:[容器埠]訪問容器。

隨機對映埠(從 32768 開始) docker run -d --name test1 -P alpine

指定對映埠 docker run -d --name test2 -p 88:80 alpine

看下面的截圖,我們發現這個容器帶來的網絡卡都是一對一對的,這就是 evth-pair( virtual Ethernet pair )技術,就是一對的虛擬裝置介面,它們都是成對出現的,一段連線著協議,一段彼此相連。正因為有這個特性,evth-pair 充當一個橋樑,來連線各種虛擬網路裝置。

在這裡插入圖片描述

二、Docker 的網路模式

  1. 預設網路當你安裝 Docker 時,它會自動建立三個網路 bridge (建立容器預設連線到此網路)、none、host。你可以使用以下 docker network ls 或者 docker network list 命令列出這些網路

  2. 使用 docker run 建立 docker 容器時,可以用 --net --network 選項指定容器的網路模式host 模式:使用 --net=host 指定none 模式:使用 --net=none 指定container 模式:使用 --net=container:${NAME/ID} 指定bridge 模式:使用 --net=bridge 指定,預設設定,可省略

2.1 Host 模式

host 模式:使用 --net=host 指定

相當於 VMware 中的橋接模式,與宿主機在同一個網路中,但是沒有獨立 IP 地址,直接使用宿主機的 IP 地址與外界進行通訊,不再需要額外進行轉換。

docker 啟動時指定-network=host 或-net=host,此時通過-p 對映埠不會氣到任何作用,埠號會以主機埠號為主,重複時則遞增。

Docker 使用了 Linux 的 Namespace 技術來進行資源隔離,如 PID Namespace 隔離程序,Mount Namespace 隔離檔案系統,Network Namespace 隔離網路等。一個 Network Namespace 提供了一份獨立的網路環境,包括網絡卡,路由,iptable 規則等都與其他 Network Namespace 隔離。一個 Docker 容器一般會分配一個獨立的 Network Namespace。

但是如果啟動容器的時候使用 host 模式,那麼這個容器將不會獲得一個獨立的 Network Namespace ,而是和宿主機共用一個 Network Namespace 。容器將不會虛擬出自己的網絡卡,配置自己的 IP 等,而是使用宿主機的 IP 和埠範圍。此時容器不再擁有隔離的、獨立的網路棧,不擁有埠資源。

容器的網路使用的是宿主機的網路,但是,容器的其他方面,如檔案系統、程序列表等還是和宿主機隔離的。

2.2 none 模式

使用 none 模式,Docker 容器擁有自己的 Network Namespace ,但是,並不為 Docker 容器進行任何網路配置。

也就是說,這個 Docker 容器沒有網絡卡、IP、路由等資訊。這種網路模式下容器只有 lo 迴環網路,沒有其他網絡卡。這種型別的網路沒有辦法聯網,封閉的網路能很好的保證容器的安全性。

在這裡插入圖片描述

2.3 container 模式

這個模式指定新建立的容器和已經存在的一個容器共享一個 Network Namespace (網路名稱空間),而不是和宿主機共享。

新建立的容器不會建立自己的網絡卡,配置自己的 IP,而是和一個指定的容器共享 IP、埠範圍等。同樣,兩個容器除了網路方面,其他的如檔案系統、程序列表等還是隔離的。兩個容器的程序可以通過 lo 網絡卡裝置通訊。

在這裡插入圖片描述

2.4 bridge 模式

bridge 模式是 docker 的預設網路模式,不用 --net 引數,就是 bridge 模式。

相當於 VMware 中的 nat 模式,容器使用獨立 network Namespace ,並連線到 docker0 虛擬網絡卡。通過 docker0 網橋以及 iptables nat 表配置與宿主機通訊,此模式會為每一個容器分配 Network Namespace、設定 IP 等,並將一個主機上的 Docker 容器連線到一個虛擬網橋上。

當 Docker 程序啟動時,會在主機上建立一個名為 docker0 的虛擬網橋,此主機上啟動的 Docker 容器會連線到這個虛擬網橋上。虛擬網橋的工作方式和物理交換機類似,這樣主機上的所有容器就通過交換機連在了一個二層網路中。

從 docker0 子網中分配一個 IP 給容器使用,並設定 docker0 的 IP 地址為容器的預設閘道器。在主機上建立一對虛擬網絡卡 veth pair 裝置。veth 裝置總是成對出現的,它們組成了一個數據的通道,資料從一個裝置進入,就會從另一個裝置出來。因此,veth 裝置常用來連線兩個網路裝置。

在這裡插入圖片描述

Docker 將 veth pair 裝置的一端放在新建立的容器中,並命名為 eth0 (容器的網絡卡),另一端放在主機中,以 veth*這樣類似的名字命名,並將這個網路裝置加入到 docker0 網橋中。可以通過 brctl show 命令檢視。

yum install bridge-utils -y

使用 docker run -p 時,docker 實際是在 iptables 做了 DNAT 規則,實現埠轉發功能。可以使用 iptables -t nat -nL 檢視。

在這裡插入圖片描述

2.5 自定義網路模式

新建自定義網路: docker network create ${network-name}

在這裡插入圖片描述

以我們新建的網路啟動兩個 alpine 容器,進入任意一個容器,ping 另外一個容器的名字,yeah,ping 通了~

在這裡插入圖片描述