Docker Swarm 日常運維命令筆記

散盡浮華發表於2018-11-12

 

之前介紹了Docker管理工具-Swarm部署記錄,這裡簡單總結下Docker Swarm的日常維護命令,以作為平時運維筆記.

Swarm作為一個管理Docker叢集的工具,首先需要將其部署起來,可以單獨將Swarm部署於一個節點。另外,自然需要一個Docker叢集,叢集上每一個節點均安裝有Docker。具體的Swarm架構圖可以參照下圖:

Swarm架構中最主要的處理部分自然是Swarm節點,Swarm管理的物件自然是Docker Cluster,Docker Cluster由多個Docker Node組成,而負責給Swarm傳送請求的是Docker Client。Swarm架構圖可以讓大家對Swarm有一個初步的認識,比如Swarm的具體工作流程:Docker Client傳送請求給Swarm;Swarm處理請求併傳送至相應的Docker Node;Docker Node執行相應的操作並返回響應。除此之外,Swarm的工作原理依然還不夠明瞭。深入理解Swarm的工作原理,可以先從Swarm提供的命令入手。Swarm支援的命令主要有4個:swarm create、swarm manage、swarm join、swarm list。當然還有一個swarm help命令,該命令用於指導大家如何正確使用swarm命令.

swarm create
Swarm中swarm create命令用於建立一個叢集標誌,用於Swarm管理Docker叢集時,Docker Node的節點發現功能。發起該命令之後,Swarm會前往Docker Hub上內建的發現服務中獲取一個全球唯一的token,用以唯一的標識Swarm管理的Docker叢集。

swarm manage
Swarm中swarm manage是最為重要的管理命令。一旦swarm manage命令在Swarm節點上被觸發,則說明使用者需要swarm開始管理Docker叢集。從執行流程的角度來講,swarm經歷的階段主要有兩點:啟動swarm、接收並處理Docker叢集管理請求。

Swarm啟動的過程包含三個步驟:
► 發現Docker叢集中的各個節點,收集節點狀態、角色資訊,並監視節點狀態的變化;
► 初始化內部排程(scheduler)模組;
► 建立並啟動API監聽服務模組;

第一個步驟,Swarm發現Docker叢集中的節點。發現(discovery)是Swarm中用於維護Docker叢集狀態的機制。既然涉及到發現(discovery),那在這之前必須先有註冊(register)。Swarm中有專門負責發現(discovery)的模組,而關於註冊(register)部分,不同的discovery模式下,註冊(register)也會有不同的形式。

目前,Swarm中提供了5種不同的發現(discovery)機制:Node Discovery、File Discovery、Consul Discovery、EtcD Discovery和Zookeeper Discovery。

第二個步驟,Swarm內部的排程(scheduler)模組被初始化。swarm通過發現機制發現所有註冊的Docker Node,並收集到所有Docker Node的狀態以及具體資訊。此後,一旦Swarm接收到具體的Docker管理請求,Swarm需要對請求進行處理,並通過所有Docker Node的狀態以及具體資訊,來篩選(filter)決策到底哪些Docker Node滿足要求,並通過一定的策略(strategy)將請求轉發至具體的一個Docker Node。

第三個步驟,Swarm建立並初始化API監聽服務模組。從功能的角度來講,可以將該模組抽象為Swarm Server。需要說明的是:雖然Swarm Server完全相容Docker的API,但是有不少Docker的命令目前是不支援的,畢竟管理Docker叢集與管理單獨的Docker會有一些區別。當Swarm Server被初始化並完成監聽之後,使用者即可以通過Docker Client向Swarm傳送Docker叢集的管理請求。

Swarm的swarm manage接收並處理Docker叢集的管理請求,即是Swarm內部多個模組協同合作的結果。請求入口為Swarm Server,處理引擎為Scheduler,節點資訊依靠Disocovery。

swarm join
Swarm的swarm join命令用於將Docker Node新增至Swarm管理的Docker叢集中。從這點也可以看出swarm join命令的執行位於Docker Node,因此在Docker Node上執行該命令,首先需要在Docker Node上安裝Swarm,由於該Swarm只會執行swarm join命令,故可以將其當成Docker Node上用於註冊的agent模組。

功能而言,swarm join可以認為是完成Docker Node在Swarm節點處的註冊(register)工作,以便Swarm在執行swarm manage時可以發現該Docker Node。然而,上文提及的5種discovery模式中,並非每種模式都支援swarm join命令。不支援的discovery的模式有Node Discovery與File Discovery。

Docker Node上swarm join執行之後,標誌著Docker Node向Swarm註冊,請求加入Swarm管理的Docker叢集中。Swarm通過註冊資訊,發現Docker Node,並獲取Docker Node的狀態以及具體資訊,以便處理Docker請求時作為排程依據。

swarm list
Swarm中的swarm list命令用以列舉Docker叢集中的Docker Node。Docker Node的資訊均來源於Swarm節點上註冊的Docker Node。而一個Docker Node在Swarm節點上註冊,僅僅是註冊了Docker Node的IP地址以及Docker監聽的埠號。

使用swarm list命令時,需要指定discovery的型別,型別包括:token、etcd、file、zk以及。而swarm list並未羅列Docker叢集的動態資訊,比如Docker Node真實的執行狀態,或者Docker Node在Docker叢集中扮演的角色資訊。

==========================下面簡單梳理了一些日常運維中用到的Swarm相關命令=============================

1) 初始化swarm manager並制定網路卡地址
# docker swarm init --advertise-addr 182.48.115.237

2) 刪除叢集,強制退出需要加–force (針對manager節點). 到各個節點上執行退出叢集的命令
# docker node rm swarm-node1     
# docker swarm leave --force      //manager節點退出叢集,需要加--force

3) 檢視swarm worker的連線令牌
# docker swarm join-token worker

例如:
[root@manager-node ~]# docker swarm init --advertise-addr 182.48.115.237
Swarm initialized: current node (1gi8utvhu4rxy8oxar2g7h6gr) is now a manager.
 
To add a worker to this swarm, run the following command:
 
    docker swarm join \
    --token SWMTKN-1-4roc8fx10cyfgj1w1td8m0pkyim08mve578wvl03eqcg5ll3ig-f0apd81qfdwv27rnx4a4y9jej \
    182.48.115.237:2377
 
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.

4)  加入docker swarm叢集,作為worker節點
利用上面執行結果中的命令放在其他節點上執行,則該節點加入到swarm叢集中作為worker節點
[root@node1 ~]# docker swarm join --token SWMTKN-1-4roc8fx10cyfgj1w1td8m0pkyim08mve578wvl03eqcg5ll3ig-f0apd81qfdwv27rnx4a4y9jej 182.48.115.237:2377
This node joined a swarm as a worker.

5) 檢視swarm manager的連線令牌
# docker swarm join-token manager

例如:
[root@swarm-manager-node ~]# docker swarm join-token manager
To add a manager to this swarm, run the following command:

    docker swarm join \
    --token SWMTKN-1-075gaitl18z3v0p37sx7i5cmvzjjur0fbuixzp4tun0xh0cikd-0y8ttp5h0g54j10amn670w6su \
    172.16.60.220:2377

6) 加入docker swarm叢集,作為manager節點
利用上面執行結果中的命令放在其他節點上執行,則該節點加入到swarm叢集中作為manager管理節點,狀態為reachable. 
[root@swarm-manager-node2 ~]# docker swarm join --token SWMTKN-1-075gaitl18z3v0p37sx7i5cmvzjjur0fbuixzp4tun0xh0cikd-0y8ttp5h0g54j10amn670w6su 172.16.60.220:2377
This node joined a swarm as a manager.

[root@swarm-manager-node2 ~]# docker node ls
ID                                                HOSTNAME                  STATUS      AVAILABILITY  MANAGER STATUS
rpbey5t1v14olke2mgtc430de     swarm-node2                 Ready        Active        
u6gkfr4j19gq16ddyb76fxsl3       swarm-node1                 Ready        Active        
vwbb0imil512a1le04bnkx98u *   swarm-manager-node    Ready       Active                      Leader
ybjvaszg838upeqvvzswhq0tt       swarm-manager-node2  Ready       Active                      Reachable

如果之前的leader狀態的manager管理節點掛了後(假如systemctl stop docker, 然後再systemctl start docker),
則新加入的manager節點狀態由reachable變為leader, 之前的manager節點狀態為unreachable.
[root@swarm-manager-node2 ~]# docker node ls
ID                                                HOSTNAME                  STATUS      AVAILABILITY  MANAGER STATUS
rpbey5t1v14olke2mgtc430de     swarm-node2                 Ready        Active        
u6gkfr4j19gq16ddyb76fxsl3       swarm-node1                 Ready        Active        
vwbb0imil512a1le04bnkx98u *   swarm-manager-node    Ready       Active                      Unreachable
ybjvaszg838upeqvvzswhq0tt       swarm-manager-node2  Ready       Active                      Leader

7) 使舊令牌無效並生成新令牌
# docker swarm join-token --rotate

8) 檢視叢集中的節點
# docker node ls

9) 檢視叢集中節點資訊
# docker node inspect swarm-node1 --pretty

10) 排程程式可以將任務分配給節點
# docker node update --availability active swarm-node1

11) 排程程式不向節點分配新任務,但是現有任務仍然保持執行
# docker node update --availability pause swarm-node1

12) 排程程式不會將新任務分配給節點。排程程式關閉任何現有任務並在可用節點上安排它們. 也就是線下節點,不參與任務分配.
# docker node update --availability drain swarm-node1

13) 新增節點標籤
# docker node update --label-add label1 --label-add bar=label2 swarm-node1

14) 刪除節點標籤
# docker node update --label-rm label1 swarm-node1

15) 將worker節點升級為manager節點
# docker node promote swarm-node1

16) 將manager節點降級為worker節點
# docker node demote swarm-manager-node

17) 檢視服務列表
# docker service ls

18) 檢視服務的具體資訊
# docker service ps my-test

19) 建立一個不定義name,不定義replicas的服務. (如下的nginx是docker的nginx映象名稱,不是服務名稱)
# docker service create nginx

20) 建立一個指定name的服務
# ocker service create --name my-nginx nginx

21) 建立一個指定name、run cmd的服務
# docker service create --name my-nginx nginx ping www.baidu.com

22) 建立一個指定name、version、run cmd的服務
# docker service create --name my-redis redis:3.0.6
# docker service create --name my-nginx nginx:1.8 /bin/bash

23) 建立一個指定name、port、replicas的服務
# docker service create --name my-nginx --replicas 3 -p 80:80 nginx

24) 為指定的服務更新一個埠
# docker service update --publish-add 80:80 my-nginx

25) 為指定的服務刪除一個埠
# docker service update --publish-rm 80:80 my-nginx

26) 將redis:3.0.6更新至redis:3.0.7
# docker service update --image redis:3.0.7 redis

27) 配置執行環境,指定工作目錄及環境變數
# docker service create --name my-nginx --env MYVAR=myvalue --workdir /data/www --user my_user nginx ping www.baidu.com

28) 建立一個my-nginx的服務
# docker service create --name my-nginx nginx ping www.baidu.com

29) 更新my-nginx服務的執行命令
# docker service update --args "ping www.baidu.com" my-nginx

30) 刪除一個服務
# docker service rm my-nginx

31) 在每個群組節點上執行web服務
# docker service create --name tomcat --mode global --publish mode=host,target=8080,published=8080 tomcat:latest

32) 建立一個overlay網路
# docker network create --driver overlay my-network
# docker network create --driver overlay --subnet 10.10.10.0/24 --gateway 10.10.10.1 haha-network

33) 建立服務並將網路新增至該服務
# docker service create --name my-test --replicas 3 --network my-network redis

34) 刪除群組網路
# docker service update --network-rm my-network my-test

35) 更新群組網路
# docker service update --network-add haha-network my-test

36) 建立群組並配置cpu和記憶體
# docker service create --name my_nginx --reserve-cpu 2 --reserve-memory 512m --replicas 3 nginx

37) 更改所分配的cpu和記憶體
# docker service update --reserve-cpu 1 --reserve-memory 256m my_nginx

38) 建立服務時自定義的幾個引數
指定每次更新的容器數量
--update-parallelism

指定容器更新的間隔
--update-delay

定義容器啟動後監控失敗的持續時間
--update-monitor 

定義容器失敗的百分比
--update-max-failure-ratio

定義容器啟動失敗之後所執行的動作
--update-failure-action

比如:建立一個服務並執行3個副本,同步延遲10秒,10%任務失敗則暫停
# docker service create --name mysql_5_6_36 --replicas 3 --update-delay 10s --update-parallelism 1 --update-monitor 30s --update-failure-action pause --update-max-failure-ratio 0.1 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.6.36

39) 回滾至之前版本
# docker service update --rollback mysql

自動回滾 
如果服務部署失敗,則每次回滾2個任務,監控20秒,回滾可接受失敗率20%
# docker service create --name redis --replicas 6 --rollback-parallelism 2 --rollback-monitor 20s --rollback-max-failure-ratio .2 redis:latest

40) 建立服務並將目錄掛在至container中
# docker service create --name mysql --publish 3306:3306 --mount type=bind,src=/data/mysql,dst=/var/lib/mysql --replicas 3 -e MYSQL_ROOT_PASSWORD=123456 mysql:5.6.36

需要注意使用bind繫結宿主機目錄會帶來的風險 
- 繫結的主機路徑必須存在於每個叢集節點上,否則會有問題;
- 排程程式可能會在任何時候重新安排執行服務容器,如果目標節點主機變得不健康或無法訪問;
- 主機繫結資料不可移植,當你繫結安裝時,不能保證你的應用程式開發方式與生產中的執行方式相同;

41) 新增swarm配置
# echo "this is a mysql config" | docker config create mysql -

42) 檢視配置
# docker config ls

檢視配置詳細資訊
# docker config inspect mysql

43) 刪除配置
# docker config rm mysql

44) 新增配置
# docker service update --config-add mysql mysql

45) 刪除配置
# docker service update --config-rm mysql mysql

46) 新增配置
# docker config create kevinpage index.html

47) 啟動容器的同時新增配置(target如果報錯,就使用dst或destination)
# docker service create --name nginx --publish 80:80 --replicas 3 --config src=kevinpage,target=/usr/share/nginx/html/index.html nginx 

相關文章