1. 程式人生 > 其它 >Docker網路模式詳解及容器間網路通訊(6)

Docker網路模式詳解及容器間網路通訊(6)

Docker網路模式詳解及容器間網路通訊

參考資料

B站狂神說教程

B站清風程式碼教程

1. 預設網路

安裝 Docker 以後,會預設建立三種網路,可以通過 docker network ls 檢視。

[root@CentOS7 ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
71c1c4608319   bridge    bridge    local
767f114c1d6a   host      host      local
239984d23cb5   none      null      local

在學習 Docker 網路之前,我們有必要先來了解一下這幾種網路模式都是什麼意思。

網路模式 簡介
bridge 為每一個容器分配、設定 IP 等,並將容器連線到一個 docker0 虛擬網橋,預設為該模式。
host 容器將不會虛擬出自己的網絡卡,配置自己的 IP 等,而是使用宿主機的 IP 和埠。
none 容器有獨立的 Network namespace,但並沒有對其進行任何網路設定,如分配 veth pair 和網橋連線,IP 等。
container 新建立的容器不會建立自己的網絡卡和配置自己的 IP,而是和一個指定的容器共享 IP、埠範圍等。

1.1. bridge網路模式

在該模式中,Docker 守護程序建立了一個虛擬乙太網橋 docker0 ,新建的容器會自動橋接到這個介面,附加在其上的任何網絡卡之間都能自動轉發資料包。
預設情況下,守護程序會建立一對對等虛擬裝置介面 veth pair ,將其中一個介面設定為容器的 eth0 介面(容器的網絡卡),另一個介面放置在宿主機的名稱空間中,以類似 vethxxx 這樣的名字命名,從而將宿主機上的所有容器都連線到這個內部網路上。
比如我執行一個基於 busybox 映象構建的容器 bbox01 ,檢視 ip addr :

busybox 被稱為嵌入式 Linux 的瑞士軍刀,整合了很多小的 unix 下的通用功能到一個小的可執行檔案中。

然後宿主機通過 ip addr 檢視資訊如下:

通過以上的比較可以發現,證實了之前所說的:守護程序會建立一對對等虛擬 裝置介面 veth pair ,將其中一個介面設定為容器的 eth0 介面(容器的網 卡),另一個介面放置在宿主機的名稱空間中,以類似 vethxxx 這樣的名字命名。

同時,守護程序還會從網橋 docker0 的私有地址空間中分配一個 IP 地址和子 網給該容器,並設定 docker0 的 IP 地址為容器的預設閘道器。也可以安裝 yum install -y bridge-utils 以後,通過 brctl show 命令檢視網橋資訊。

對於每個容器的 IP 地址和 Gateway 資訊,我們可以通過 docker inspect 容器名稱|ID 進行檢視,在 NetworkSettings 節點中可以看到詳細資訊。

我們可以通過 docker network inspect bridge 檢視所有 bridge 網路模 式下的容器,在 Containers 節點中可以看到容器名稱。

關於 bridge 網路模式的使用,只需要在建立容器時通過引數 --net bridge 或者 --network bridge 指定即可,當然這也是建立容器預設使用的 網路模式,也就是說這個引數是可以省略的。

Bridge 橋接模式的實現步驟主要如下:

  • Docker Daemon 利用 veth pair 技術,在宿主機上建立一對對等虛擬網路介面設 備,假設為 veth0 和 veth1。而 veth pair 技術的特性可以保證無論哪一個 veth 接收到網路報文,都會將報文傳 輸給另一方。
  • Docker Daemon 將 veth0 附加到 Docker Daemon 建立的 docker0 網橋上。保證宿 主機的網路報文可以發往 veth0;
  • Docker Daemon 將 veth1 新增到 Docker Container 所屬的 namespace 下,並被改 名為 eth0。如此一來,宿主機的網路報文若發往 veth0,則立即會被 Container 的 eth0 接收,實現宿主機到 Docker Container 網路的聯通性;同時,也保證 Docker Container 單獨使用 eth0,實現容器網路環境的隔離性。

1.2. host網路模式

  • host 網路模式需要在建立容器時通過引數 --net host 或者 --network host 指定;
  • 採用 host 網路模式的 Docker Container,可以直接使用宿主機的 IP 地址與外界進 行通訊,若宿主機的 eth0 是一個公有 IP,那麼容器也擁有這個公有 IP。同時容 器內服務的埠也可以使用宿主機的埠,無需額外進行 NAT 轉換;
  • host 網路模式可以讓容器共享宿主機網路棧,這樣的好處是外部主機與容器直 接通訊,但是容器的網路缺少隔離性。

比如我基於 host 網路模式建立了一個基於 busybox 映象構建的容器 bbox02 ,檢視 ip addr :

然後宿主機通過 ip addr 檢視資訊如下:

對,你沒有看錯,返回資訊一模一樣,我也可以肯定我沒有截錯圖,不信接著 往下看。我們可以通過 docker network inspect host 檢視所有 host 網路模 式下的容器,在 Containers 節點中可以看到容器名稱。

1.3. none網路模式

  • none 網路模式是指禁用網路功能,只有 lo 介面 local 的簡寫,代表 127.0.0.1,即 localhost 本地環回介面。在建立容器時通過引數 --net none 或者 --network none 指定;
  • none 網路模式即不為 Docker Container 建立任何的網路環境,容器內部就只能 使用 loopback 網路裝置,不會再有其他的網路資源。可以說 none 模式為 Docke Container 做了極少的網路設定,但是俗話說得好“少即是多”,在沒有網路配置 的情況下,作為 Docker 開發者,才能在這基礎做其他無限多可能的網路定製開 發。這也恰巧體現了 Docker 設計理念的開放。

比如我基於 none 網路模式建立了一個基於 busybox 映象構建的容器 bbox03 ,檢視 ip addr :

我們可以通過 docker network inspect none 檢視所有 none 網路模式下 的容器,在 Containers 節點中可以看到容器名稱。

1.4. container網路模式

  • Container 網路模式是 Docker 中一種較為特別的網路的模式。在建立容器時通過 引數 --net container:已執行的容器名稱|ID 或者 --network container:已 執行的容器名稱|ID 指定;
  • 處於這個模式下的 Docker 容器會共享一個網路棧,這樣兩個容器之間可以使用 localhost 高效快速通訊。

Container 網路模式即新建立的容器不會建立自己的網絡卡,配置自己的 IP,而是 和一個指定的容器共享 IP、埠範圍等。同樣兩個容器除了網路方面相同之外,其他的如檔案系統、程序列表等還是隔離的。

比如我基於容器 bbox01 建立了 container 網路模式的容器 bbox04 ,檢視 ip addr :

容器 bbox01 的 ip addr 資訊如下:

宿主機的 ip addr 資訊如下:

通過以上測試可以發現,Docker 守護程序只建立了一對對等虛擬裝置介面用於 連線 bbox01 容器和宿主機,而 bbox04 容器則直接使用了 bbox01 容器的網絡卡資訊。

這個時候如果將 bbox01 容器停止,會發現 bbox04 容器就只剩下 lo 介面了。


然後 bbox01 容器重啟以後,bbox04 容器也重啟一下,就又可以獲取到網絡卡信 息了。

docker run --link 可以用來連線兩個容器,使得源容器(被連結的容器)和 接收容器(主動去連結的容器)之間可以互相通訊,並且接收容器可以獲取源容器 的一些資料,如源容器的環境變數。  

這種方式官方已不推薦使用,並且在未來版本可能會被移除,所以這裡不作為 重點講解,感興趣可自行了解。

官網警告資訊:https://docs.docker.com/network/links/

2. 自定義網路

雖然 Docker 提供的預設網路使用比較簡單,但是為了保證各容器中應用的安全 性,在實際開發中更推薦使用自定義的網路進行容器管理,以及啟用容器名稱到 IP 地址的自動 DNS 解析。

從 Docker 1.10 版本開始,docker daemon 實現了一個內嵌的 DNS server, 使容器可以直接通過容器名稱進行通訊。方法很簡單,只要在建立容器時使用 --name 為容器命名即可。  

但是使用 Docker DNS 有個限制:只能在 user-defined 網路中使用。也就是 說,預設的 bridge 網路是無法使用 DNS 的,所以我們就需要自定義網路。

2.1. 建立網路

通過 docker network create 命令可以建立自定義網路模式,命令提示如下:

進一步檢視 docker network create 命令使用詳情,發現可以通過 -- driver 指定網路模式且預設是 bridge 網路模式,提示如下:

建立命令:

# 建立一個基於 **bridge** 網路模式的自定義網路模式 custom_network ,完整命 令如下:
docker network create custom_network

# 通過 docker network ls 檢視網路模式:
docker network ls

# 通過自定義網路模式 custom_network 建立容器:
docker run -di --name bbox05 --net custom_network busybox

通過 docker inspect 容器名稱|ID 檢視容器的網路資訊,在 NetworkSettings 節點中可以看到詳細資訊。

2.2. 連線網路

通過 docker network connect 網路名稱 容器名稱 為容器連線新的網路模式。

# bbox05 連線到 bridge 網路
docker network connect bridge bbox05

# 檢視容器的網路資訊
docker inspect bbox05

通過 docker inspect 容器名稱|ID 再次檢視容器的網路資訊,多增加了預設的 bridge

2.3 斷開網路

# 通過 docker network disconnect 網路名稱 容器名稱 命令斷開網路。
docker network disconnect custom_network bbox05

# 通過 docker inspect 容器名稱|ID 再次檢視容器的網路資訊,發現只剩下預設的 bridge
docker inspect bbox05 

2.4. 移除網路

可以通過 docker network rm 網路名稱 命令移除自定義網路模式,網路模式移除成功會返回網路模式名稱。

docker network rm custom_network

注意:如果通過某個自定義網路模式建立了容器,則該網路模式無法刪除

3. 容器間網路通訊

接下來我們通過所學的知識實現容器間的網路通訊。首先明確一點,容器之間要互相通訊,必須要有屬於同一個網路的網絡卡。

3.1. 預設網路通訊

# 我們先建立兩個基於預設的 bridge 網路模式的容器。
docker run -di --name default_bbox01 busybox
docker run -di --name default_bbox02 busybox

# 通過 docker network inspect bridge 檢視兩個容器的具體IP資訊

然後測試兩容器間是否可以進行網路通訊。

經過測試,從結果得知兩個屬於同一個網路的容器是可以進行網路通訊的,但 是 IP 地址可能是不固定的,有被更改的情況發生,那容器內所有通訊的 IP 地址也需要進行更改,能否使用容器名稱進行網路通訊?繼續測試。

經過測試,從結果得知使用容器進行網路通訊是不行的,那怎麼實現這個功能呢?

3.2. 自定義網路通訊

從 Docker 1.10 版本開始,docker daemon 實現了一個內嵌的 DNS server,使容 器可以直接通過容器名稱通訊。方法很簡單,只要在建立容器時使用 --name 為容器 命名即可。  

但是使用 Docker DNS 有個限制:只能在 user-defined 網路中使用。也就是說, 預設的 bridge 網路是無法使用 DNS 的,所以我們就需要自定義網路。  

我們先基於 bridge 網路模式建立自定義網路 custom_network ,然後建立兩 個基於自定義網路模式的容器。

docker run -di --name custom_bbox01 --net custom_network busybox
docker run -di --name custom_bbox02 --net custom_network busybox

通過 docker network inspect custom_network 檢視兩容器的具體 IP 信 息。

然後測試兩容器間是否可以進行網路通訊,分別使用具體 IP 和容器名稱進行網路通訊。

經過測試,從結果得知兩個屬於同一個自定義網路的容器是可以進行網路通訊 的,並且可以使用容器名稱進行網路通訊。

那如果此時我希望 bridge 網路下的容器可以和 custom_network 網路下的容器進行網路又該如何操作?其實答案也非常簡單:讓 bridge 網路下的容器連線至新的 custom_network 網路即可。

docker network connect custom_network default_bbox01

然後通過 default_bbox01 去 ping custom

學完容器網路通訊,大家就可以練習使用多個容器完成常見應用叢集的部署 了。後面就該學習 Docker 進階部分的內容 Docker Compose 和 Docker Swarm。