本文來源
翻譯並總結官方文檔,添加自定義示例,參考自Docker 19.03版本官方文檔
未來可能歸檔為:https://docs.docker.com/v19.03/
2020.01.03為https://docs.docker.com/engine/swarm/
本文目標
本文主要演示創建一個小規模的Swarm集群,包含一個管理節點與兩個工作節點,概念可以參考https://www.cnblogs.com/hellxz/p/12134386.html
- 創建Docker Swarm集群
- 添加節點
- 部署應用服務
- 管理Swarm集群
環境說明
- 三台安裝Docker的Linux虛擬機:本文用Docker Machine創建虛擬機
- Docker版本:18.09.7,理論上1.12版本以后均可
- 三台虛擬機網絡互通
Docker Machine安裝參考我的上一篇文章,安裝Docker Machine
虛擬機准備
實體機安裝Linux或Mac,跳過此節
本文通過一台Linux虛擬機中創建三個虛擬機節點來操作的,虛擬機內存可以開大些,另外需要配置開啟Intel VT-x/EPT或AMD-RVI(V)

另外,由於我們要做的實驗是在虛擬機下的再創建虛擬機,外部虛擬機與虛擬機內構成內網,在沒有設置代理的情況下,我們無法直接通過瀏覽器直接訪問
創建 Swarm 集群(Create a swarm)
創建一個管理節點的虛擬機
$ docker-machine create -d virtualbox manager

連接創建的管理節點虛擬機
$ docker-machine ssh manager1

出現上圖已經進入虛擬機了
初始化Swarm集群
$ docker swarm init --advertise-addr 192.168.99.100

初始化完成,在多網卡的情況下,必須使用--advertise-addr指定IP,其它主機必須可以訪問此ip,輸出中包含新節點加入此節點的命令,我們只需要復制此命令到其它節點上執行
執行
docker swarm init的節點自動成為管理節點,節點的ip是ssh到節點后ifconfig查到的添加節點命令要先復制出來,一會添加節點會用,如果沒復制也不要緊
在manager節點輸入docker swarm join-token 角色 就能提示token了,上邊復制的默認是worker角色的命令
輸入docker info查看當前節點的Docker Swarm Mode已經處於激活狀態了

執行docker node ls查看當前Swarm集群中節點的情況

*指示當前登錄的節點
輸出exit退出當前登錄的主機
向Swarm添加節點(Add nodes to the swarm)
創建第一個工作節點並ssh連接到這個節點上
$ docker-machine create -d virtualbox worker1
$ docker-machine ssh worker1

執行剛才復制的docker swarm join-token命令,忘了就先去manager節點下執行docker swarm join-token worker來查看命令
$ docker swarm join --token SWMTKN-1-0kr7tkx9ku4rcrl1lny1o8chg9xl24h4nexmz1ctfwz43425uq-egecegeyfaet0volcvo15zia8 192.168.99.100:2377
This node joined a swarm as a worker.
接着創建個worker2,操作不再復述了
查看集群節點情況
連接manager節點,執行命令查看集群狀態
$ docker node ls

docker node ls命令僅可以在管理節點使用
部署服務到Swarm集群(Deployed a service)
部署服務只需要使用docker service create加正常的docker命令,還可以指定創建幾個備份實例,這里部署2個Nginx
$ docker service create --replicas 2 --name nginx -p 80:80 nginx:mainline-alpine

docker service create命令主要參數:
--name- 用來指定服務名,部署服務的容器名使用這個名稱作為前綴--replicas- 設置負載實例數其余參數請自行參考
docker service create --help文檔此命名僅能在manager節點執行
在Docker Swarm Mode簡介與核心概念 一文中,我們有談過:服務可以運行在Manager節點上,也可以運行在Worker節點上
部署服務的輸出並沒有提示具體將服務部署到哪個節點上,接下來我們看看節點情況
查看服務
使用docker service ls查看服務列表,查看具體服務部署在哪個節點使用docker service ps 服務名

如圖,我們的服務一個部署到了manger節點上,一個部署在worker1節點上
檢查部署在Swarm集群中的服務(Inspect the service)
通過docker service inspect命令檢查服務的詳細信息,使用--pretty使輸出更易讀
$ docker service inspect --pretty nginx

除了這種簡單的方法外就是普通的辦法——去部署的節點上docker ps 🐻
服務伸縮(Scale the service)
使用docker service scale命令來對服務進行擴大或縮小實例數
當業務壓力攀升時,我們需要對服務進行橫向擴容,添加更多的實例,就可以像下邊這么做
$ docker service scale nginx=5
=左邊是服務名,右邊是負載數

業務壓力下降時只需調小負載數的值
刪除服務(Delete the service)
使用docker service rm命名來刪除服務,包含服務包含的所有Task都會被刪除
$ docker service rm nginx

滾動升級服務(Apply rolling updates)
一般升級服務的方式是停服再啟動新的服務這種方式,有些人習慣將原服務刪除,再部署新的,當新的服務有問題,想回退上一版本時就傻眼了
在Docker部署服務的情況下,我們可以自己手動docker stop容器再創建新的部署新的容器,這樣雖然看起來沒問題,但是手動操作一方面是很大重復勞動,另一方面人工也容易誤操作
在這種情況下,Docker Swarm為我們准備了docker service update命令來更新服務,一方面簡單更新操作,另一方面提供回滾的命令,這個稍后會提及
關於服務更新的配置有兩種:
- 一種是在初次部署服務時就指定的配置,比如在
docker service create時添加參數--update-delay+時延來設置每個服務的Task間的延遲,--update-parallelism設置更新時最大並行部署數值,--update-failure-action標記更新失敗要做的動作 等- 另一種就是
docker service update時指定參數,上邊舉例的三個參數此命令也可以使用以上提到的參數在例子中就不寫了
剛才已經把nginx的服務干掉了,我們再創建部署一個nginx服務
$ docker service create --replicas 2 --name nginx -p 80:80 nginx:mainline-alpine
查看下當前服務鏡像,一會我們通過命令修改鏡像版本

我們更新下nginx服務的鏡像版本,格式為docker service update --image 鏡像 服務名
$ docker service update --image nginx:alpine nginx

再查看下nginx服務

我們發現鏡像的版本已經改變了
使用docker service ps nginx查看服務情況

我們發現之前版本的Task還有保留,只是狀態為Shutdown
保留的Task可以用於后續如果服務不正常,回滾版本
docker service update更多操作請參考--help文檔
服務回退
使用docker service rollback命令對服務進行一鍵回退
$ docker service rollback nginx

回退成功,如上圖我還執行的查看服務命令,發現之前升級與回退的版本都還在,層次也比較清晰
排除節點(Drain a node on the swarm)
當我們部署服務的時候,Manager節點會將Task分發到所有狀態為ACTIVE 的節點上,執行Task
當需要維護一個節點的時候,你一定不會希望還有Task被分配到此節點上,Swarm的設計者也考慮到這點,除了ACTIVE狀態外,還有一個DRAIN 狀態用來標識當前節點(Node)不再提供服務,你也別給我這發Task了
使用docker node update --availability drain 節點名來完成此功能
$ docker node update --availability drain worker1

上圖先是查看了當前nginx服務部署在worker1與manager節點上,接着下線了worker1
我們發現Manger將原來部署在worker1的節點下線,重新在worker2節點上部署了nginx的task
可能上圖中對node的狀態描述不直觀,執行docker node ls或許更清楚些😄

上線與之相反,設置drain為active即可,docker node update --availability active 節點名
使用swarm模式路由網格(Use swarm mode routing mesh)
簡單來說是使用Swarm模式的網絡路由,將服務指定端口暴露出去提供服務
有點類似於
-p 8080:80這種寫法,按官網的說法是:分隔的寫法是舊版本的寫法😙 ,因為新版本更靈活易讀
看了下文檔,把我認為最關鍵的先拋出來
暴露端口(Publish a port for a service)
Swarm中暴露接口有兩種情況,一種是創建服務時暴露,另一種是服務已經存在,需要暴露
創建服務時暴露端口
$ docker service create \
--name <SERVICE-NAME> \
--publish published=<PUBLISHED-PORT>,target=<CONTAINER-PORT> \
<IMAGE>
更新服務時暴露接口
$ docker service update \
--publish-add published=<PUBLISHED-PORT>,target=<CONTAINER-PORT> \
<IMAGE>

分流路由(Bypass the routing mesh)
官方文檔這塊沒看明白,大意是使用節點的host模式網絡繞過路由網格
$ docker service create --name dns-cache \
--publish published=53,target=53,protocol=udp,mode=host \
--mode global \
dns-cache
TODO: 待完善,如您有清晰的概念,還請留言解惑,在此先行感謝
配置外部負載均衡器(Configure an external load balancer)
相信我貼一張圖就明白了,就是配置個負載均衡配置到Node節點的特定端口上,此端口相對於容器暴露的端口作映射

本文是官網翻譯文檔,如有錯誤與不准確處,希望讀者可以留言與本人探討

