使用 Overlay 網路進行網路連接
本系列教學課程介紹了叢集服務的網路設定。若要了解獨立容器的網路設定,請參閱獨立容器的網路設定。如果您需要了解更多關於 Docker 網路設定的整體資訊,請參閱概觀。
本頁包含以下教學課程。您可以在 Linux、Windows 或 Mac 上執行每個教學課程,但最後一個教學課程需要您在其他地方執行第二個 Docker 主機。
使用預設重疊網路示範了當您初始化或加入叢集時,Docker 會自動為您設定的預設重疊網路的使用方式。此網路不是生產系統的最佳選擇。
使用使用者定義重疊網路展示了如何建立和使用您自己的自訂重疊網路來連接服務。這建議用於在生產環境中執行的服務。
為獨立容器使用重疊網路展示了如何使用重疊網路在不同 Docker 常駐程式上的獨立容器之間進行通訊。
先決條件
這些教學課程要求您至少有一個單節點叢集,這表示您已經啟動 Docker 並在主機上執行了 docker swarm init。您也可以在多節點叢集上執行這些範例。
使用預設重疊網路
在此範例中,您將啟動一個 alpine 服務,並從各個服務容器的角度檢查網路的特性。
本教學課程不會深入探討重疊網路的作業系統特定實作細節,而是專注於從服務的角度來看重疊網路的運作方式。
先決條件
本教學課程需要三個實體或虛擬 Docker 主機,它們彼此之間都能夠通訊。本教學課程假設這三個主機都在同一個網路上執行,且沒有涉及防火牆。
這些主機將分別稱為 manager、worker-1 和 worker-2。manager 主機將同時作為管理者和工作者,這表示它既可以執行服務任務,也可以管理叢集。worker-1 和 worker-2 將僅作為工作者。
如果您沒有三個現成的主機,一個簡單的解決方案是在雲端供應商(例如 Amazon EC2)上設定三個 Ubuntu 主機,所有主機都在同一個網路上,並且允許所有主機之間的所有通訊(使用諸如 EC2 安全群組的機制),然後遵循在 Ubuntu 上安裝 Docker Engine - Community 的說明。
逐步解說
建立叢集
在本程序結束時,所有三個 Docker 主機都將加入叢集,並使用名為 ingress 的重疊網路相互連接。
在
manager上,初始化叢集。如果主機只有一個網路介面,則--advertise-addr旗標是可選的。$ docker swarm init --advertise-addr=<IP-ADDRESS-OF-MANAGER>請記下列印出的文字,因為其中包含您將用於將
worker-1和worker-2加入叢集的令牌 (token)。建議將此令牌儲存在密碼管理器中。在
worker-1上,加入叢集。如果主機只有一個網路介面,則--advertise-addr旗標是可選的。$ docker swarm join --token <TOKEN> \ --advertise-addr <IP-ADDRESS-OF-WORKER-1> \ <IP-ADDRESS-OF-MANAGER>:2377在
worker-2上,加入叢集。如果主機只有一個網路介面,則--advertise-addr旗標是可選的。$ docker swarm join --token <TOKEN> \ --advertise-addr <IP-ADDRESS-OF-WORKER-2> \ <IP-ADDRESS-OF-MANAGER>:2377在
manager上,列出所有節點。此命令只能從管理者執行。$ docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS d68ace5iraw6whp7llvgjpu48 * ip-172-31-34-146 Ready Active Leader nvp5rwavvb8lhdggo8fcf7plg ip-172-31-35-151 Ready Active ouvx2l7qfcxisoyms8mtkgahw ip-172-31-36-89 Ready Active您也可以使用
--filter旗標依角色進行篩選$ docker node ls --filter role=manager ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS d68ace5iraw6whp7llvgjpu48 * ip-172-31-34-146 Ready Active Leader $ docker node ls --filter role=worker ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS nvp5rwavvb8lhdggo8fcf7plg ip-172-31-35-151 Ready Active ouvx2l7qfcxisoyms8mtkgahw ip-172-31-36-89 Ready Active列出
manager、worker-1和worker-2上的 Docker 網路,並注意每個主機現在都有一個名為ingress的重疊網路和一個名為docker_gwbridge的橋接網路。此處僅顯示manager的列表$ docker network ls NETWORK ID NAME DRIVER SCOPE 495c570066be bridge bridge local 961c6cae9945 docker_gwbridge bridge local ff35ceda3643 host host local trtnl4tqnc3n ingress overlay swarm c8357deec9cb none null local
docker_gwbridge 將 ingress 網路連接到 Docker 主機的網路介面,以便流量可以在叢集管理者和工作者之間流動。如果您建立叢集服務時未指定網路,它們將連接到 ingress 網路。建議為每個應用程式或協同運作的應用程式群組使用單獨的重疊網路。在下一個程序中,您將建立兩個重疊網路並將一個服務連接到每個網路。
建立服務
在
manager上,建立一個名為nginx-net的新重疊網路$ docker network create -d overlay nginx-net您不需要在其他節點上建立重疊網路,因為當其中一個節點開始執行需要該網路的服務任務時,它將會自動建立。
在
manager上,建立一個連接到nginx-net的 5 副本 Nginx 服務。該服務將會將連接埠 80 發佈到外部。所有服務任務容器都可以彼此通訊,無需開啟任何連接埠。注意服務只能在管理者上建立。
$ docker service create \ --name my-nginx \ --publish target=80,published=80 \ --replicas=5 \ --network nginx-net \ nginx當您未為
--publish旗標指定mode時,使用的ingress預設發佈模式表示,如果您瀏覽manager、worker-1或worker-2上的連接埠 80,您將連接到 5 個服務任務中的其中一個的連接埠 80,即使您瀏覽的節點上目前沒有任務在執行。如果您想使用host模式發佈連接埠,您可以將mode=host加入到--publish輸出中。但是,在這種情況下,您也應該使用--mode global而不是--replicas=5,因為在給定節點上只有一個服務任務可以綁定一個給定的連接埠。執行
docker service ls以監控服務啟動的進度,這可能需要幾秒鐘。檢查
manager、worker-1和worker-2上的nginx-net網路。請記住,您無需在worker-1和worker-2上手動建立它,因為 Docker 會為您自動建立。輸出將會很長,但請注意Containers和Peers部分。Containers列出了從該主機連接到重疊網路的所有服務任務(或獨立容器)。從
manager,使用docker service inspect my-nginx檢查服務,並注意服務使用的連接埠和端點資訊。建立一個新網路
nginx-net-2,然後更新服務以使用此網路,而不是nginx-net$ docker network create -d overlay nginx-net-2$ docker service update \ --network-add nginx-net-2 \ --network-rm nginx-net \ my-nginx執行
docker service ls以驗證服務已更新且所有任務已重新部署。執行docker network inspect nginx-net以驗證沒有容器連接到它。對nginx-net-2執行相同的命令,並注意所有服務任務容器都已連接到它。注意儘管重疊網路會根據需要自動在叢集工作節點上建立,但它們不會自動移除。
清理服務和網路。從
manager,執行以下命令。管理者將指示工作者自動移除網路。$ docker service rm my-nginx $ docker network rm nginx-net nginx-net-2
使用使用者定義重疊網路
先決條件
本教學課程假設叢集已經設定好,並且您位於管理者上。
逐步解說
建立使用者定義重疊網路。
$ docker network create -d overlay my-overlay啟動一個使用重疊網路的服務,並將連接埠 80 發佈到 Docker 主機上的連接埠 8080。
$ docker service create \ --name my-nginx \ --network my-overlay \ --replicas 1 \ --publish published=8080,target=80 \ nginx:latest執行
docker network inspect my-overlay,並透過查看Containers部分來驗證my-nginx服務任務是否已連接到它。移除服務和網路。
$ docker service rm my-nginx $ docker network rm my-overlay
為獨立容器使用重疊網路
此範例示範了 DNS 容器發現 — 特別是,如何使用重疊網路在不同 Docker 常駐程式上的獨立容器之間進行通訊。步驟如下:
- 在
host1上,將節點初始化為叢集(管理者)。 - 在
host2上,將節點加入叢集(工作者)。 - 在
host1上,建立一個可附加的重疊網路(test-net)。 - 在
host1上,在test-net上執行一個互動式 alpine 容器(alpine1)。 - 在
host2上,在test-net上執行一個互動式且分離的 alpine 容器(alpine2)。 - 在
host1上,從alpine1的會話中,pingalpine2。
先決條件
對於此測試,您需要兩個可以相互通訊的不同 Docker 主機。每個主機必須在兩個 Docker 主機之間開啟以下連接埠:
- TCP 連接埠 2377
- TCP 和 UDP 連接埠 7946
- UDP 連接埠 4789
設定此環境的一個簡單方法是準備兩個虛擬機(本地或在 AWS 等雲端供應商上),每個虛擬機都安裝並執行 Docker。如果您使用 AWS 或類似的雲端運算平台,最簡單的配置是使用一個安全群組,該群組會開啟兩個主機之間所有傳入連接埠以及從您的用戶端 IP 位址到 SSH 的連接埠。
此範例將我們的叢集中的兩個節點稱為 host1 和 host2。此範例也使用 Linux 主機,但相同的命令在 Windows 上也適用。
逐步解說
設定叢集。
a. 在
host1上,初始化一個叢集(如果提示,請使用--advertise-addr來指定與叢集中其他主機通訊的介面 IP 位址,例如 AWS 上的私有 IP 位址)$ docker swarm init Swarm initialized: current node (vz1mm9am11qcmo979tlrlox42) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-5g90q48weqrtqryq4kj6ow0e8xm9wmv9o6vgqc5j320ymybd5c-8ex8j0bc40s6hgvy5ui5gl4gy 172.31.47.252:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.b. 在
host2上,依照上述說明加入叢集$ docker swarm join --token <your_token> <your_ip_address>:2377 This node joined a swarm as a worker.如果節點無法加入叢集,
docker swarm join命令將會逾時。若要解決此問題,請在host2上執行docker swarm leave --force,驗證您的網路和防火牆設定,然後再試一次。在
host1上,建立一個名為test-net的可附加重疊網路$ docker network create --driver=overlay --attachable test-net uqsof8phj3ak0rq9k86zta6ht請注意回傳的 NETWORK ID — 當您從
host2連接到它時,您會再次看到它。在
host1上,啟動一個連接到test-net的互動式(-it)容器(alpine1)$ docker run -it --name alpine1 --network test-net alpine / #在
host2上,列出可用網路 — 請注意test-net尚未存在$ docker network ls NETWORK ID NAME DRIVER SCOPE ec299350b504 bridge bridge local 66e77d0d0e9a docker_gwbridge bridge local 9f6ae26ccb82 host host local omvdxqrda80z ingress overlay swarm b65c952a4b2b none null local在
host2上,啟動一個連接到test-net的分離式(-d)和互動式(-it)容器(alpine2)$ docker run -dit --name alpine2 --network test-net alpine fb635f5ece59563e7b8b99556f816d24e6949a5f6a5b1fbd92ca244db17a4342注意自動 DNS 容器發現僅適用於唯一的容器名稱。
在
host2上,驗證test-net是否已建立(並具有與host1上test-net相同的 NETWORK ID)$ docker network ls NETWORK ID NAME DRIVER SCOPE ... uqsof8phj3ak test-net overlay swarm在
host1上,在alpine1的互動式終端機中 pingalpine2/ # ping -c 2 alpine2 PING alpine2 (10.0.0.5): 56 data bytes 64 bytes from 10.0.0.5: seq=0 ttl=64 time=0.600 ms 64 bytes from 10.0.0.5: seq=1 ttl=64 time=0.555 ms --- alpine2 ping statistics --- 2 packets transmitted, 2 packets received, 0% packet loss round-trip min/avg/max = 0.555/0.577/0.600 ms這兩個容器透過連接兩個主機的重疊網路進行通訊。如果您在
host2上執行另一個 未分離 的 alpine 容器,您可以從host2pingalpine1(我們在此處新增了移除選項以進行自動容器清理)$ docker run -it --rm --name alpine3 --network test-net alpine / # ping -c 2 alpine1 / # exit在
host1上,關閉alpine1會話(這也會停止容器)/ # exit清理您的容器和網路
您必須在每個主機上獨立停止並移除容器,因為 Docker 常駐程式獨立運作,且這些是獨立容器。您只需在
host1上移除網路,因為當您在host2上停止alpine2時,test-net將會消失。a. 在
host2上,停止alpine2,檢查test-net是否已移除,然後移除alpine2$ docker container stop alpine2 $ docker network ls $ docker container rm alpine2a. 在
host1上,移除alpine1和test-net$ docker container rm alpine1 $ docker network rm test-net