Docker Swarm 提供了原生網路功能,簡化了容器間的通訊。透過 overlay 網路,不同主機上的容器如同在同一個區域網路內,可以直接透過容器名稱互相存取。文章中以 books-ms 服務為例,示範瞭如何使用 Docker Compose 定義服務網路,並透過 docker network create 建立 overlay 網路。同時,也說明瞭如何透過 Consul 查詢服務地址,以及如何使用 docker exec 進入容器驗證網路設定。此外,文章也詳細介紹瞭如何使用 Docker Swarm 擴充套件和縮減服務,並透過 docker ps 命令檢視容器佈署狀態。最後,文章還介紹瞭如何結合 Ansible 和 Jenkins,實作 Docker Swarm 的自動化佈署,並說明瞭藍綠佈署策略的應用。
使用 Docker Swarm 進行服務叢集與擴充套件
服務間的網路連線組態
在前面的章節中,我們探討瞭如何使用 Docker Compose 來佈署服務。現在,我們將深入瞭解如何利用 Docker Swarm 進行服務的叢集與擴充套件。首先,我們來看看服務之間的網路連線是如何組態的。
環境變數與 Docker 網路
當我們執行 docker exec -it books-ms env 命令時,可以看到一系列環境變數被設定。其中,DB_HOST 被設定為 books-ms-db。這表明我們的服務使用了 Docker 網路來進行容器間的通訊。
docker exec -it books-ms env
輸出結果如下:
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=eb3443a66355
DB_HOST=books-ms-db
DB_DBNAME=books
DB_COLLECTION=books
HOME=/root
使用 Docker Compose 指定網路
在 docker-compose-swarm.yml 檔案中,我們指定了 net 引數來定義網路。這樣,Docker Compose 就會為我們的服務建立一個新的網路。
app:
image: 10.100.198.200:5000/books-ms
ports:
- 8080
net: books-ms
environment:
- SERVICE_NAME=books-ms
- DB_HOST=books-ms-db
db:
container_name: books-ms-db
image: mongo
net: books-ms
environment:
- SERVICE_NAME=books-ms-db
建立網路並執行容器
在執行容器之前,我們先建立一個名為 books-ms 的網路。
docker network create books-ms
docker-compose -f docker-compose-swarm.yml up -d db app
驗證網路組態
執行 docker network ls 命令,可以看到 books-ms 網路已經被成功建立。
docker network ls
輸出結果如下:
NETWORK ID NAME DRIVER
6e5f816d4800 swarm-node-1/host host
aa1ccdaefd70 swarm-node-2/docker_gwbridge bridge
cd8b1c3d9be5 swarm-node-2/none null
ebcc040e5c0c swarm-node-1/bridge bridge
6768bad8b390 swarm-node-1/docker_gwbridge bridge
8ebdbd3de5a6 swarm-node-1/none null
58a585d09bbc books-ms overlay
de4925ea50d1 swarm-node-2/bridge bridge
2b003ff6e5da swarm-node-2/host host
驗證容器內的主機檔案組態
進入容器並檢視 /etc/hosts 檔案,可以看到主機名 books-ms-db 已經被正確解析。
docker exec -it booksms_app_1 bash
cat /etc/hosts
exit
輸出結果如下:
10.0.0.2 3166318f0f9c
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
10.0.0.3 books-ms-db
10.0.0.3 books-ms-db.my-network
測試服務功能
透過 Consul 取得服務的 IP 和埠,並傳送 PUT 和 GET 請求來測試服務是否正常運作。
ADDRESS=`curl \
10.100.192.200:8500/v1/catalog/service/books-ms \
| jq -r '.[0].ServiceAddress + ":" + (.[0].ServicePort | tostring)'`
curl -H 'Content-Type: application/json' -X PUT -d \
'{"_id": 2,
"title": "My Second Book",
"author": "John Doe",
"description": "A bit better book"}' \
$ADDRESS/api/v1/books | jq '.'
curl $ADDRESS/api/v1/books | jq '.'
輸出結果如下:
[
{
"author": "John Doe",
"title": "My Second Book",
"_id": 2
}
]
使用 Docker Swarm 進行服務擴充套件
Docker Swarm 允許我們輕鬆地在叢集中擴充套件服務。現在,我們將 books-ms 服務擴充套件到三個例項。
Docker Swarm 的優勢
- 利用 Docker 網路實作容器間的通訊。
- 支援跨主機的容器佈署。
- 可透過 Docker Compose 檔案定義服務和網路。
- 能夠動態地擴充套件或縮減服務例項數量。
#### 內容解密:
上述指令展示瞭如何使用Docker Swarm進行服務佈署和擴充套件。首先,我們透過docker network create建立了一個overlay型別的網路books-ms,使得不同主機上的容器可以互相通訊。然後,使用docker-compose -f docker-compose-swarm.yml up -d db app命令啟動了資料函式庫和應用程式服務。接著,透過檢查網路組態和容器內的主機檔案,確認了容器間的網路連線正常。最後,透過向Consul查詢服務地址並傳送HTTP請求,驗證了跨主機佈署的服務能夠正常運作。整個流程展現了Docker Swarm在多主機環境下佈署和管理容器的能力。
叢集與擴充套件服務
在前面的章節中,我們已經瞭解瞭如何使用 Docker Swarm 來佈署和擴充套件服務。本文將探討如何根據保留的 CPU 和記憶體來排程容器。
擴充套件服務
首先,讓我們來擴充套件 books-ms 服務到三個例項。
docker-compose -f docker-compose-swarm.yml scale app=3
接著,使用 docker ps 命令來檢視目前執行的容器。
docker ps --filter name=books --format "table {{.Names}}"
輸出結果
NAMES
swarm-node-2/booksms_app_3
swarm-node-1/booksms_app_2
swarm-node-2/books-ms-db
swarm-node-1/booksms_app_1
從輸出結果中,我們可以看到 Swarm 均勻地分配容器到不同的節點上。目前,每個節點執行兩個容器。由於我們要求 Docker Swarm 將 books-ms 容器擴充套件到三個,因此兩個容器執行在不同的節點上,而第三個容器與資料函式庫一起佈署。
內容解密:
docker-compose scale app=3:將app服務擴充套件到三個例項。docker ps --filter name=books --format "table {{.Names}}":列出名稱包含books的容器,並以表格形式顯示容器名稱。
縮減服務
服務也可以輕易地縮減。例如,當流量下降時,我們可能希望釋放資源給其他服務。
docker-compose -f docker-compose-swarm.yml scale app=1
內容解密:
docker-compose scale app=1:將app服務縮減到一個例項。- Swarm 將移除多餘的容器例項,只保留一個執行中的例項。
根據保留的 CPU 和記憶體排程容器
預設情況下,Swarm 會將容器佈署到執行容器數量最少的伺服器上。然而,在實際情況中,並非所有容器都需要相同的資源。我們可以透過指定所需的 CPU 和記憶體來進一步最佳化 Swarm 的佈署。
檢視目前節點狀態
docker info
輸出結果(相關部分)
...
Nodes: 2
swarm-node-1: 10.100.192.201:2375
└ Containers: 2
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 1.535 GiB
...
swarm-node-2: 10.100.192.202:2375
└ Containers: 2
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 1.535 GiB
...
內容解密:
docker info:顯示 Docker 的相關資訊,包括節點狀態。- 目前兩個節點都沒有保留任何 CPU 或記憶體。
使用 CPU 和記憶體限制佈署容器
讓我們嘗試執行一個 MongoDB 容器,並保留一個 CPU 給該程式。
docker run -d --cpu-shares 1 --name db1 mongo
輸出結果(相關部分)
...
Nodes: 2
swarm-node-1: 10.100.192.201:2375
└ Status: Healthy
└ Containers: 3
└ Reserved CPUs: 1 / 1
└ Reserved Memory: 0 B / 1.535 GiB
...
swarm-node-2: 10.100.192.202:2375
└ Status: Healthy
└ Containers: 2
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 1.535 GiB
...
內容解密:
docker run -d --cpu-shares 1 --name db1 mongo:執行一個 MongoDB 容器,並保留一個 CPU 給該容器。- 由於每個節點只有一個 CPU,因此 Swarm 將該容器佈署到
swarm-node-1上。
使用記憶體限制佈署容器
我們也可以使用記憶體作為限制條件。例如,佈署一個保留一個 CPU 和一 GB 記憶體的容器。
docker run -d --cpu-shares 1 -m 1g --name db1 mongo
輸出結果(相關部分)
...
Nodes: 2
swarm-node-1: 10.100.192.201:2375
└ Status: Healthy
└ Containers: 3
└ Reserved CPUs: 1 / 1
└ Reserved Memory: 1 GiB / 1.535 GiB
...
swarm-node-2: 10.100.192.202:2375
└ Status: Healthy
└ Containers: 2
└ Reserved CPUs: 0 / 1
└ Reserved Memory: 0 B / 1.535 GiB
...
內容解密:
docker run -d --cpu-shares 1 -m 1g --name db1 mongo:執行一個 MongoDB 容器,並保留一個 CPU 和一 GB 記憶體給該容器。- Swarm 將該容器佈署到
swarm-node-1上,並保留相應的資源。
本章節展示瞭如何使用 Docker Swarm 對服務進行擴充套件和縮減,以及如何根據 CPU 和記憶體限制來排程容器的佈署。這些功能使得在叢集中管理容器變得更加靈活和高效。
自動化佈署與 Docker Swarm 及 Ansible 的整合應用
在前面的章節中,我們已經探討了 Docker Swarm 的基本操作與叢集管理,接下來將深入討論如何結合 Ansible 自動化工具來實作佈署自動化。
準備環境:Jenkins 與 Ansible 的整合
首先,我們需要利用 Ansible 來佈建我們的 cd 節點並安裝 Jenkins。
ansible-playbook /vagrant/ansible/jenkins-node-swarm.yml \
-i /vagrant/ansible/hosts/prod
ansible-playbook /vagrant/ansible/jenkins.yml \
-c local
內容解密:
ansible-playbook命令用於執行 Ansible 指令碼。/vagrant/ansible/jenkins-node-swarm.yml是用於設定 Jenkins 節點的 playbook。-i /vagrant/ansible/hosts/prod指定了 inventory 檔案的位置,定義了目標主機。- 第二個命令則是在本地執行 Jenkins 的設定。
Jenkins Workflow 與 Docker Swarm 的整合
Jenkins Workflow 提供了一個靈活的方式來定義佈署流程。我們將探討 books-ms-swarm 這個 Job 的設定。
node("cd") {
def serviceName = "books-ms"
def prodIp = "10.100.192.200"
def proxyIp = "10.100.192.200"
def proxyNode = "swarm-master"
def registryIpPort = "10.100.198.200:5000"
def swarmPlaybook = "swarm.yml"
def proxyPlaybook = "swarm-proxy.yml"
def instances = 1
def flow = load "/data/scripts/workflow-util.groovy"
git url: "https://github.com/vfarcic/${serviceName}.git"
flow.provision(swarmPlaybook)
flow.provision(proxyPlaybook)
flow.buildTests(serviceName, registryIpPort)
flow.runTests(serviceName, "tests", "")
flow.buildService(serviceName, registryIpPort)
def currentColor = flow.getCurrentColor(serviceName, prodIp)
def nextColor = flow.getNextColor(currentColor)
flow.deploySwarm(serviceName, prodIp, nextColor, instances)
flow.runBGPreIntegrationTests(serviceName, prodIp, nextColor)
flow.updateBGProxy(serviceName, proxyNode, nextColor)
flow.runBGPostIntegrationTests(serviceName, prodIp, proxyIp, proxyNode, currentColor, nextColor)
}
內容解密:
node("cd")指定了執行該 Workflow 的節點。- 定義了一系列變數,例如服務名稱、生產 IP、代理 IP 等。
- 載入了一個共用的 Groovy 指令碼
workflow-util.groovy,該指令碼封裝了許多佈署相關的函式。 - 使用
git命令從 GitHub 提取程式碼。 - 呼叫
provision函式執行 Ansible playbook 來佈建 Swarm 叢集和設定代理伺服器。 - 編譯、測試、建置服務,並進行藍綠佈署。
Docker Swarm 的佈署策略
在 Docker Swarm 中,我們可以透過不同的策略來控制服務的佈署。預設情況下,Swarm 會根據節點的資源狀況來決定在哪個節點上佈署容器。
docker ps --filter name=db --format "table {{.Names}}"
內容解密:
docker ps命令用於列出正在執行的容器。--filter name=db表示只顯示名字中包含db的容器。--format "table {{.Names}}"指定了輸出的格式,只顯示容器的名稱。