Docker Swarm 集群
本文檔介紹了 Docker Swarm 集群的基本概念、工作原理以及相關命令使用示例,包括如何在服務調度中使用自定義標簽。本文檔適用于需要管理和擴展 Docker 容器化應用程序的生產環境場景。
1. 什么是 Docker Swarm
Docker Swarm 是用于管理 Docker 集群的原生工具,從 Docker 1.12.0 版本開始,Swarm 已經內置于 Docker 引擎中。Swarm 可以將多臺 Docker 主機組織成一個統一的虛擬主機,使用戶能夠輕松部署、管理和擴展容器化應用程序。
官方文檔:Docker Swarm Overview
2. 與 Docker Compose 的區別
- Docker Compose:適用于單節點環境,通過定義
docker-compose.yml
文件快速搭建和調試容器化應用。 - Docker Swarm:專為生產環境設計,支持多節點集群管理和容器編排,還能實現零宕機滾動更新、彈性伸縮等高級功能。
3. Docker Swarm 的工作原理
3.1 基本概念
-
節點 (Node)
集群中的每個 Docker 主機都被稱為一個節點。節點分為兩種角色:- Manager 節點:負責集群的管理與控制,集群中可以有多個 Manager,但只有一個 Manager 被選舉為 Leader。
- Worker 節點:用于運行任務,由 Manager 分配任務后執行相應的容器操作。
-
多重身份
一個節點可以同時扮演 Manager 和 Worker 的角色。 -
Raft 協議
使用 Raft 協議選舉 Manager Leader 并同步狀態信息,要求至少兩個 Manager 參與選舉。
3.2 工作流程
-
集群初始化
使用docker swarm init
命令初始化集群,執行節點自動成為 Manager(通常也是 Leader)。 -
節點加入
其他 Docker 主機通過 Manager 節點分配的 token 加入集群,并被授予 Manager 或 Worker 角色。 -
服務定義
通過定義服務來描述容器應用程序,并由 Manager 將任務分配到合適的節點。任務是 Swarm 中最小的調度單位,而一個服務是多個任務的集合。 -
調度策略
Manager 節點按照調度策略(spread、binpack、random)選擇合適的節點部署服務實例。 -
容器編排
Manager 負責執行創建、啟動、停止、重啟等操作,保證應用程序持續高可用運行。
4. Swarm 集群管理
4.1 集群節點準備
角色 | IP | Hostname |
---|---|---|
Manager1 | 172.16.10.110 | manager1 |
Manager2 | 172.16.10.111 | manager2 |
Worker1 | 172.16.10.120 | worker1 |
Worker2 | 172.16.10.121 | worker2 |
4.2 初始化集群
在 Manager1 上執行以下命令:
docker swarm init --advertise-addr 172.16.10.110
執行成功后,輸出中會顯示用于其他節點加入集群的 token。注意:
- 參數
--advertise-addr
用于指定通信的 IP 地址(默認端口為 2377),在多網卡環境下建議指定。
查看 token:
docker swarm join-token manager # 查看管理節點 token
docker swarm join-token worker # 查看工作節點 token
4.3 節點加入
-
加入 Manager2
在 Manager2 上執行(請替換<manager_token>
與對應的廣播地址):docker swarm join --advertise-addr <Manager2_IP> --token <manager_token> 172.16.10.110:2377
-
加入 Worker1 和 Worker2
分別在 Worker 節點上執行:docker swarm join --advertise-addr <Worker_IP> --token <worker_token> 172.16.10.110:2377
在 Manager1 上使用 docker node ls
查看當前集群狀態。
4.4 集群解散
要將節點退出并從集群移除:
-
在目標節點上執行:
docker swarm leave [--force] # Manager 節點退出需加 --force
-
在 Manager 節點上刪除該節點:
docker node rm <節點名稱>
5. 節點管理
以下命令需在 Manager 節點上執行(Worker 節點無操作權限):
-
查看集群所有節點
docker node ls
-
查看指定節點詳情
docker node inspect <節點名稱> --pretty
-
節點升級與降級
bash復制編輯docker node promote <節點名稱> # 將 Worker 升級為 Manager docker node demote <節點名稱> # 將 Manager 降級為 Worker
-
節點下線(暫停任務調度)
docker node update --availability drain <節點名稱>
-
節點上線
docker node update --availability active <節點名稱>
6. 服務管理
6.1 服務定義
創建服務時常用的命令格式如下:
bash復制編輯docker service create --name <服務名> \[-d] [-p] [-e] [--network] [--replicas] [--mount] \image:tag
示例
-
測試 1:指定副本數、端口映射
docker service create -d --name web-nginx --replicas 2 -p 80:80 nginx
-
測試 2:傳遞環境變量
bash復制編輯docker service create -d --name mysql --replicas=1 \-p 3306:3306 \-e MYSQL_ROOT_PASSWORD=123456 \-e MYSQL_DATABASES=test \mysql:5.7
6.2 服務查看
-
查看所有服務:
docker service ls
-
查看指定服務及其任務分布:
docker service ps <服務名>
示例輸出:
docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
0jlt1yx8dcox mysql replicated 1/1 mysql:5.7 *:3306->3306/tcp
fxha9cy659vu web-nginx replicated 3/3 nginx:1.24.0 *:80->80/tcpdocker service ps mysql
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
wit44m5i6plf mysql.1 mysql:5.7 master Running Running 3 minutes ago
6.3 服務移除
docker service rm <服務名稱>
6.4 服務模式及調度
-
服務模式
- Replicated 模式(默認):在指定節點上運行多個副本。
- Global 模式:在每個節點上都運行一個副本(適合日志收集、監控等場景)。
示例:
docker service create --name cadvisor --mode global \--mount type=bind,src=/,dst=/rootfs,readonly \--mount type=bind,src=/var/run,dst=/var/run \--mount type=bind,src=/sys,dst=/sys,readonly \--mount type=bind,src=/var/lib/docker/,dst=/var/lib/docker,readonly \--publish 8888:8080 \gcr.io/cadvisor/cadvisor:latest
-
調度約束
通過指定調度約束,可以控制服務任務只在符合要求的節點上運行。
-
根據節點主機名調度:
docker service create --name my-service \--constraint 'node.hostname == node01' \nginx:latest
-
根據自定義標簽調度:
-
給節點添加自定義 Label
在 Manager 節點上執行(假設給 node01 添加
hm=node01
):docker node update --label-add hm=node01 node01
查看節點標簽:
docker node inspect node01 --pretty
-
使用標簽調度創建服務
docker service create --name my-service \--constraint 'node.labels.hm == node01' \nginx:latest
在
docker-compose.yml
文件中也可通過deploy.placement.constraints
設置:version: '3.8' services:web:image: nginx:latestdeploy:replicas: 1placement:constraints:- "node.labels.hm == node01"ports:- "80:80"
部署命令:
docker stack deploy -c docker-compose.yml mystack
-
-
-
移除節點標簽
docker node update --label-rm hm node01
6.5 服務日志
查看服務日志:
docker service logs <服務名>
7. Swarm 集群的彈性伸縮
彈性伸縮指動態增加或減少服務任務數。
-
創建服務時指定副本數
docker service create -d --name mysql --replicas=2 \-p 3306:3306 \-e MYSQL_ROOT_PASSWORD=123456 \mysql:5.7
-
在線伸縮命令
-
使用 update 命令:
docker service update --replicas <新副本數> <服務名>
-
或者使用 scale 命令:
docker service scale <服務名>=<副本數>
-
8. Swarm 集群服務的滾動更新
滾動更新允許在不中斷服務的情況下更新服務。常用于灰度發布與鏡像升級。
8.1 更新命令示例
例如升級 MySQL 服務鏡像版本,從 v5.7 到 v8.0,同時調整副本數量:
docker service update --replicas 5 \--image mysql:8.0 \--update-delay 60s \--update-parallelism 5 \mysql
參數說明:
--update-delay
:指定滾動更新每個任務之間的延時(支持秒、分鐘、小時)。--update-parallelism
:指定同時更新的任務數。
8.2 鏡像版本回退
有兩種方式:
-
方式一:使用 rollback 命令
docker service rollback mysql
此命令會回滾到上次成功部署的狀態。
-
方式二:手動指定舊版本進行更新
docker service update --image mysql:5.7 mysql
-
查看更新狀態
docker service inspect --pretty mysql
輸出中
UpdateConfig
部分會顯示當前服務的更新狀態,例如rollback_completed
表示已回滾。
9. 使用 Docker Compose 部署 Swarm 集群
9.1 docker service create
的局限
該命令一次只能創建一個服務,多個服務時較為繁瑣,因此推薦使用 Compose 文件配合 docker stack deploy
部署整個應用堆棧。
9.2 Docker Compose 文件中的 Swarm 配置
在 Compose 文件中,可在 deploy
下配置與 Swarm 相關的屬性。請注意,使用 docker-compose up
時會忽略 deploy
部分,因此必須通過 docker stack deploy
部署。
示例:
yaml復制編輯version: '3.8'
services:web:image: nginx:latestdeploy:replicas: 2 # 服務副本數mode: replicated # 服務模式:replicated(默認)或 globalplacement:constraints:- "node.hostname == node01" # 根據主機名調度- "node.labels.hm == node01" # 根據自定義標簽調度restart_policy:condition: on-failure # 僅在容器異常退出時重啟delay: 10s # 嘗試重啟的間隔時間max_attempts: 3 # 最大重啟嘗試次數ports:- "80:80"
9.3 部署 Stack
使用以下命令部署堆棧:
docker stack deploy -c docker-compose.yml mystack
-
查看堆棧列表:
docker stack ls
-
查看堆棧服務:
docker stack services mystack
-
查看堆棧任務:
docker stack ps mystack
-
刪除堆棧:
docker stack rm mystack