上一篇文章《Docker Swarm 叢集管理利器核心概念掃盲》中我們把 Swarm 重要的概念性知識給大家講解了一波,理論完事就該實戰了,這篇文章帶大家從零開始,搭建 Docker Swarm 叢集環境,并通過 Swarm 實作服務的彈性部署,滾動更新服務及復原服務等功能。
叢集搭建
環境準備
- 五台安裝了 Docker 的 CentOS 機器,版本為:
CentOS 7.8.2003
- Docker Engine 1.12+(最低要求 1.12,本文使用 19.03.12)
- 防火牆開啟以下端口或者關閉防火牆:
- TCP 端口 2377,用于叢集管理通信;
- TCP 和 UDP 端口 7946,用于節點之間通信;
- UDP 端口 4789,用于覆寫網絡。
機器分布
角色 | IP | HOSTNAME | Docker 版本 |
---|---|---|---|
Manager | 192.168.10.101 | manager1 | 19.03.12 |
Manager | 192.168.10.102 | manager2 | 19.03.12 |
Manager | 192.168.10.103 | manager3 | 19.03.12 |
Worker | 192.168.10.10 | worker1 | 19.03.12 |
Worker | 192.168.10.11 | worker2 | 19.03.12 |
- 可以通過
修改機器的主機名(立即生效,重新開機後失效);hostname 主機名
- 或者
修改機器的主機名(立即生效,重新開機也生效);hostnamectl set-hostname 主機名
- 或者
編輯 hosts 檔案,如下所示, 給 127.0.0.1 添加主機名(重新開機生效)。vi /etc/hosts
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 manager1
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
建立叢集
在任意節點下通過
docker swarm init
指令建立一個新的 Swarm 叢集并加入,且該節點會預設成為 Manager 節點。根據我們預先定義的角色,在 101 ~ 103 的任意一台機器上運作該指令即可。
通常,第一個加入叢集的管理節點将成為
Leader
,後來加入的管理節點都是
Reachable
。目前的 Leader 如果挂掉,所有的 Reachable 将重新選舉一個新的 Leader。
[[email protected] ~]# docker swarm init --advertise-addr 192.168.10.101
Swarm initialized: current node (clumstpieg0qzzxt1caeazg8g) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-5ob7jlej85qsygxubqypjuftiwruvew8e2cr4u3iuo4thxyrhg-3hbf2u3i1iagurdprl3n3yra1 192.168.10.101:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
加入叢集
Docker 中内置的叢集模式自帶了公鑰基礎設施(PKI)系統,使得安全部署容器變得簡單。叢集中的節點使用傳輸層安全協定(TLS)對叢集中其他節點的通信進行身份驗證、授權和加密。
預設情況下,通過
docker swarm init
指令建立一個新的 Swarm 叢集時,Manager 節點會生成新的根證書頒發機構(CA)和密鑰對,用于保護與加入群集的其他節點之間的通信安全。
Manager 節點會生成兩個令牌,供其他節點加入叢集時使用:一個 Worker 令牌,一個 Manager 令牌。每個令牌都包括根 CA 證書的摘要和随機生成的密鑰。當節點加入群集時,加入的節點使用摘要來驗證來自遠端管理節點的根 CA 證書。遠端管理節點使用密鑰來確定加入的節點是準許的節點。
Manager
若要向該叢集添加 Manager 節點,管理節點先運作
docker swarm join-token manager
指令檢視管理節點的令牌資訊。
docker swarm join-token manager
然後在其他節點上運作
docker swarm join
并攜帶令牌參數加入 Swarm 叢集,該節點角色為 Manager。
Worker
通過建立叢集時傳回的結果可以得知,要向這個叢集添加一個 Worker 節點,運作下圖中的指令即可。或者管理節點先運作
docker swarm join-token worker
指令檢視工作節點的令牌資訊。
然後在其他節點上運作
docker swarm join
并攜帶令牌參數加入 Swarm 叢集,該節點角色為 Worker。
檢視叢集資訊
在任意 Manager 節點中運作
docker info
可以檢視目前叢集的資訊。
檢視叢集節點
在任意 Manager 節點中運作
docker node ls
可以檢視目前叢集節點資訊。
*
代表目前節點,現在的環境為 3 個管理節點構成 1 主 2 從,以及 2 個工作節點。
節點
MANAGER STATUS
說明:表示節點是屬于 Manager 還是 Worker,沒有值則屬于 Worker 節點。
-
:該節點是管理節點中的主節點,負責該叢集的叢集管理和編排決策;Leader
-
:該節點是管理節點中的從節點,如果 Leader 節點不可用,該節點有資格被選為新的 Leader;Reachable
-
:該管理節點已不能與其他管理節點通信。如果管理節點不可用,應該将新的管理節點加入群集,或者将工作節點更新為管理節點。Unavailable
節點
AVAILABILITY
說明:表示排程程式是否可以将任務配置設定給該節點。
-
:排程程式可以将任務配置設定給該節點;Active
-
:排程程式不會将新任務配置設定給該節點,但現有任務仍可以運作;Pause
-
:排程程式不會将新任務配置設定給該節點,并且會關閉該節點所有現有任務,并将它們排程在可用的節點上。Drain
删除節點
Manager
删除節點之前需要先将該節點的
AVAILABILITY
改為
Drain
。其目的是為了将該節點的服務遷移到其他可用節點上,確定服務正常。最好檢查一下容器遷移情況,確定這一步已經處理完成再繼續往下。
docker node update --availability drain 節點名稱|節點ID
然後,将該 Manager 節點進行降級處理,降級為 Worker 節點。
docker node demote 節點名稱|節點ID
然後,在已經降級為 Worker 的節點中運作以下指令,離開叢集。
docker swarm leave
最後,在管理節點中對剛才離開的節點進行删除。
docker node rm 節點名稱|節點ID
Worker
删除節點之前需要先将該節點的
AVAILABILITY
改為
Drain
。其目的是為了将該節點的服務遷移到其他可用節點上,確定服務正常。最好檢查一下容器遷移情況,確定這一步已經處理完成再繼續往下。
docker node update --availability drain 節點名稱|節點ID
然後,在準備删除的 Worker 節點中運作以下指令,離開叢集。
docker swarm leave
最後,在管理節點中對剛才離開的節點進行删除。
docker node rm 節點名稱|節點ID
服務部署
注意:跟叢集管理有關的任何操作,都是在 Manager 節點上操作的。
建立服務
下面這個案例,使用 nginx 鏡像建立了一個名為 mynginx 的服務,該服務會被随機指派給一個工作節點運作。
docker service create --replicas 1 --name mynginx -p 80:80 nginx
-
:建立服務;docker service create
-
:指定一個服務有幾個執行個體運作;--replicas
-
:服務名稱。--name
檢視服務
可以通過
docker service ls
檢視運作的服務。
[[email protected] ~]# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
hepx06k5ik5n mynginx replicated 1/1 nginx:latest *:80->80/tcp
可以通過
docker service inspect 服務名稱|服務ID
檢視服務的詳細資訊。
[[email protected] ~]# docker service inspect mynginx
[
{
"ID": "k0dbjg1zzy3l3g71kdwa56ect",
"Version": {
"Index": 127
},
"CreatedAt": "2020-09-16T10:05:55.627974095Z",
"UpdatedAt": "2020-09-16T10:05:55.629507771Z",
"Spec": {
"Name": "mynginx",
"Labels": {},
"TaskTemplate": {
"ContainerSpec": {
"Image": "nginx:[email protected]:c628b67d21744fce822d22fdcc0389f6bd763daac23a6b77147d0712ea7102d0",
"Init": false,
"StopGracePeriod": 10000000000,
"DNSConfig": {},
"Isolation": "default"
},
"Resources": {
"Limits": {},
"Reservations": {}
},
"RestartPolicy": {
"Condition": "any",
"Delay": 5000000000,
"MaxAttempts": 0
},
"Placement": {
"Platforms": [
{
"Architecture": "amd64",
"OS": "linux"
},
{
"OS": "linux"
},
{
"OS": "linux"
},
{
"Architecture": "arm64",
"OS": "linux"
},
{
"Architecture": "386",
"OS": "linux"
},
{
"Architecture": "mips64le",
"OS": "linux"
},
{
"Architecture": "ppc64le",
"OS": "linux"
},
{
"Architecture": "s390x",
"OS": "linux"
}
]
},
"ForceUpdate": 0,
"Runtime": "container"
},
"Mode": {
"Replicated": {
"Replicas": 1
}
},
"UpdateConfig": {
"Parallelism": 1,
"FailureAction": "pause",
"Monitor": 5000000000,
"MaxFailureRatio": 0,
"Order": "stop-first"
},
"RollbackConfig": {
"Parallelism": 1,
"FailureAction": "pause",
"Monitor": 5000000000,
"MaxFailureRatio": 0,
"Order": "stop-first"
},
"EndpointSpec": {
"Mode": "vip",
"Ports": [
{
"Protocol": "tcp",
"TargetPort": 80,
"PublishedPort": 80,
"PublishMode": "ingress"
}
]
}
},
"Endpoint": {
"Spec": {
"Mode": "vip",
"Ports": [
{
"Protocol": "tcp",
"TargetPort": 80,
"PublishedPort": 80,
"PublishMode": "ingress"
}
]
},
"Ports": [
{
"Protocol": "tcp",
"TargetPort": 80,
"PublishedPort": 80,
"PublishMode": "ingress"
}
],
"VirtualIPs": [
{
"NetworkID": "st2xiy7pjzap093wz4w4u6nbs",
"Addr": "10.0.0.15/24"
}
]
}
}
]
可以通過
docker service ps 服務名稱|服務ID
檢視服務運作在哪些節點上。
在對應的任務節點上運作
docker ps
可以檢視該服務對應容器的相關資訊。
調用服務
接下來我們測試一下服務是否能被正常通路,并且該叢集下任意節點的 IP 位址都要能通路到該服務才行。
測試結果:5 台機器均可正常通路到該服務。
彈性服務
将 service 部署到叢集以後,可以通過指令彈性擴縮容 service 中的容器數量。在 service 中運作的容器被稱為 task(任務)。
通過
docker service scale 服務名稱|服務ID=n
可以将 service 運作的任務擴縮容為 n 個。
通過
docker service update --replicas n 服務名稱|服務ID
也可以達到擴縮容的效果。
将 mynginx service 運作的任務擴充為 5 個:
[[email protected] ~]# docker service scale mynginx=5
mynginx scaled to 5
overall progress: 5 out of 5 tasks
1/5: running [==================================================>]
2/5: running [==================================================>]
3/5: running [==================================================>]
4/5: running [==================================================>]
5/5: running [==================================================>]
verify: Service converged
通過
docker service ps 服務名稱|服務ID
檢視服務運作在哪些節點上。
我們再來一波縮容的操作,指令如下:
[[email protected] ~]# docker service update --replicas 3 mynginx
mynginx
overall progress: 3 out of 3 tasks
1/3: running [==================================================>]
2/3: running [==================================================>]
3/3: running [==================================================>]
verify: Service converged
通過
docker service ps 服務名稱|服務ID
檢視服務運作在哪些節點上。
在 Swarm 叢集模式下真正意義實作了所謂的彈性服務,動态擴縮容一行指令搞定,簡單、便捷、強大。
删除服務
通過
docker service rm 服務名稱|服務ID
即可删除服務。
[[email protected] ~]# docker service rm mynginx
mynginx
[[email protected] ~]# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
滾動更新及復原
以下案例将示範 Redis 版本如何滾動更新至更高版本再復原至上一次的操作。
首先,建立 5 個 Redis 服務副本,版本為 5,詳細指令如下:
# 建立 5 個副本,每次更新 2 個,更新間隔 10s,20% 任務失敗繼續執行,超出 20% 執行復原,每次復原 2 個
docker service create --replicas 5 --name redis \
--update-delay 10s \
--update-parallelism 2 \
--update-failure-action continue \
--rollback-monitor 20s \
--rollback-parallelism 2 \
--rollback-max-failure-ratio 0.2 \
redis:5
-
:定義滾動更新的時間間隔;--update-delay
-
:定義并行更新的副本數量,預設為 1;--update-parallelism
-
:定義容器啟動失敗之後所執行的動作;--update-failure-action
-
:定義復原的監控時間;--rollback-monitor
-
:定義并行復原的副本數量;--rollback-parallelism
-
:任務失敗復原比率,超過該比率執行復原操作,0.2 表示 20%。--rollback-max-failure-ratio
然後通過以下指令實作服務的滾動更新。
docker service update --image redis:6 redis
復原服務,隻能復原到上一次操作的狀态,并不能連續復原到指定操作。
docker service update --rollback redis
常用指令
docker swarm
指令 | 說明 |
---|---|
docker swarm init | 初始化叢集 |
docker swarm join-token worker | 檢視工作節點的 token |
docker swarm join-token manager | 檢視管理節點的 token |
docker swarm join | 加入叢集 |
docker node
指令 | 說明 |
---|---|
docker node ls | 檢視叢集所有節點 |
docker node ps | 檢視目前節點所有任務 |
docker node rm 節點名稱|節點ID | 删除節點( 強制删除) |
docker node inspect 節點名稱|節點ID | 檢視節點詳情 |
docker node demote 節點名稱|節點ID | 節點降級,由管理節點降級為工作節點 |
docker node promote 節點名稱|節點ID | 節點更新,由工作節點更新為管理節點 |
docker node update 節點名稱|節點ID | 更新節點 |
docker service
指令 | 說明 |
---|---|
docker service create | 建立服務 |
docker service ls | 檢視所有服務 |
docker service inspect 服務名稱|服務ID | 檢視服務詳情 |
docker service logs 服務名稱|服務ID | 檢視服務日志 |
docker service rm 服務名稱|服務ID | 删除服務( 強制删除) |
docker service scale 服務名稱|服務ID=n | 設定服務數量 |
docker service update 服務名稱|服務ID | 更新服務 |
參考資料
- https://docs.docker.com/engine/swarm/swarm-tutorial/
- https://docs.docker.com/engine/swarm/swarm-mode/
- https://docs.docker.com/engine/swarm/how-swarm-mode-works/pki/
- https://docs.docker.com/engine/swarm/join-nodes/
- https://docs.docker.com/engine/swarm/swarm-tutorial/rolling-update/
本文采用
知識共享「署名-非商業性使用-禁止演繹 4.0 國際」許可協定
。
大家可以通過
分類
檢視更多關于
Docker
的文章。
🤗 您的
點贊
和
轉發
是對我最大的支援。
📢 掃碼關注
哈喽沃德先生
「文檔 + 視訊」每篇文章都配有專門視訊講解,學習更輕松噢 ~