Docker 的網路模型對於容器間通訊和外部服務存取至關重要。理解不同網路模式的特性和組態方法,才能有效管理容器化應用程式。本文將探討 Docker 的 bridge、overlay 和 ingress 網路模式,並提供 Swarm 模式下的網路組態與管理實務。透過實際案例和程式碼範例,將能更清晰地理解 Docker 網路模型的運作方式,以及如何根據應用需求選擇合適的網路模式。同時也涵蓋了網路管理的常見問題和解決方案,例如跨主機通訊、外部服務存取和網路安全等議題,幫助讀者建立更穩固且高效的容器化應用程式架構。
Docker 網路模式深度解析
Docker 的預設網路模式是透過 docker0 網橋提供容器間的通訊,但此模式存在多主機網路限制及外部存取隔離問題。本章將探討 Docker 網路架構及其解決方案。
預設 Docker 網路的限制
預設的 docker0 網橋網路有以下主要限制:
- 區域性限制:僅限於單一 Docker 主機,無法跨主機通訊
- 外部存取隔離:容器預設與外部網路隔離,雖可對映埠到主機,但仍受限於 docker0 網橋的設定
Swarm 模式下的網路解決方案
在 Docker Engine 1.12 以上版本啟用 Swarm 模式後,會自動建立一個名為 ingress 的 overlay 網路。此網路提供多主機通訊能力,並允許外部使用者端存取 Swarm 服務。
Ingress 網路特性
- 自動建立於 Swarm 初始化時
- 提供負載平衡功能
- 服務若發布埠則自動加入 ingress 網路
- 具備預設閘道器和子網路設定
自定義 Overlay 網路
除了預設的 ingress 網路,使用者可透過 overlay 驅動程式建立自定義 overlay 網路,用於服務間通訊。
主要特點
- 提供服務間直接通訊能力
- 僅 Swarm 服務任務容器可使用
- 網路範圍預設限於執行服務任務的節點
- 可與底層網路重疊(在現代核心上)
docker_gwbridge 網路
當 Swarm 模式初始化時,除了 ingress 網路,還會自動建立 docker_gwbridge 網路。該網路作為橋接網路,將所有 overlay 網路(包括 ingress)連線到 Docker 守護程式的主機網路。
連線特性
- 連線所有 overlay 網路到主機網路
- 每個服務容器都會連線到本地的 docker_gwbridge 網路
Bridge 網路的應用場景
在 Docker 主機上,bridge 網路用於管理容器間的通訊。Swarm 模式下的服務若未發布埠,也會被建立在 bridge 網路中。
主要應用
- 單一主機上的容器間通訊
- 未發布埠的 Swarm 服務容器網路
- 使用
docker run啟動的容器預設網路
程式碼範例與解析
以下是一個建立 Swarm 服務並發布埠的命令範例:
docker service create \
--name my_service \
--publish 8080:80 \
nginx:latest
內容解密:
docker service create:建立新的 Swarm 服務--name my_service:指定服務名稱為 my_service--publish 8080:80:將服務的 80 埠對映到主機的 8080 埠nginx:latest:使用最新的 nginx 映象建立服務
此命令會將服務加入 ingress 網路,並允許外部存取。
Docker Swarm 網路組態與管理
環境設定
首先,在 Docker for AWS 上建立一個包含三個節點的 Docker Swarm 叢集,如第 3 章所述。利用 AWS CloudFormation 堆積疊(如圖 10-3 所示)來建立 Swarm 叢集。
接著,取得 Swarm 管理節點的公有 IP 地址(如圖 10-4 所示),並透過 SSH 登入該節點。
[root@localhost ~]# ssh -i "docker.pem" [email protected]
Welcome to Docker!
列出 Swarm 節點,包括一個管理節點和兩個工作節點。
~ $ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
npz2akark8etv4ib9biob5yyk ip-172-31-47-123.ec2.internal Ready Active
p6wat4lxq6a1o3h4fp2ikgw6r ip-172-31-3-168.ec2.internal Ready Active
tb5agvzbi0rupq7b83tk00cx3 * ip-172-31-47-15.ec2.internal Ready Active Leader
內容解密:
此步驟的主要目的是驗證 Swarm 叢集的設定是否正確。透過 docker node ls 命令,可以檢視叢集中各節點的狀態和角色。
Swarm 模式下的網路
在 Swarm 模式下,Docker 提供了一些預設網路,可以透過 docker network ls 命令列出。這些網路不僅適用於 Docker for AWS,也適用於任何支援 Swarm 模式的平台(如 CoreOS)。
~ $ docker network ls
NETWORK ID NAME DRIVER SCOPE
34a5f77de8cf bridge bridge local
0e06b811a613 docker_gwbridge bridge local
6763ebad69cf host host local
e41an60iwval ingress overlay swarm
eb7399d3ffdd none null local
內容解密:
此處列出的網路包括 bridge、docker_gwbridge、host、ingress 和 none。其中,ingress 網路是 Swarm 模式下用於外部存取的 overlay 網路。
使用預設的 Overlay 網路建立服務
要使用預設的 ingress 網路建立服務,不需要指定特殊的選項,但需要使用 --publish 或 -p 選項發布埠。以下示例建立了一個 MySQL 服務。
~ $ docker service create \
> --env MYSQL_ROOT_PASSWORD='mysql' \
> --replicas 1 \
> --name mysql \
> --publish published=3306,target=3306 \
> mysql
內容解密:
此命令建立了一個名為 mysql 的服務,並將其埠 3306 發布到 Swarm 叢集的外部。透過 --replicas 1 指定服務的副本數為 1。
自定義 Overlay 網路
除了使用預設的 ingress 網路外,也可以建立自定義的 overlay 網路。
~ $ docker network create --driver overlay my-overlay-net
內容解密:
此命令建立了一個名為 my-overlay-net 的自定義 overlay 網路,用於在 Swarm 叢集內部進行容器間的通訊。
Docker Swarm 網路組態與應用
Docker Swarm 為容器協調提供了強大的網路功能,包括預設的 ingress 網路和自定義的 overlay 網路。ingress 網路主要用於 Swarm 模式下的路由網狀結構,允許所有節點接受對已發布服務的連線請求,即使該服務的任務並未在該節點上執行。自定義 overlay 網路則可用於服務間的通訊。
在 Ingress 網路中建立服務
在 ingress 網路中建立 Docker 服務時,不需要使用 --network 選項指定網路,但必須發布一個埠。以下命令建立了一個名為 hello-world 的服務,並將其埠 80 發布到主機的 8080 埠。
docker service create \
--name hello-world \
-p 8080:80 \
--replicas 3 \
tutum/hello-world
內容解密:
docker service create:建立一個新的服務。--name hello-world:指定服務名稱為hello-world。-p 8080:80:將容器的 80 埠對映到主機的 8080 埠。--replicas 3:指定服務執行 3 個副本。tutum/hello-world:使用的 Docker 映象名稱。
該服務會在 Swarm 中的每個節點上建立一個任務,並可透過任何節點的 <Public DNS>:8080 或負載平衡器的 <LoadBalancer DNS>:8080 存取。
自定義 Overlay 網路
除了預設的 ingress 網路外,還可以建立自定義的 overlay 網路,用於服務間的通訊。建立自定義 overlay 網路時,需要指定 --driver overlay,並可使用 --subnet、--gateway 和 --ip-range 等選項進行詳細組態。
docker network create \
--subnet=192.168.0.0/16 \
--subnet=192.170.0.0/16 \
--gateway=192.168.0.100 \
--gateway=192.170.0.100 \
--ip-range=192.168.1.0/24 \
--driver overlay \
mysql-network
內容解密:
docker network create:建立一個新的網路。--subnet:指定網路的子網。--gateway:指定網路的閘道器。--ip-range:指定網路中分配 IP 的範圍。--driver overlay:指定網路驅動為 overlay。mysql-network:自定義網路的名稱。
自定義 overlay 網路建立後,可以透過 docker network ls 和 docker network inspect 命令檢視其詳細資訊。
docker network ls --filter driver=overlay
docker network inspect mysql-network
內容解密:
docker network ls --filter driver=overlay:列出所有 overlay 網路。docker network inspect mysql-network:檢視mysql-network網路的詳細組態。
新建立的 overlay 網路預設情況下只在管理節點上可見,當有容器使用該網路時,才會擴充套件到工作節點。
Docker Swarm 模式下的網路組態與管理
Docker Swarm 模式提供了一種強大且彈性的網路管理機制,讓開發者能夠輕鬆地在多個節點之間建立和管理容器網路。本章將探討 Docker Swarm 模式下的網路組態,包括自定義 overlay 網路的建立、加密網路的組態,以及內部網路的建立和使用。
自定義 Overlay 網路的建立與擴充套件
在 Docker Swarm 模式下,自定義 overlay 網路允許跨多個節點的容器進行通訊。首先,使用 docker network create 命令建立一個自定義 overlay 網路。
docker network create \
--driver overlay \
--opt encrypted \
overlay-network-2
上述命令建立了一個名為 overlay-network-2 的加密 overlay 網路。Swarm 模式下的 overlay 網路預設是安全的,使用 AES 演算法在 GCM 模式下進行加密和認證。
要將自定義 overlay 網路擴充套件到 worker 節點,需要在該網路中建立一個服務,並在 worker 節點上執行任務。
docker service create \
--env MYSQL_ROOT_PASSWORD='mysql' \
--replicas 1 \
--network mysql-network \
--name mysql-2 \
mysql
內容解密:
--env MYSQL_ROOT_PASSWORD='mysql':設定 MySQL 的 root 密碼環境變數。--replicas 1:指定服務的副本數量為 1。--network mysql-network:將服務連線到名為mysql-network的自定義 overlay 網路。--name mysql-2:指定服務的名稱為mysql-2。mysql:指定要使用的 Docker 映象名稱。
使用自定義 Overlay 網路建立服務
使用自定義 overlay 網路建立服務時,必須指定 --network 選項。這樣可以確保服務的容器能夠加入到指定的網路中。
docker service create \
--env MYSQL_ROOT_PASSWORD='mysql' \
--replicas 1 \
--network mysql-network \
--name mysql-2 \
mysql
內容解密:
- 該命令建立了一個名為
mysql-2的 MySQL 服務,並將其連線到mysql-network網路。 --replicas 1指定了服務的初始副本數量。- 該服務使用
mysql映象,並設定了 root 密碼。
內部 Overlay 網路的建立與使用
內部 overlay 網路不提供外部連線性,這意味著容器不能直接從主機或更廣泛的網際網路存取。要建立一個內部 overlay 網路,可以使用 --internal 選項。
docker network create \
--subnet=10.0.0.0/16 \
--gateway=10.0.0.100 \
--internal \
--label HelloWorldService \
--ip-range=10.0.1.0/24 \
--driver overlay \
hello-world-network
內容解密:
--subnet=10.0.0.0/16:指定網路的子網範圍。--gateway=10.0.0.100:指定網路的閘道器地址。--internal:標記該網路為內部網路,禁止外部連線。--label HelloWorldService:為網路新增標籤。--ip-range=10.0.1.0/24:指定 IP 地址範圍。--driver overlay:指定網路驅動程式為 overlay。
第11章 日誌記錄與監控
Docker 內建多種日誌驅動程式供容器使用,例如 json-file、syslog、journald、gelf、fluentd 和 awslogs。Docker 也提供 docker logs 命令來取得容器的日誌。Docker 1.13 版本包含了一個實驗性功能,允許使用 docker service logs 命令取得 Docker 服務的日誌。
問題描述
Docker Swarm 模式缺乏原生的監控服務來監控 Docker 服務和容器。此外,取得服務日誌的實驗性功能是一個命令列功能,需要針對每個服務執行。缺乏一個能夠收集所有服務的日誌和指標並在儀錶板中檢視的記錄服務。
解決方案
Sematext 是一個整合的資料分析平台,提供 SPM(效能監控)用於收集指標和事件,以及 Logsene 用於收集日誌,包括效能指標、日誌和事件之間的關聯。Logsene 是一個託管的 ELK(Elasticsearch、Logstash、Kibana)堆積疊。需要在 Swarm 中的每個節點上安裝 Sematext Docker Agent,以持續收集日誌、指標和事件,如圖 11-1 所示。
Docker 網路組態與日誌管理
建立內部網路
在 Docker 中,可以建立一個內部網路,使容器之間可以互相通訊,而不允許外部連線。以下是一個建立內部網路並在其中建立服務的範例:
docker service create \
--name hello-world \
--network hello-world-network \
--replicas 3 \
tutum/hello-world
連線測試
取得某個服務任務的容器 ID,例如 d365d4a5ff4c,然後從該容器 ping google.com。
docker exec -it d365d4a5ff4c ping -c 1 google.com
由於容器位於內部網路,因此無法連線到外部網路。
內部網路連線測試
取得同一內部網路中另一個容器的 ID,例如 57e612f35a38,然後從第一個容器 ping 該容器。
docker exec -it d365d4a5ff4c ping -c 1 57e612f35a38
發布埠
如果在建立服務時發布埠(例如 --publish 8080:80),則服務將被新增到入口網路(ingress network),即使它位於內部網路,也會提供外部連線。
docker service create \
--name hello-world \
--network hello-world-network \
--publish 8080:80 \
--replicas 3 \
tutum/hello-world
連線到外部網路
發布埠後,容器可以連線到外部網路。
docker exec -it 1c52804dc256 ping -c 1 google.com
刪除網路
可以使用 docker network rm 命令刪除未使用的網路。
docker network rm hello-world-network mkileuo6ve32 qwgb1lwycgvo overlay-network-2
無法刪除正在使用的網路
如果網路正在被服務使用,則無法刪除。
Error response from daemon: rpc error: code = 9 desc = network mkileuo6ve329jx5xbd1m6r1o is in use by service ocd9sz8qqp2becf0ww2rj5p5nqwgb1lwycgvo