1. 程式人生 > >"三劍客”之Swarm集群架構、集群管理 、服務管理

"三劍客”之Swarm集群架構、集群管理 、服務管理

swarm swarm集群 docker集群 swarm服務管理 甘兵

1.前言

?在看過筆者之前關於Docker的文章後,我相信大家對Docker的內功心法以及對Docker相關武器都有了深刻的認識。在企業玩玩Docker大家也不成問題。但是呢,這些心法和武器往往還是不夠了。

?因為,在Docker應用越來越深入的時代,把調度粒度停在單個容器上是非常沒有效率的。同樣地,在提高對Docker宿主機管理效率和利用率的方向上,選擇集群化管理方式才是正常的道路。我們是時候從更高的抽象層次上來使用Dokcer了,Swarm和Kubernetes將來滿足我們的願景和需求。
技術分享圖片

然而,本文的重點內容在於分享Swarm;可能有些朋友會問,為什麽不分享一下Kubernetes呢,別著急。常言道:路得一步一步走,飯要一口一口吃。Kubernetes比較難理解,所以咋們先把Swarm玩明白了之後在來玩Kubernetes會順暢很多。

2.swarm概念

?Swram是Docker公司推出的官方容器集群平臺,基於go語言實現,代碼開源在 https://github.com/docker/swarm .2016年2月對架構進行重新設計,推出了v2版本,支持超過1千個節點。作為容器集群管理器,Swarm最大的優勢之一就是100%支持標準的Docker API及工具(如Compose,docker-py等),Docker本身就可以很好地與Swarm進行集成。

?我們來看下Swarm做了什麽?試想一下目前操作docker集群的方式,用戶必須單獨對每一個容器執行命令,如下圖所示:
技術分享圖片

?有了Swarm後,使用多臺Docker宿主機的方式就變成了如下圖的形式:

技術分享圖片

2.1.swarm集群

技術分享圖片
從上圖可以看出,Swarm有兩個角色(Manager、agent(也可稱為worker)),簡單說一下這兩個角色的作用:

  • Manager:接收客戶端服務定義,將任務發送到agnet節點,維護集群期望狀態和集群管理功能以及leader選舉。默認情況下manager節點也會運行任務,也可以配置只做管理任務。
  • agent:接收並執行從管理節點分配的任務,並報告任務當前的狀態,以便Manager節點維護每個服務期望狀態。

從上圖還可以看出,Manager收到的請求可發細分為4大類:

  1. 第一類,針對已創建容器的操作,Swarm只是起到一個轉發請求到特定宿主機的作用。
  2. 第二類,
    針對Docker鏡像的操作。
  3. 第三類,創建新的容器docker create這一命令,其中涉及的集群調度會在下面的內容中分享;
  4. 第四類,其他獲取集群整體信息的操作,比如獲取所有容器信息、查看Docker版本等。

2.2swarm集群調度策略

?Swarm管理了多臺Docker宿主機,用戶在這些宿主機上創建容器時,究竟會與哪臺宿主機產生交互呢?

2.2.1 Filter

Swarm提供了Filter(篩選)的功能,用來幫助用戶篩選出符合他們條件的宿主機。
Filters分兩類:節點過濾器和容器過濾器。

節點過濾器:以Docker Deamon的配置或Docker主機的特性為條件進行過濾的,它包括:

  • constraint
  • health

容器過濾器:以Docker容器的配置作為條件過濾,它包括:

  • affinity
  • dependency
  • port

下面用個場景為例,用戶需要將一個MYSQL名為db的容器部署到一臺裝有固態硬盤的宿主機上。裝有固態硬盤的宿主機在啟動Docker服務時會使用下面的命令來添加適當的標簽信息:

# docker run -d -p 3306:3306 -e constraint:storage=ssd  --name db mysql

?constraint環境變量會被Manager解析,然後篩選出所有帶有storage:ssd這一鍵/值對標簽的宿主機作為備選。用戶還可以用environment:test、environment:production來區分測試環境和生產環境。

2.2.2 strategy

?使用了filter之後,Swarm還提供了strategy(策略)來選出最終運行容器的宿主機,目前swarm已經提供了有如下幾種策略:

  1. random策略:random就是在候選宿主機中(agnet中)隨機選擇一臺的策略;
  2. binpacking策略:binpacking則會在權衡宿主機CPU和內存的占用率之後選擇能分配到最大資源的那臺候選宿主機;
  3. spread策略:spread嘗試把每個容器平均地部署到每個節點上。

?與此同時,調度策略支持對節點的信任機制,如果一個節點總是處於工作狀態,沒有失敗連接的情況,那麽相同條件下,該節點將會優先被選擇。目前對宿主機資源的調度策略還在不斷開發中,使用filter和strategy這種組合方式,對容器的部署仍然保留了Docker宿主機粒度的操作,已能滿足大多數的需求了。

3.swarm集群部署

3.1 集群環境

服務器 角色 docker版本 系統版本
172.18.18.32 Manager docker 17.12.0-ce centos7.4 x64
172.18.18.33 agent01 docker 17.12.0-ce centos7.4 x64
172.18.18.34 agent02 docker 17.12.0-ce centos7.4 x64

說明:

  • Docker版本需要1.12+及以上;
  • 集群節點之間保證TCP 2377(集群管理)、TCP/UDP 7946(容器網絡發現)、UDP 4789(overlay網絡)端口通信;

3.2 準備環境

1、安裝docker:
需要在Manager和所有agent節點上都安裝docker engine,安裝方法不詳細介紹,可參考 《docker環境安裝(Ubuntu、Centos)》

2、配置iptables,開放相關端口(2379、7946、4789):
需要在Manager和所有agent節點都進行配置,如果你沒有啟動iptables服務,可忽略此步:

[root@Manager ~]# iptables -I INPUT -s 172.18.18.0/24 -j ACCEPT
[root@agent01 ~]# iptables -I INPUT -s 172.18.18.0/24 -j ACCEPT
[root@agnet02 ~]# iptables -I INPUT -s 172.18.18.0/24 -j ACCEPT

由於環境都是內網中,環境比較安全,我這裏就直接配置一條策略對172.18.18.0整個網段都開放了,當然,你也可以按照下面的策略逐條的配置:

#iptables -I INPUT -s 172.18.18.0/24 -p tcp --dport 2379 -j ACCEPT
#iptables -I INPUT -s 172.18.18.0/24 -p tcp --dport 7946 -j ACCEPT
#iptables -I INPUT -s 172.18.18.0/24 -p udp --dport 7946 -j ACCEPT
#iptables -I INPUT -s 172.18.18.0/24 -p udp --dport 4789 -j ACCEPT

3.3 初始化swarm集群

1、swarm管理節點初始化,在Manager操作,非常簡單的一條命令:

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

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

    docker swarm join --token SWMTKN-1-2mkrlpdbxuo00hyf97e91cy7ehxs1hut28hne905d6eq3y0pqp-ct7xdzcda003ceah8xp42brho 172.18.18.32:2377

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

參數說明:
init:初始化swarm集群;
--advertise-addr:通告地址,告知其它swarm節點通過172.18.18.32加入swarm集群;

註意:
初始化swarm之後,會給出一條命令信息,agent節點通過給出的命令信息加入到swarm集群中:docker swarm join --token SWMTKN-1-2mkrlpdbxuo00hyf97e91cy7ehxs1hut28hne905d6eq3y0pqp-ct7xdzcda003ceah8xp42brho 172.18.18.32:2377

2、agnet節點加入swarm集群:

[root@agent01 ~]# docker swarm join --token SWMTKN-1-2mkrlpdbxuo00hyf97e91cy7ehxs1hut28hne905d6eq3y0pqp-ct7xdzcda003ceah8xp42brho 172.18.18.32:2377
This node joined a swarm as a worker.

[root@agnet02 ~]# docker swarm join --token SWMTKN-1-2mkrlpdbxuo00hyf97e91cy7ehxs1hut28hne905d6eq3y0pqp-ct7xdzcda003ceah8xp42brho 172.18.18.32:2377
This node joined a swarm as a worker.

 通過上面的信息可以看出,agent兩個都已加入swarm,是不是swarm集群配置很簡單。在Manager上查看一下agnet節點是否加入進來了:

[root@Manager ~]# docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS
jxw920bzistlqnn5webytua87 *   Manager             Ready               Active              Leader
fjf78k25qr4qchanc63atpn9q     agent01             Ready               Active              
9e69g7gfuptfyiyrjfq41tckv     agnet02             Ready               Active  

通過docker node ls命令可以得到(ID信息、主機名、節點狀態、是否可用以及誰是管理節點),一目了然,下面我們來了解一下swarm集群管理的主要命令有哪些。

3.3 swarm集群命令

技術分享圖片
通過 docker --help來了解一下,swarm常用的有這幾選項:

  • docker node:用來管理swarm節點
  • docker service:用來管理swarm服務(創建服務、查看服務詳細信息、刪除和升級服務等)
  • docker stack:用來管理swarm堆棧(可以結合compose.yml一起使用)
  • docker swarm:管理swarm(初始化swarm集群、加入swarm集群、離開swarm集群等)

在來通過docker node --help來了解這個選項有哪些命令:
技術分享圖片
命令說明:

  • demote:從集群中降級一個或多個節點;
  • inspect:在一個或多個節點上顯示詳細信息;
  • ls:列出群中的節點;
  • prromote:將一個或多個節點提升為Manager;
  • ps:列出在一個或多個節點上運行的任務,默認為當前節點;
  • rm:從群中刪除一個或多個節點;
  • update:更新節點;

其實,這些命令和管理docker鏡像和容器的命令作用都很相似,所以大家如果在管理docker鏡像、容器的這些命令比較熟悉,就自然而然的對swarm這些命令用起來順手。其它幾個選項就不挨個介紹了,大家可以通過 --help去查看了解;

4.swarm服務管理

?下面通過busybox鏡像來創建服務進行演示,當然你也可以用其它鏡像操作(比如centos鏡像、nginx鏡像等)。swarm服務管理是通過 “docker service”命令進行管理的,以下操作只能在Manager節點操作。

4.1 通過docker service create 命令創建服務

[root@Manager ~]# docker service create --replicas 1  --name test01 busybox top
8xvp5453ostkjhzcy0u91ko6g
overall progress: 1 out of 1 tasks 
1/1: running   
verify: Service converged 

參數數明:
--replicas :創建的副本數,我這裏先創建1個副本;
--name:容器名稱取名為test01
busybox:這個是docker hub中的一個官方鏡像;
top:通過busybox鏡像運行容器後執行的top命令,因為busybox鏡像運行後沒有任何進程在跑,如果不在後臺跑個進程容器會自動退出,如果你用其它的官方鏡像就不需要這種操作,所以我們隨便跑個top進程;

4.2 通過docker service ps 查看副本運行情況:

[root@Manager ~]# docker service ps test01 
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE           ERROR               PORTS
iwadbu4vyvor        test01.1            busybox:latest      agnet02             Running             Running 4 minutes ago                    

?是不是發現這個服務被分配到了agent02節點上,狀態顯示也是Running,而且,這個命令和docker ps很相似。但是,你用docker ps是查看不到這個運行test01這個服務。

4.3 顯示服務詳細信息:

[root@Manager ~]# docker service inspect test01
[root@Manager ~]# docker service inspect --pretty test01 

?上面--pretty參數是以人性化的格式打印信息,不加--pretty參數就是以json打印信息;

4.4 擴展服務數量:

接下來,我們來演示一下如何把剛才創建的1個test01副本怎麽擴展為3個。

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

查看一下是否已擴展了:

[root@Manager ~]# docker service ls
ID                  NAME                MODE                REPLICAS            IMAGE               PORTS
8xvp5453ostk        test01              replicated          3/3                 busybox:latest  
[root@Manager ~]# docker service ps test01 
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE            ERROR               PORTS
iwadbu4vyvor        test01.1            busybox:latest      agnet02             Running             Running 40 minutes ago                       
im6263jsap6l        test01.2            busybox:latest      agent01             Running             Running 2 minutes ago                        
12r1xk6v8epw        test01.3            busybox:latest      Manager             Running             Running 30 seconds ago     

從上面可以看出,擴展的服務分別分配到了兩臺agnet和一臺Manager。也就是說Manager它即可以管理agent、也同樣承擔運行服務的角色。

4.5 更新服務某些項:

比如,我想更新一下test01這幾個副本的CPU只能使用宿主機50%的CPU資源

[root@Manager ~]# docker service update --limit-cpu=0.5  test01

然後,查看一下是否更新了,在Limits信息欄中可以看到已經更新了:

[root@Manager ~]# docker service inspect test01
...
 "Resources": {
                    "Limits": {
                        "NanoCPUs": 500000000
                    },
...

通過docker service update --help查看幫助信息,裏面有所有update更新的選項(dns、memory、mount、user等等),本文就不一一介紹演示了,大家--help一下自己看看。

4.6滾動更新、回滾更新服務版本:

docker srvice update有一個比較重要的參數要演示一下,它可以對鏡像版本進行更新和回滾,比如先創建一個nginx-1.11.5版本的服務,然後通過docker service update --image選項更新到nginx-1.11.6。

[root@Manager ~]# docker service  create --replicas 3 --name web_test -p 80:80 nginx:1.11.5

看一下nginx服務是否運行:

[root@Manager ~]# docker service ps web_test 
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE           ERROR               PORTS
vz1twcdbpaut        web_test.1          nginx:1.11.5        agent01             Running             Running 4 minutes ago                       
kmcdo4cifygf        web_test.2          nginx:1.11.5        agnet02             Running             Running 5 minutes ago                       
ipynj6l9hegu        web_test.3          nginx:1.11.5        Manager             Running             Running 3 minutes ago  

接下來,我們通過--image選項把nginx更新到版本1.11.6:

[root@Manager ~]# docker service update --image nginx:1.11.6 web_test

查看一下更新後的信息:

[root@Manager ~]# docker service ps  web_test 
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE                 ERROR               PORTS
js9tvwk3ffg9        web_test.1          nginx:1.11.6        agent01             Running             Running 2 minutes ago                             
vz1twcdbpaut         \_ web_test.1      nginx:1.11.5        agent01             Shutdown            Shutdown 2 minutes ago                            
mhbd0fdpofq8        web_test.2          nginx:1.11.6        agnet02             Running             Running 3 minutes ago                             
kmcdo4cifygf         \_ web_test.2      nginx:1.11.5        agnet02             Shutdown            Shutdown 4 minutes ago                            
jswemeuox4yk        web_test.3          nginx:1.11.6        Manager             Running             Running about a minute ago                        
ipynj6l9hegu         \_ web_test.3      nginx:1.11.5        Manager             Shutdown            Shutdown about a minute ago 

從上面可以看出,DESIRED STATE狀態為Shutdown的服務版本為1.15,狀態為Running的服務版本為1.16了,說明更新是OK的。

最後,來演示一下通過--rollback選項如何回滾服務版本:

[root@Manager ~]# docker service update --rollback web_test
web_test
rollback: manually requested rollback 
overall progress: rolling back update: 3 out of 3 tasks 
1/3: running   [>                                                  ] 
2/3: running   [>                                                  ] 
3/3: running   [>                                                  ] 
verify: Service converged 

再來看一下是否回滾:

[root@Manager ~]# docker service ps web_test 
ID                  NAME                IMAGE               NODE                DESIRED STATE       CURRENT STATE             ERROR               PORTS
vrwxibtkjhvg        web_test.1          nginx:1.11.5        agent01             Running             Running 2 minutes ago                         
js9tvwk3ffg9         \_ web_test.1      nginx:1.11.6        agent01             Shutdown            Shutdown 2 minutes ago                        
vz1twcdbpaut         \_ web_test.1      nginx:1.11.5        agent01             Shutdown            Shutdown 6 minutes ago                        
dvcy2q4b3xoy        web_test.2          nginx:1.11.5        agnet02             Running             Running 3 minutes ago                         
mhbd0fdpofq8         \_ web_test.2      nginx:1.11.6        agnet02             Shutdown            Shutdown 3 minutes ago                        
kmcdo4cifygf         \_ web_test.2      nginx:1.11.5        agnet02             Shutdown            Shutdown 7 minutes ago                        
oxx0lslzzt9h        web_test.3          nginx:1.11.5        Manager             Running             Running 42 seconds ago                        
jswemeuox4yk         \_ web_test.3      nginx:1.11.6        Manager             Shutdown            Shutdown 42 seconds ago                       
ipynj6l9hegu         \_ web_test.3      nginx:1.11.5        Manager             Shutdown            Shutdown 5 minutes ago     

是不是狀態為Running的nginx又回到了1.15的版本了。那麽,我們在實際工作中這種對服務更新和回滾會用到哪呢?大家可以留言一起討論一下。

本章內容到此結束,喜歡我的文章,請點擊最上方右角處的《關註》!!!
技術分享圖片

"三劍客”之Swarm集群架構、集群管理 、服務管理