跳至主要内容

7.3 Docker Swarm 指令

這邊將帶大家使用一些在 Swarm 模式下常見的指令,並且熟悉 Swarm 模式的運作方式。

下方的指令可以列出目前的 Swarm 中有幾個節點,也會有關於這個節點的資訊,是 Manager 還是 Worker;以及該節點的 Docker 版本為何。

$ docker node list
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
ne5c... doc.... Ready Active Leader 20.10.17

還記得在一開始我們執行了 docker swarm init 之後,會產生一段特別的 Token 讓我們可以把其他的機器加入 Swarm 成為節點。

但若不是在執行 docker swarm init 時加入電腦,而是運作了一段時間後,需要加入新節點該怎麼做呢?

可以透過 docker swarm join-token 這個指令,後方可以放 manager 或是 worker 兩個參數,就會產生 Token 讓我們可以加新的機器到 Swarm 之中。

$ docker swarm join-token manager/worker
To add a manager/worker to this swarm, run the following command:

docker swarm join --token SWMTKN-1-1mmrll6hucyytwlv3p06lvbap84ihgm2rquql0952mhloczirw-en5o6gf8igzu4syt9g0vmeol8 192.168.65.3:2377

還記得前幾個章節中,我們在使用容器時,若是要更新容器的設定,都需要重新啟動容器以便新的設定可以套用到容器內。

而在 Swarm 模式下的 Service 已經不需要這麼做了,可以使用 docker service update 的指令,讓 Swarm 幫我們更新設定以及重啟容器,且中間完全不會有任何的空檔出現。

意思是即使在正式環境中,也可以在有使用者的情形下更新服務,而使用者不會察覺更新的異狀。

例如下方指令,可以在原先啟動的 nginx Service 內添加環境變數:

$ docker service update --env-add NAME=robert nginx
nginx
overall progress: 3 out of 3 tasks
1/3: running [=============================================>]
2/3: running [=============================================>]
3/3: running [=============================================>]
verify: Service converged

還可以透過 docker service ps 的指令來看到 Swarm 替換容器的過程:

$ docker service ps nginx
ID NAME IMAGE NODE DES... CURRE... ERROR PORTS
m7l9... nginx.1 nginx desktop Running Runn....
m2z.... \_ nginx.1 nginx desktop Running Shut....
hwy.... nginx.2 nginx desktop Running Runn....
s2d.... \_ nginx.2 nginx desktop Running Shut....
2bn.... nginx.3 nginx desktop Running Runn....
oxd.... \_ nginx.3 nginx desktop Running Shut....

透過終端機畫面可以很清楚的看出來有三個舊的容器被替換掉了,而當然也要來驗證看看環境變數是否有真的如同預期一般進入新的容器內。

$ docker container list
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
8152c....... nginx "/dock..." 6 mi... Up... 80/tcp nginx.1
a783c....... nginx "/dock..." 6 mi... Up... 80/tcp nginx.2
74552....... nginx "/dock..." 6 mi... Up... 80/tcp nginx.3

接著我們像以前一樣進入其中一個容器:

$ docker container exec --interactive --tty 8152 bash
root@8152cc109eae:/# echo $NAME
robert

環境變數確實新增了,這是怎麼辦到的呢?

Service 的滾動更新

Docker Swarm 預設更新 Service 的模式是先從編號 1 容器開始關閉,並且再啟動擁有新設定的編號 1 容器,接著才是編號 2,以此類推,所以在無時無刻都會有 nginx 服務的容器存在,服務才不會斷檔。

這時候你或許會有疑問,那是因為這個 Service 有三個副本,才能夠做到服務不斷檔,但我的 Service 若是只有一個副本呢?

這時候就可以使用 --update-order 這個參數,我們可以告訴 Swarm,我們希望更新時的順序,這邊 Docker 官方有兩種設定,分別是 start-first 以及 stop-first。

而 start-first 則和前面提到的更新模式不同,不會先關閉編號 1 的容器,而是先製作一個擁有新設定的編號 1 容器,才關閉舊的編號 1 容器,這邊一樣可以使用前面有介紹到的 watch 套件來觀看,在 docker container list 時會發現,突然變成 4 個 nginx 的容器,接著又變成 3 個。

至於 stop-first 則和預設的行為一樣,採取先關閉,後啟動的方式。

其實更新還有非常多的參數可以嘗試,在之後我們會寫得更加詳細,這邊是希望大家對於 Service 能夠更有概念一些,在 Swarm 的模式下,可以想像成一個功能更強的容器,雖然不一樣,但在一開始進入到 Swarm 時可以用這樣的思維去使用,才不會覺得綁手綁腳。

刪除 Service

接著來結束 Service 的生命週期吧!

$ docker service rm nginx
nginx

最棒的是,Swarm 還會自動幫我們把容器加上 --rm 的指令,也就是我們在結束 Service 後,並不需要擔心滿山滿谷的停止容器佔據硬碟。

整個 Swarm 模式下的指令雖然看似變多變複雜,但使用習慣後,就如同使用容器一樣,而且多了更多可以設定的參數,下一個小節我們將會利用 DigitalOcean 來嘗試建立一個小型的叢集,不然一直在本機上嘗試好像都沒有真的看到 Swarm 的方便之處。