1. 程式人生 > >Docker Swarm 集群(十七)

Docker Swarm 集群(十七)

docker swarm

一、Docker Swarm 概念

1、集群

從主機的層面來看,Docker Swarm 管理的是 Docker Host 集群。所以先來討論一個重要的概念 - 集群化(Clustering)。

服務器集群由一組網絡上相互連接的服務器組成,它們一起協同工作。一個集群和一堆服務器最顯著的區別在於:
集群能夠像 單個 系統那樣工作,同時提供高可用、負載均衡和並行處理。

如果我們部署應用和服務時選擇的是多個獨立的服務器而非集群,資源的整體利用率則很難達到最優,因為我們無法提前知道如何分布這些應用才能達到資源利用的最大化。而且,應用使用資源的趨勢是波動的,早上某些服務可能需要大量的內存,而下午使用量就降下來了。提前指定應用應該運行在哪個服務器上會喪失業務的彈性,當某個服務器宕機了,我們不得不手工將受影響的應用遷移到其他服務器上。

實現集群化後我們的思維方式就必須改變了:不再考慮一個一個的服務器,而是將集群看做是一個整體。

部署應用時,我們只考慮需要多少內存和 CPU,而不是考慮會使用那臺服務器的內存和 CPU。我們不應該關心應用會被部署在哪裏,我們關心的是運行這個應用需要哪些資源,然後將它部署到集群,集群管理程序(比如 Docker Swarm)會搞定這些細節。

集群整體容量的調整是通過往集群中添加和刪除主機節點實現的。但不管做怎樣的操作,集群始終還是一個整體。

2、Docker Swarm

Docker v1.12 是一個非常重要的版本,Docker 重新實現了集群的編排方式。在此之前,提供集群功能的 Docker Swarm 是一個單獨的軟件,而且依賴外部數據庫(比如 Consul、etcd 或 Zookeeper)。

從 v1.12 開始,Docker Swarm 的功能已經完全與 Docker Engine 集成,要管理集群,只需要啟動 Swarm Mode。安裝好 Docker,Swarm 就已經在那裏了,服務發現也在那裏了(不需要安裝 Consul 等外部數據庫)。

3、重要概念

swarm

swarm 是運行 Docker Engine 的多個主機組成的集群。

從 v1.12 開始,集群管理和編排功能已經集成進 Docker Engine。當 Docker Engine 初始化了一個 swarm 或者加入到一個存在的 swarm 時,它就啟動了 swarm mode。

沒啟動 swarm mode 時,Docker 執行的是容器命令;運行 swarm mode 後,Docker 增加了編排 service 的能力。

Docker 允許在同一個 Docker 主機上既運行 swarm service,又運行單獨的容器。

node

swarm 中的每個 Docker Engine 都是一個 node,有兩種類型的 node:manager 和 worker。

為了向 swarm 中部署應用,我們需要在 manager node 上執行部署命令,manager node 會將部署任務拆解並分配給一個或多個 worker node 完成部署。

manager node 負責執行編排和集群管理工作,保持並維護 swarm 處於期望的狀態。swarm 中如果有多個 manager node,它們會自動協商並選舉出一個 leader 執行編排任務。

woker node 接受並執行由 manager node 派發的任務。默認配置下 manager node 同時也是一個 worker node,不過可以將其配置成 manager-only node,讓其專職負責編排和集群管理工作。

work node 會定期向 manager node 報告自己的狀態和它正在執行的任務的狀態,這樣 manager 就可以維護整個集群的狀態。

service

service 定義了 worker node 上要執行的任務。swarm 的主要編排任務就是保證 service 處於期望的狀態下。

舉一個 service 的例子:在 swarm 中啟動一個 http 服務,使用的鏡像是 httpd:latest,副本數為 3。

manager node 負責創建這個 service,經過分析知道需要啟動 3 個 httpd 容器,根據當前各 worker node 的狀態將運行容器的任務分配下去,比如 worker1 上運行兩個容器,worker2 上運行一個容器。

運行了一段時間,worker2 突然宕機了,manager 監控到這個故障,於是立即在 worker3 上啟動了一個新的 httpd 容器。

這樣就保證了 service 處於期望的三個副本狀態。

二、創建 Swarm 集群

1、環境準備

所有節點的 Docker 版本均不低於 v1.12,我們是最新版的 v18.04,我們的實驗環境 node 的操作系統為 Ubuntu 16.04,當然其他 Linux 也是可以的。

swarm-manager:192.168.1.200
swarm-worker1:192.168.1.201
swarm-worker1:192.168.1.203

2、創建 swarm

在 swarm-manager 上執行如下命令創建 swarm,使用命令docker swarm init --advertise-addr 192.168.1.200

[root@master ~]# docker swarm init --advertise-addr 192.168.1.200
Swarm initialized: current node (udbgr7vn9x5gntpqbj8m82x7l) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join         --token SWMTKN-1-22q5qlm1mxbilt504ghcf0ug9gsn9a40szbhiohyh9kqiayyku-a8crg1xr8vab1vwrh7kmsy3kw         192.168.1.200:2377

To add a manager to this swarm, run ‘docker swarm join-token manager‘ and follow the instructions.

從結果輸出我們可以看出 manager 已經初始化完成,swarm-manager 成為 manager node,可以看到添加 worker node 和 manager node 的執行指令。

--advertise-addr:指定與其他 node 通信的地址。

3、添加 node

執行 docker node ls 查看當前 swarm 的 node,目前只有一個 manager。

[root@master ~]# docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
udbgr7vn9x5gntpqbj8m82x7l *   master              Ready               Active              Leader              18.04.0-ce

如果當時沒有記錄下 docker swarm init 提示的添加 worker 的完整命令,可以通過docker swarm join-token worker查看。

復制前面的 docker swarm join命令,在 swarm-worker1 和 swarm-worker2 上執行,將它們添加到 swarm 中。

但是出現如下問題:

技術分享圖片

這是因為我們在之前配置多主機網絡的時候,添加的配置,我們現在需要取消掉這兩個參數。

--cluster-advertise:是用來指定集群與其他node的通信地址的。
--cluster-store:是我之前做網絡實驗的時候配置了etcd集群的通信地址用的。

技術分享圖片

去掉之後,重啟docker,host1 和 host2 即可添加了。

技術分享圖片

root@host2:~# docker swarm join > --token SWMTKN-1-22q5qlm1mxbilt504ghcf0ug9gsn9a40szbhiohyh9kqiayyku-a8crg1xr8vab1vwrh7kmsy3kw > 192.168.1.200:2377
This node joined a swarm as a worker.

4、查看添加結果

docker node ls可以看到兩個 worker node 已經添加進來了。

[root@master ~]# docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
c1scfpzw4s9hx1ykiggzs5qym     host1               Ready               Active                                  18.04.0-ce
6cwk70xzafhfwn1x3replywn7     host2               Ready               Active                                  18.04.0-ce
udbgr7vn9x5gntpqbj8m82x7l *   master              Ready               Active              Leader              18.04.0-ce

至此,三節點的 swarm 集群就已經搭建好了,操作還是相當簡單的。

三、Docker Service

1、創建 service

我們創建好了 Swarm 集群, 現在部署一個運行 httpd 鏡像的 service,執行如下命令:

[root@master ~]# docker service create --name web_server httpd
gjy6az3urqsbktichzoz6vpdh
overall progress: 1 out of 1 tasks 
1/1: running   [==================================================>] 
verify: Service converged 

2、查看

通過 docker service ls 可以查看當前 swarm 中的 service。

[root@master ~]# docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
gjy6az3urqsb        web_server          replicated          1/1                 httpd:latest        

REPLICAS 顯示當前副本信息,1/1 的意思是 web_server 這個 service 期望的容器副本數量為 1,目前已經啟動的副本數量為 1。也就是當前 service 已經部署完成。
命令 docker service ps可以查看 service 每個副本的狀態。

[root@master ~]# docker service ps gjy6az3urqsb
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE           ERROR               PORTS
b86hi4ivf855        web_server.1        httpd:latest        master              Running             Running 3 minutes ago                       

我們可以看到 service 被分配到了 master 上面。

3、service scale up

前面部署了只有一個副本的 Service,不過對於 web 服務,我們通常會運行多個實例。這樣可以負載均衡,同時也能提供高可用。

swarm 要實現這個目標非常簡單,增加 service 的副本數就可以了。在 swarm-manager 上執行如下命令:

[root@master ~]# docker service scale web_server=5
web_server 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

副本數增加到 5,通過 docker service lsdocker service ps web_server查看副本的詳細信息。

技術分享圖片

我們可以看到 manager 上面運行了兩個副本,默認配置下 manager node 也是 worker node,所以 swarm-manager 上也運行了副本。如果不希望在 manager 上運行 service,可以執行如下命令:

docker node update --availability drain master

技術分享圖片

我們可以看到 master 上面的副本已經轉移了。

4、service scale down

前面我們的場景是 scale up,我們還可以 scale down,減少副本數,運行下面的命令:

[root@master ~]# docker service scale web_server=3
web_server scaled to 3
overall progress: 3 out of 3 tasks 
1/3: running   [==================================================>] 
2/3:   
3/3: running   [==================================================>] 
verify: Service converged 

技術分享圖片

我們可以看到目前 host1 上面運行了一個副本,host2 上面運行了兩個副本。

Docker Swarm 集群(十七)