管理 Swarm 服務網路
本頁面說明 Swarm 服務的網路組態。
Swarm 與流量類型
Docker Swarm 會產生兩種不同的流量
控制與管理平面流量:這包括 Swarm 管理訊息,例如加入或離開 Swarm 的請求。此流量一律經過加密。
應用程式資料平面流量:這包括容器流量,以及與外部用戶端之間的流量。
關鍵網路概念
下列三個網路概念對 Swarm 服務很重要
疊加網路管理參與 Swarm 的 Docker 守護程式之間的通訊。您可以建立疊加網路,方式與為獨立容器建立使用者定義網路相同。您也可以將服務連接至一個或多個現有的疊加網路,以啟用服務間通訊。疊加網路是使用
overlay網路驅動程式的 Docker 網路。Ingress 網路是一種特殊的疊加網路,用於促進服務節點之間的負載平衡。當任何 Swarm 節點在發布的連接埠上收到請求時,它會將該請求轉交給一個名為
IPVS的模組。IPVS會追蹤參與該服務的所有 IP 位址,選擇其中一個,並透過ingress網路將請求路由到該位址。當您初始化或加入 Swarm 時,
ingress網路會自動建立。大多數使用者不需要自訂其設定,但 Docker 允許您這麼做。docker_gwbridge是一個橋接網路,用於將疊加網路 (包括ingress網路) 連接至個別 Docker 守護程式的實體網路。依預設,服務執行的每個容器都會連接到其本機 Docker 守護程式主機的docker_gwbridge網路。當您初始化或加入 Swarm 時,
docker_gwbridge網路會自動建立。大多數使用者不需要自訂其設定,但 Docker 允許您這麼做。
提示另請參閱 網路概覽 以取得有關 Swarm 網路的更多詳細資訊。
防火牆考量
參與 Swarm 的 Docker 守護程式需要能夠透過以下連接埠相互通訊
- 連接埠
7946TCP/UDP,用於容器網路探索。 - 連接埠
4789UDP (可設定),用於疊加網路 (包括 ingress) 資料路徑。
在 Swarm 中設定網路時,應特別小心。請參閱 教學課程 以取得概覽。
疊加網路
當您初始化 Swarm 或將 Docker 主機加入現有的 Swarm 時,該 Docker 主機上會建立兩個新網路
- 一個名為
ingress的疊加網路,負責處理與 Swarm 服務相關的控制和資料流量。當您建立 Swarm 服務且未將其連接至使用者定義的疊加網路時,它會預設連接到ingress網路。 - 一個名為
docker_gwbridge的橋接網路,用於將個別 Docker 守護程式連接至參與 Swarm 的其他守護程式。
建立疊加網路
若要建立疊加網路,請在使用 docker network create 命令時指定 overlay 驅動程式
$ docker network create \
--driver overlay \
my-network
上述命令未指定任何自訂選項,因此 Docker 會指派一個子網路並使用預設選項。您可以使用 docker network inspect 查看有關網路的資訊。
當沒有容器連接到疊加網路時,其設定內容並不豐富
$ docker network inspect my-network
[
{
"Name": "my-network",
"Id": "fsf1dmx3i9q75an49z36jycxd",
"Created": "0001-01-01T00:00:00Z",
"Scope": "swarm",
"Driver": "overlay",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": []
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"Containers": null,
"Options": {
"com.docker.network.driver.overlay.vxlanid_list": "4097"
},
"Labels": null
}
]
在上述輸出中,請注意驅動程式為 overlay 且範圍為 swarm,而不是您可能在其他類型 Docker 網路中看到的 local、host 或 global 範圍。此範圍表示只有參與 Swarm 的主機才能存取此網路。
當服務首次連接到網路時,網路的子網路和閘道會動態設定。以下範例顯示與上方相同的網路,但有三個 redis 服務的容器連接到它。
$ docker network inspect my-network
[
{
"Name": "my-network",
"Id": "fsf1dmx3i9q75an49z36jycxd",
"Created": "2017-05-31T18:35:58.877628262Z",
"Scope": "swarm",
"Driver": "overlay",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "10.0.0.0/24",
"Gateway": "10.0.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"Containers": {
"0e08442918814c2275c31321f877a47569ba3447498db10e25d234e47773756d": {
"Name": "my-redis.1.ka6oo5cfmxbe6mq8qat2djgyj",
"EndpointID": "950ce63a3ace13fe7ef40724afbdb297a50642b6d47f83a5ca8636d44039e1dd",
"MacAddress": "02:42:0a:00:00:03",
"IPv4Address": "10.0.0.3/24",
"IPv6Address": ""
},
"88d55505c2a02632c1e0e42930bcde7e2fa6e3cce074507908dc4b827016b833": {
"Name": "my-redis.2.s7vlybipal9xlmjfqnt6qwz5e",
"EndpointID": "dd822cb68bcd4ae172e29c321ced70b731b9994eee5a4ad1d807d9ae80ecc365",
"MacAddress": "02:42:0a:00:00:05",
"IPv4Address": "10.0.0.5/24",
"IPv6Address": ""
},
"9ed165407384f1276e5cfb0e065e7914adbf2658794fd861cfb9b991eddca754": {
"Name": "my-redis.3.hbz3uk3hi5gb61xhxol27hl7d",
"EndpointID": "f62c686a34c9f4d70a47b869576c37dffe5200732e1dd6609b488581634cf5d2",
"MacAddress": "02:42:0a:00:00:04",
"IPv4Address": "10.0.0.4/24",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.driver.overlay.vxlanid_list": "4097"
},
"Labels": {},
"Peers": [
{
"Name": "moby-e57c567e25e2",
"IP": "192.168.65.2"
}
]
}
]
自訂疊加網路
在某些情況下,您可能不想使用疊加網路的預設設定。有關可設定選項的完整列表,請執行命令 docker network create --help。以下是一些最常見的變更選項。
設定子網路和閘道
依預設,當第一個服務連接到網路時,網路的子網路和閘道會自動設定。您可以在建立網路時使用 --subnet 和 --gateway 旗標來設定這些選項。以下範例透過設定子網路和閘道來擴展先前的範例。
$ docker network create \
--driver overlay \
--subnet 10.0.9.0/24 \
--gateway 10.0.9.99 \
my-network
使用自訂預設位址池
若要為您的 Swarm 網路自訂子網路分配,您可以在 swarm init 期間選擇性地設定它們。
例如,在初始化 Swarm 時使用以下命令
$ docker swarm init --default-addr-pool 10.20.0.0/16 --default-addr-pool-mask-length 26
每當使用者建立網路但未使用 --subnet 命令列選項時,此網路的子網路將從池中下一個可用的子網路依序分配。如果指定的網路已被分配,則該網路將不會用於 Swarm。
如果需要不連續的位址空間,可以設定多個池。但是,不支援從特定池進行分配。網路子網路將從 IP 池空間依序分配,並且在從已刪除的網路中解除分配時,子網路將被重複使用。
可以設定預設的遮罩長度,並且所有網路都相同。預設設定為 /24。若要變更預設子網路遮罩長度,請使用 --default-addr-pool-mask-length 命令列選項。
注意預設位址池只能在
swarm init時設定,並且在叢集建立後無法更改。
疊加網路大小限制
Docker 建議使用 /24 區塊建立疊加網路。/24 疊加網路區塊將網路限制為 256 個 IP 位址。
此建議解決了 Swarm 模式的限制。如果您需要超過 256 個 IP 位址,請勿增加 IP 區塊大小。您可以選擇搭配外部負載平衡器使用 dnsrr 端點模式,或使用多個較小的疊加網路。請參閱設定服務探索以取得有關不同端點模式的更多資訊。
設定應用程式資料加密
與 Swarm 相關的管理和控制平面資料一律加密。有關加密機制的更多詳細資訊,請參閱Docker Swarm 模式疊加網路安全模型。
Swarm 節點之間的應用程式資料預設不加密。若要在給定的疊加網路上加密此流量,請在 docker network create 上使用 --opt encrypted 旗標。這會在 vxlan 層級啟用 IPSEC 加密。此加密會帶來不可忽略的效能損失,因此您應該在生產環境中使用此選項之前進行測試。
注意您必須自訂自動建立的 ingress 以啟用加密。依預設,所有 ingress 流量都未加密,因為加密是網路層級的選項。
將服務連接至疊加網路
若要將服務連接至現有的疊加網路,請將 --network 旗標傳遞給 docker service create,或將 --network-add 旗標傳遞給 docker service update。
$ docker service create \
--replicas 3 \
--name my-web \
--network my-network \
nginx
連接到疊加網路的服務容器可以相互通訊。
若要查看服務連接到哪些網路,請使用 docker service ls 尋找服務名稱,然後使用 docker service ps <service-name> 列出網路。或者,若要查看哪些服務的容器連接到某個網路,請使用 docker network inspect <network-name>。您可以在任何已加入 Swarm 且處於 running 狀態的 Swarm 節點上執行這些命令。
設定服務探索
服務探索是 Docker 用來將服務外部用戶端的請求路由到個別 Swarm 節點的機制,用戶端無需知道有多少節點參與服務,也無需知道它們的 IP 位址或連接埠。您無需發布同一網路中服務之間使用的連接埠。例如,如果您有一個將資料儲存在 MySQL 服務中的 WordPress 服務,並且它們連接到相同的疊加網路,則您無需向用戶端發布 MySQL 連接埠,只需發布 WordPress HTTP 連接埠。
服務探索可以透過兩種不同方式運作:在第 3 層和第 4 層使用嵌入式 DNS 和虛擬 IP (VIP) 的內部基於連接的負載平衡,或在第 7 層使用 DNS 輪詢 (DNSRR) 的外部和自訂基於請求的負載平衡。您可以為每個服務設定此功能。
依預設,當您將服務連接到網路且該服務發布一個或多個連接埠時,Docker 會為該服務指派一個虛擬 IP (VIP),這是用戶端到達服務的「前端」。Docker 會保留服務中所有工作節點的列表,並在用戶端和其中一個節點之間路由請求。來自用戶端的每個請求都可能路由到不同的節點。
如果您設定服務使用 DNS 輪詢 (DNSRR) 服務探索,則沒有單一虛擬 IP。相反,Docker 會為服務設定 DNS 條目,使得對服務名稱的 DNS 查詢會返回一個 IP 位址列表,然後用戶端直接連接到其中一個。
DNS 輪詢在您想要使用自己的負載平衡器 (例如 HAProxy) 的情況下很有用。若要設定服務使用 DNSRR,請在建立新服務或更新現有服務時使用
--endpoint-mode dnsrr旗標。
自訂 Ingress 網路
大多數使用者從不需要設定 ingress 網路,但 Docker 允許您這麼做。如果自動選擇的子網路與您網路上已存在的子網路衝突,或者您需要自訂其他低階網路設定 (例如 MTU),或者您想啟用加密,這可能很有用。
自訂 ingress 網路涉及移除並重新建立它。這通常在您在 Swarm 中建立任何服務之前完成。如果您有發布連接埠的現有服務,則在您可以移除 ingress 網路之前,需要先移除這些服務。
在沒有 ingress 網路的期間,不發布連接埠的現有服務會繼續運作,但不會進行負載平衡。這會影響發布連接埠的服務,例如發布連接埠 80 的 WordPress 服務。
使用
docker network inspect ingress檢查ingress網路,並移除任何其容器已連接到該網路的服務。這些是發布連接埠的服務,例如發布連接埠 80 的 WordPress 服務。如果所有此類服務都沒有停止,則下一步會失敗。移除現有的
ingress網路$ docker network rm ingress WARNING! Before removing the routing-mesh network, make sure all the nodes in your swarm run the same docker engine version. Otherwise, removal may not be effective and functionality of newly created ingress networks will be impaired. Are you sure you want to continue? [y/N]使用
--ingress旗標以及您要設定的自訂選項來建立新的疊加網路。此範例將 MTU 設定為 1200,將子網路設定為10.11.0.0/16,並將閘道設定為10.11.0.2。$ docker network create \ --driver overlay \ --ingress \ --subnet=10.11.0.0/16 \ --gateway=10.11.0.2 \ --opt com.docker.network.driver.mtu=1200 \ my-ingress注意您可以將
ingress網路命名為ingress以外的名稱,但您只能有一個。嘗試建立第二個會失敗。重新啟動您在第一步中停止的服務。
自訂 docker_gwbridge
docker_gwbridge 是一個虛擬橋接器,用於將疊加網路 (包括 ingress 網路) 連接至個別 Docker 守護程式的實體網路。當您初始化 Swarm 或將 Docker 主機加入 Swarm 時,Docker 會自動建立它,但它不是 Docker 裝置。它存在於 Docker 主機的核心中。如果您需要自訂其設定,您必須在將 Docker 主機加入 Swarm 之前,或在暫時將主機從 Swarm 移除之後進行。
您需要在您的作業系統上安裝 brctl 應用程式,才能刪除現有的橋接器。套件名稱為 bridge-utils。
停止 Docker。
使用
brctl show docker_gwbridge命令檢查是否存在名為docker_gwbridge的橋接裝置。如果存在,請使用brctl delbr docker_gwbridge移除它。啟動 Docker。請勿加入或初始化 Swarm。
使用您的自訂設定建立或重新建立
docker_gwbridge橋接器。此範例使用子網路10.11.0.0/16。有關可自訂選項的完整列表,請參閱橋接器驅動程式選項。$ docker network create \ --subnet 10.11.0.0/16 \ --opt com.docker.network.bridge.name=docker_gwbridge \ --opt com.docker.network.bridge.enable_icc=false \ --opt com.docker.network.bridge.enable_ip_masquerade=true \ docker_gwbridge初始化或加入 Swarm。
為控制和資料流量使用獨立介面
依預設,所有 Swarm 流量都會透過相同介面傳送,包括用於維護 Swarm 本身的控制和管理流量,以及與服務容器之間的資料流量。
您可以透過在初始化或加入 Swarm 時傳遞 --data-path-addr 旗標來分離此流量。如果有多個介面,則必須明確指定 --advertise-addr,如果未指定 --data-path-addr,則其預設為 --advertise-addr。關於加入、離開和管理 Swarm 的流量會透過 --advertise-addr 介面傳送,而服務容器之間的流量會透過 --data-path-addr 介面傳送。這些旗標可以接受 IP 位址或網路裝置名稱,例如 eth0。
此範例使用獨立的 --data-path-addr 初始化 Swarm。它假設您的 Docker 主機有兩個不同的網路介面:10.0.0.1 應用於控制和管理流量,而 192.168.0.1 應用於與服務相關的流量。
$ docker swarm init --advertise-addr 10.0.0.1 --data-path-addr 192.168.0.1
此範例加入由主機 192.168.99.100:2377 管理的 Swarm,並將 --advertise-addr 旗標設定為 eth0,將 --data-path-addr 旗標設定為 eth1。
$ docker swarm join \
--token SWMTKN-1-49nj1cmql0jkz5s954yi3oex3nedyz0fb0xx14ie39trti4wxv-8vxv8rssmk743ojnwacrr2d7c \
--advertise-addr eth0 \
--data-path-addr eth1 \
192.168.99.100:2377
在疊加網路發布連接埠
連接到相同疊加網路的 Swarm 服務會有效地相互公開所有連接埠。若要使連接埠在服務外部可存取,必須在 docker service create 或 docker service update 上使用 -p 或 --publish 旗標來發布該連接埠。支援傳統的冒號分隔語法和較新的逗號分隔值語法。較長的語法更受歡迎,因為它具有一定程度的自我文件性。
| 旗標值 | 描述 |
|---|---|
| -p 8080:80或 -p published=8080,target=80 | 將服務上的 TCP 連接埠 80 映射到路由網格上的連接埠 8080。 |
| -p 8080:80/udp或 -p published=8080,target=80,protocol=udp | 將服務上的 UDP 連接埠 80 映射到路由網格上的連接埠 8080。 |
| -p 8080:80/tcp -p 8080:80/udp或 -p published=8080,target=80,protocol=tcp -p published=8080,target=80,protocol=udp | 將服務上的 TCP 連接埠 80 映射到路由網格上的 TCP 連接埠 8080,並將服務上的 UDP 連接埠 80 映射到路由網格上的 UDP 連接埠 8080。 |