〖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 通了~

在這裏插入圖片描述