Docker管理工具 - Swarm部署記錄

散盡浮華發表於2017-05-18

 

之前介紹了Docker叢集管理工具-Kubernetes部署記錄,下面介紹另一個管理工具Swarm的用法,Swarm是Docker原生的叢集管理軟體,與Kubernetes比起來比較簡單。

Swarm介紹

Swarm這個專案名稱特別貼切。在Wiki的解釋中,Swarm behavior是指動物的群集行為。比如我們常見的蜂群,魚群,秋天往南飛的雁群都可以稱作Swarm behavior。

Swarm專案正是這樣,通過把多個Docker Engine聚集在一起,形成一個大的docker-engine,對外提供容器的叢集服務。同時這個叢集對外提供Swarm API,使用者可以像使用Docker Engine一樣使用Docker叢集。

Swarm是Docker公司在2014年12月初發布的容器管理工具,和Swarm一起釋出的Docker管理工具還有Machine以及Compose。Swarm是一套較為簡單的工具,用以管理Docker叢集,使得Docker叢集暴露給使用者時相當於一個虛擬的整體。Swarm將一群Docker宿主機變成一個單一的,虛擬的主機。Swarm使用標準的Docker API介面作為其前端訪問入口,換言之,各種形式的Docker Client(docker client in Go, docker_py, docker等)均可以直接與Swarm通訊。Swarm幾乎全部用Go語言來完成開發,Swarm0.2版本增加了一個新的策略來排程叢集中的容器,使得在可用的節點上傳播它們,以及支援更多的Docker命令以及叢集驅動。Swarm deamon只是一個排程器(Scheduler)加路由器(router),Swarm自己不執行容器,它只是接受docker客戶端傳送過來的請求,排程適合的節點來執行容器,這意味著,即使Swarm由於某些原因掛掉了,叢集中的節點也會照常執行,當Swarm重新恢復執行之後,它會收集重建叢集資訊。

Docker的Swarm(叢集)模式,整合很多工具和特性,比如:跨主機上快速部署服務,服務的快速擴充套件,叢集的管理整合到docker引擎,這意味著可以不可以不使用第三方管理工具。分散設計,宣告式的服務模型,可擴充套件,狀態協調處理,多主機網路,分散式的服務發現,負載均衡,滾動更新,安全(通訊的加密)等等,下面就來認識下Swarm(對於Swarm管理的詳細操作可以參考:https://www.centos.bz/tag/swarm/page/3/

Swarm 特點
1) 對外以Docker API介面呈現,這樣帶來的好處是,如果現有系統使用Docker Engine,則可以平滑將Docker Engine切到Swarm上,無需改動現有系統。
2) Swarm對使用者來說,之前使用Docker的經驗可以繼承過來。非常容易上手,學習成本和二次開發成本都比較低。同時Swarm本身專注於Docker叢集管理,非常輕量,佔用資源也非常少。簡單說,就是外掛化機制,Swarm中的各個模組都抽象出了API,可以根據自己一些特點進行定製實現。
3)  Swarm自身對Docker命令引數支援的比較完善,Swarm目前與Docker是同步釋出的。Docker的新功能,都會第一時間在Swarm中體現。

Docker自誕生以來,其容器特性以及映象特性給DevOps愛好者帶來了諸多方便。然而在很長的一段時間內,Docker只能在單host上執行,其跨host的部署、執行與管理能力頗受外界詬病。跨host能力的薄弱,直接導致Docker容器與host的緊耦合,這種情況下,Docker容器的靈活性很難令人滿意,容器的遷移、分組等都成為很難實現的功能點。

Swarm架構

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

Swarm架構中最主要的處理部分自然是Swarm節點,Swarm管理的物件自然是Docker Cluster,Docker Cluster由多個Docker Node組成,而負責給Swarm傳送請求的是Docker Client。

Swarm關鍵概念
1)Swarm
叢集的管理和編排是使用嵌入到docker引擎的SwarmKit,可以在docker初始化時啟動swarm模式或者加入已存在的swarm

2)Node
一個節點(node)是已加入到swarm的Docker引擎的例項 當部署應用到叢集,你將會提交服務定義到管理節點,接著Manager管理節點排程任務到worker節點,manager節點還執行維護叢集的狀態的編排和群集管理功能,worker節點接收並執行來自manager節點的任務。通常,manager節點也可以是worker節點,worker節點會報告當前狀態給manager節點. 

3)服務(Service)
服務是要在worker節點上要執行任務的定義,它在工作者節點上執行,當你建立服務的時,你需要指定容器映象

4)任務(Task)
任務是在docekr容器中執行的命令,Manager節點根據指定數量的任務副本分配任務給worker節點

==========================================================================
docker swarm:叢集管理,子命令有init, join, leave, update。(docker swarm --help檢視幫助)
docker service:服務建立,子命令有create, inspect, update, remove, tasks。(docker service--help檢視幫助)
docker node:節點管理,子命令有accept, promote, demote, inspect, update, tasks, ls, rm。(docker node --help檢視幫助)

node是加入到swarm叢集中的一個docker引擎實體,可以在一臺物理機上執行多個node,node分為:
- manager nodes,也就是管理節點
- worker nodes,也就是工作節點

1)manager node管理節點:執行叢集的管理功能,維護叢集的狀態,選舉一個leader節點去執行排程任務。
2)worker node工作節點:接收和執行任務。參與容器叢集負載排程,僅用於承載task。
3)service服務:一個服務是工作節點上執行任務的定義。建立一個服務,指定了容器所使用的映象和容器執行的命令。service是執行在worker nodes上的task的描述,service的描述包括使用哪個docker 映象,以及在使用該映象的容器中執行什麼命令。
4)task任務:一個任務包含了一個容器及其執行的命令。task是service的執行實體,task啟動docker容器並在容器中執行任務。

Swarm工作方式

1)Node

2)Service(服務, 任務, 容器)

3)任務與排程

4)服務副本與全域性服務

Swarm排程策略
Swarm在scheduler節點(leader節點)執行容器的時候,會根據指定的策略來計算最適合執行容器的節點,目前支援的策略有:spread, binpack, random.
1)Random
顧名思義,就是隨機選擇一個Node來執行容器,一般用作除錯用,spread和binpack策略會根據各個節點可用的CPU, RAM以及正在執行的容器數量來計算應該執行容器的節點。

2)Spread
在同等條件下,Spread策略會選擇執行容器最少的那臺節點來執行新的容器,binpack策略會選擇執行容器最集中的那臺機器來執行新的節點。使用Spread策略會使得容器會均衡的分佈在叢集中的各個節點上執行,一旦一個節點掛掉了只會損失少部分的容器。

3)Binpack
Binpack策略最大化的避免容器碎片化,就是說binpack策略儘可能的把還未使用的節點留給需要更大空間的容器執行,儘可能的把容器執行在一個節點上面。

Swarm Cluster模式的特性
1)批量建立服務
建立容器之前先建立一個overlay的網路,用來保證在不同主機上的容器網路互通的網路模式

2)強大的叢集的容錯性
當容器副本中的其中某一個或某幾個節點當機後,cluster會根據自己的服務註冊發現機制,以及之前設定的值--replicas n,在叢集中剩餘的空閒節點上,重新拉起容器副本。整個副本遷移的過程無需人工干預,遷移後原本的叢集的load balance依舊好使!不難看出,docker service其實不僅僅是批量啟動服務這麼簡單,而是在叢集中定義了一種狀態。Cluster會持續檢測服務的健康狀態並維護叢集的高可用性。

3)服務節點的可擴充套件性
Swarm Cluster不光只是提供了優秀的高可用性,同時也提供了節點彈性擴充套件或縮減的功能。當容器組想動態擴充套件時,只需通過scale引數即可複製出新的副本出來。仔細觀察的話,可以發現所有擴充套件出來的容器副本都run在原先的節點下面,如果有需求想在每臺節點上都run一個相同的副本,方法其實很簡單,只需要在命令中將"--replicas n"更換成"--mode=global"即可!其中:
複製服務(--replicas n)將一系列複製任務分發至各節點當中,具體取決於您所需要的設定狀態,例如“--replicas 3”。
全域性服務(--mode=global)適用於叢集內全部可用節點上的服務任務,例如“--mode global”。如果在 Swarm 叢集中設有 7 臺 Docker 節點,則全部節點之上都將存在對應容器。

4)  排程機制
所謂的排程其主要功能是cluster的server端去選擇在哪個伺服器節點上建立並啟動一個容器例項的動作。它是由一個裝箱演算法和過濾器組合而成。每次通過過濾器(constraint)啟動容器的時候,swarm cluster 都會呼叫排程機制篩選出匹配約束條件的伺服器,並在這上面執行容器。

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

一旦建立好這個cluster,就可以用命令docker service批量對叢集內的容器進行操作,非常方便!

在啟動容器後,docker 會根據當前每個swarm節點的負載判斷,在負載最優的節點執行這個task任務,用"docker service ls" 和"docker service ps + taskID"
可以看到任務執行在哪個節點上。容器啟動後,有時需要等待一段時間才能完成容器建立。

Swarm叢集部署例項(Swarm Cluster)

1)機器環境(均是centos7.2)

182.48.115.237      swarm的manager節點      manager-node    
182.48.115.238      swarm的node節點         node1
182.48.115.239      swarm的node節點         node2

設定主機名
在manager節點上
[root@manager-node ~]# hostnamectl --static set-hostname manager-node

在node1節點上
[root@node1 ~]# hostnamectl --static set-hostname node1

在node2節點上
[root@node2 ~]# hostnamectl --static set-hostname node2

在三臺機器上都要設定hosts,均執行如下命令:
[root@manager-node ~]# vim /etc/hosts
......
182.48.115.237 manager-node
182.48.115.238 node1
182.48.115.239 node2

關閉三臺機器上的防火牆。如果開啟防火牆,則需要在所有節點的防火牆上依次放行2377/tcp(管理埠)、7946/udp(節點間通訊埠)、4789/udp(overlay 網路埠)埠。
[root@manager-node ~]# systemctl disable firewalld.service
[root@manager-node ~]# systemctl stop firewalld.service

2)分別在manager節點和node節點上安裝docker,並下載swarm映象

[root@manager-node ~]# yum install -y docker
 
配置docker
[root@manager-node ~]# vim /etc/sysconfig/docker
......
OPTIONS='-H 0.0.0.0:2375 -H unix:///var/run/docker.sock'           //在OPTIONS引數項後面的''裡新增內容. 或者使用'-H tcp://0.0.0.0:2375 -H unix:///var/run/docker.sock'
 
[root@manager-node ~]# systemctl restart docker
 
下載swarm映象
[root@manager-node ~]# docker pull swarm
[root@manager-node ~]# docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
docker.io/swarm     latest              36b1e23becab        4 months ago        15.85 MB

3)建立swarm(要儲存初始化後token,因為在節點加入時要使用token作為通訊的金鑰)

[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.

上面命令執行後,該機器自動加入到swarm叢集。這個會建立一個叢集token,獲取全球唯一的 token,作為叢集唯一標識。後續將其他節點加入叢集都會用到這個token值。
其中,--advertise-addr參數列示其它swarm中的worker節點使用此ip地址與manager聯絡。命令的輸出包含了其它節點如何加入叢集的命令。

-------------------------------------------------------------------------------------------------------------------
溫馨提示:
如果再次執行上面啟動swarm叢集的命令,會報錯說這個節點已經在叢集中了
Error response from daemon: This node is already part of a swarm. Use "docker swarm leave" to leave this swarm and join another one.

解決辦法:
[root@manager-node ~]# docker swarm leave --help           //檢視幫助
[root@manager-node ~]# docker swarm leave --force
-------------------------------------------------------------------------------------------------------------------

使用docker info 或 docker node ls 檢視叢集中的相關資訊
[root@manager-node ~]# docker info
.......
Swarm: active
 NodeID: 1gi8utvhu4rxy8oxar2g7h6gr
 Is Manager: true
 ClusterID: a88a9j6nwcbn31oz6zp9oc0f7
 Managers: 1
 Nodes: 1
 Orchestration:
  Task History Retention Limit: 5
.......

[root@manager-node ~]# docker node ls                  
ID                           HOSTNAME      STATUS  AVAILABILITY  MANAGER STATUS
1gi8utvhu4rxy8oxar2g7h6gr *  manager-node  Ready   Active        Leader

注意上面node ID旁邊那個*號表示現在連線到這個節點上。

4)新增節點到swarm叢集中

在docker swarm init 完了之後,會提示如何加入新機器到叢集,如果當時沒有注意到,也可以通過下面的命令來獲知 如何加入新機器到叢集。
 
登入到node1節點上,執行前面建立swarm叢集時輸出的命令:
[root@node1 ~]# docker swarm join --token SWMTKN-1-4roc8fx10cyfgj1w1td8m0pkyim08mve578wvl03eqcg5ll3ig-f0apd81qfdwv27rnx4a4y9jej 182.48.115.237:2377
This node joined a swarm as a worker.
 
同理在node2節點上,也執行這個命令
[root@node2 ~]# docker swarm join --token SWMTKN-1-4roc8fx10cyfgj1w1td8m0pkyim08mve578wvl03eqcg5ll3ig-f0apd81qfdwv27rnx4a4y9jej 182.48.115.237:2377
This node joined a swarm as a worker.
 
如果想要將其他更多的節點新增到這個swarm叢集中,新增方法如上一致!
 
然後在manager-node管理節點上看一下叢集節點的狀態:
[root@manager-node ~]# docker node ls
ID                           HOSTNAME      STATUS  AVAILABILITY  MANAGER STATUS
1gi8utvhu4rxy8oxar2g7h6gr *  manager-node  Ready   Active        Leader
ei53e7o7jf0g36329r3szu4fi    node1         Ready   Active       
f1obgtudnykg51xzyj5fs1aev    node2         Ready   Active

--------------------------------------------------------------------------------------------------------------------
溫馨提示:更改節點的availablity狀態
swarm叢集中node的availability狀態可以為 active或者drain,其中:
active狀態下,node可以接受來自manager節點的任務分派;
drain狀態下,node節點會結束task,且不再接受來自manager節點的任務分派(也就是下線節點)。

[root@manager-node ~]# docker node update --availability drain node1    //將node1節點下線。如果要刪除node1節點,命令是"docker node rm --force node1"
[root@manager-node ~]# docker node ls
ID                           HOSTNAME      STATUS  AVAILABILITY  MANAGER STATUS
1gi8utvhu4rxy8oxar2g7h6gr *  manager-node  Ready   Active        Leader
ei53e7o7jf0g36329r3szu4fi    node1         Ready   drain       
f1obgtudnykg51xzyj5fs1aev    node2         Ready   Active

如上,當node1的狀態改為drain後,那麼該節點就不會接受task任務分發,就算之前已經接受的任務也會轉移到別的節點上。

再次修改為active狀態(及將下線的節點再次上線)
[root@manager-node ~]# docker node update --availability active node1

5)在Swarm中部署服務(這裡以nginx服務為例)

Docker 1.12版本提供服務的Scaling、health check、滾動升級等功能,並提供了內建的dns、vip機制,實現service的服務發現和負載均衡能力。

在啟動容器之前,先來建立一個覆蓋網路,用來保證在不同主機上的容器網路互通的網路模式
[root@manager-node ~]# docker network create -d overlay ngx_net
[root@manager-node ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
8bbd1b7302a3        bridge              bridge              local             
9e637a97a3b9        docker_gwbridge     bridge              local             
b5a41c8c71e7        host                host                local             
1x45zepuysip        ingress             overlay             swarm             
3ye6vfp996i6        ngx_net             overlay             swarm             
0808a5c72a0a        none                null                local
  
在manager-node節點上使用上面這個覆蓋網路建立nginx服務:
其中,--replicas 引數指定服務由幾個例項組成。
注意:不需要提前在節點上下載nginx映象,這個命令執行後會自動下載這個容器映象(比如此處建立tomcat容器,就將下面命令中的映象改為tomcat映象)。
[root@manager-node ~]# docker service create --replicas 1 --network ngx_net --name my-test -p 80:80 nginx
  
就建立了一個具有一個副本(--replicas 1 )的nginx服務,使用映象nginx
  
使用 docker service ls 檢視正在執行服務的列表
[root@manager-node ~]# docker service ls
ID            NAME     REPLICAS  IMAGE            COMMAND
0jb5eebo8j9q  my-test  1/1       nginx
  
查詢Swarm中服務的資訊
-pretty 使命令輸出格式化為可讀的格式,不加 --pretty 可以輸出更詳細的資訊:
[root@manager-node ~]# docker service inspect --pretty my-test
ID:   0jb5eebo8j9qb1zc795vx3py3
Name:   my-test
Mode:   Replicated
 Replicas:  1
Placement:
UpdateConfig:
 Parallelism: 1
 On failure:  pause
ContainerSpec:
 Image:   nginx
Resources:
Networks: 3ye6vfp996i6eq17tue0c2jv9
Ports:
 Protocol = tcp
 TargetPort = 80
 PublishedPort = 80
  
 查詢到哪個節點正在執行該服務。如下該容器被排程到manager-node節點上啟動了,然後訪問http://182.48.115.237即可訪問這個容器應用(如果排程到其他節點,訪問也是如此)
 [root@manager-node ~]# docker service ps my-test
ID                         NAME       IMAGE            NODE          DESIRED STATE  CURRENT STATE          ERROR
2m8qqpoa0dpeua5jbgz1infuy  my-test.1  nginx  manager-node  Running        Running 3 minutes ago
  
注意,如果上面命令執行後,上面的 STATE 欄位中剛開始的服務狀態為 Preparing,需要等一會才能變為 Running 狀態,其中最費時間的應該是下載映象的過程。
  
  
有上面命令可知,該服務在manager-node節點上執行。登陸該節點,可以檢視到nginx容器在執行中
[root@manager-node ~]# docker ps
CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS              PORTS               NAMES
1ea1d72007da        nginx:latest   "nginx -g 'daemon off"   4 minutes ago       Up 4 minutes        80/tcp              my-test.1.2m8qqpoa0dpeua5jbgz1infuy
  
-----------------------------------------------------------在Swarm中動態擴充套件服務(scale)-----------------------------------------------------------
當然,如果只是通過service啟動容器,swarm也算不上什麼新鮮東西了。Service還提供了複製(類似kubernetes裡的副本)功能。可以通過 docker service scale 命令來設定服務中容器的副本數:
  
比如將上面的my-test容器動態擴充套件到5個,命令如下:
[root@manager-node ~]# docker service scale my-test=5
  
和建立服務一樣,增加scale數之後,將會建立新的容器,這些新啟動的容器也會經歷從準備到執行的過程,過一分鐘左右,服務應該就會啟動完成,這時候可以再來看一下 nginx 服務中的容器
[root@manager-node ~]# docker service ps my-test
ID                         NAME       IMAGE            NODE          DESIRED STATE  CURRENT STATE          ERROR
2m8qqpoa0dpeua5jbgz1infuy  my-test.1  nginx  manager-node  Running        Running 9 minutes ago
aqko8yhmdj53gmzs8gqhoylc2  my-test.2  nginx  node2         Running        Running 2 minutes ago
erqk394hd4ay7nfwgaz4zp3s0  my-test.3  nginx  node1         Running        Running 2 minutes ago
2dslg6w16wzcgboa2hxw1c6k1  my-test.4  nginx  node1         Running        Running 2 minutes ago
bmyddndlx6xi18hx4yinpakf3  my-test.5  nginx  manager-node  Running        Running 2 minutes ago
  
可以看到,之前my-test容器只在manager-node節點上有一個例項,而現在又增加了4個例項。
這5個副本的my-test容器分別執行在這三個節點上,登陸這三個節點,就會發現已經存在執行著的my-test容器。
  
-----------------------------------------------------------------------------------------------------
特別需要清楚的一點:
如果一個節點當機了(即該節點就會從swarm叢集中被踢出),則Docker應該會將在該節點執行的容器,排程到其他節點,以滿足指定數量的副本保持執行狀態。
  
比如:
將node1當機後或將node1的docker服務關閉,那麼它上面的task例項就會轉移到別的節點上。當node1節點恢復後,它轉移出去的task例項不會主動轉移回來,
只能等別的節點出現故障後轉移task例項到它的上面。使用命令"docker node ls",發現node1節點已不在swarm叢集中了。
  
然後過一會查詢服務的狀態列表
[root@manager-node ~]# docker service ps my-test
ID                         NAME           IMAGE            NODE          DESIRED STATE  CURRENT STATE           ERROR
2m8qqpoa0dpeua5jbgz1infuy  my-test.1      docker.io/nginx  manager-node  Running        Running 33 minutes ago
aqko8yhmdj53gmzs8gqhoylc2  my-test.2      docker.io/nginx  node2         Running        Running 26 minutes ago
di99oj7l9x6firw1ai25sewwc  my-test.3      docker.io/nginx  node2         Running        Running 6 minutes ago 
erqk394hd4ay7nfwgaz4zp3s0   \_ my-test.3  docker.io/nginx  node1         Shutdown       Complete 5 minutes ago
aibl3u3pph3fartub0mhwxvzr  my-test.4      docker.io/nginx  node2         Running        Running 6 minutes ago 
2dslg6w16wzcgboa2hxw1c6k1   \_ my-test.4  docker.io/nginx  node1         Shutdown       Complete 5 minutes ago
bmyddndlx6xi18hx4yinpakf3  my-test.5      docker.io/nginx  manager-node  Running        Running 26 minutes ago
  
發現,node1節點出現故障後,它上面之前的兩個task任務已經轉移到node2節點上了。
登陸到node2節點上,可以看到這兩個執行的task任務。當訪問182.48.115.239節點的80埠,swarm的負載均衡會把請求路由到一個任意節點的可用的容器上。
[root@node2 ~]# docker ps
CONTAINER ID        IMAGE                    COMMAND                  CREATED             STATUS              PORTS               NAMES
216abf6bebea        docker.io/nginx:latest   "nginx -g 'daemon off"   7 minutes ago       Up 7 minutes        80/tcp              my-test.3.di99oj7l9x6firw1ai25sewwc
1afd12cc9140        docker.io/nginx:latest   "nginx -g 'daemon off"   7 minutes ago       Up 7 minutes        80/tcp              my-test.4.aibl3u3pph3fartub0mhwxvzr
cc90da57c25e        docker.io/nginx:latest   "nginx -g 'daemon off"   27 minutes ago      Up 27 minutes       80/tcp              my-test.2.aqko8yhmdj53gmzs8gqhoylc2
  
再次在node2節點上將從node1上轉移過來的兩個task關閉
[root@node2 ~]# docker stop my-test.3.di99oj7l9x6firw1ai25sewwc my-test.4.aibl3u3pph3fartub0mhwxvzr
my-test.3.di99oj7l9x6firw1ai25sewwc
my-test.4.aibl3u3pph3fartub0mhwxvzr
  
再次查詢服務的狀態列表,發現這兩個task又轉移到node1上了(即在swarm cluster叢集中啟動的容器,在worker node節點上刪除或停用後,該容器會自動轉移到其他的worker node節點上)
[root@manager-node ~]# docker service ps my-test
ID                         NAME           IMAGE            NODE          DESIRED STATE  CURRENT STATE                ERROR
2m8qqpoa0dpeua5jbgz1infuy  my-test.1      docker.io/nginx  manager-node  Running        Running 38 minutes ago     
aqko8yhmdj53gmzs8gqhoylc2  my-test.2      docker.io/nginx  node2         Running        Running 31 minutes ago     
7dhmc63rk0bc8ngt59ix38l44  my-test.3      docker.io/nginx  node1         Running        Running about a minute ago 
di99oj7l9x6firw1ai25sewwc   \_ my-test.3  docker.io/nginx  node2         Shutdown       Complete about a minute ago
erqk394hd4ay7nfwgaz4zp3s0   \_ my-test.3  docker.io/nginx  node1         Shutdown       Complete 9 minutes ago     
607tyjv6foc0ztjjvdo3l3lge  my-test.4      docker.io/nginx  node1         Running        Running about a minute ago 
aibl3u3pph3fartub0mhwxvzr   \_ my-test.4  docker.io/nginx  node2         Shutdown       Complete about a minute ago
2dslg6w16wzcgboa2hxw1c6k1   \_ my-test.4  docker.io/nginx  node1         Shutdown       Complete 9 minutes ago     
bmyddndlx6xi18hx4yinpakf3  my-test.5      docker.io/nginx  manager-node  Running        Running 31 minutes ago
 
----------------------------------------------------------------------------------------------------
同理,swarm還可以縮容,如下,將my-test容器變為1個。
[root@manager-node ~]# docker service scale my-test=1
[root@manager-node ~]# docker service ps my-test
ID                         NAME       IMAGE            NODE          DESIRED STATE  CURRENT STATE          ERROR
2m8qqpoa0dpeuasdfsdfdfsdf  my-test.1  nginx  manager-node  Running        Running 3 minutes ago
 
登入node2節點,使用docker ps檢視,會發現容器被stop而非rm
 
---------------------------------------------------------------------------------------------------
刪除容器服務
[root@manager-node ~]# docker service --help       //檢視幫助
[root@manager-node ~]# docker service rm my-test    //這樣就會把所有節點上的所有容器(task任務例項)全部刪除了
my-nginx
  
---------------------------------------------------------------------------------------------------
除了上面使用scale進行容器的擴容或縮容之外,還可以使用docker service update 命令。 可對 服務的啟動 引數 進行 更新/修改。
[root@manager-node ~]# docker service update --replicas 3 my-test
my-test
 
更新完畢以後,可以檢視到REPLICAS已經變成3/3
[root@manager-node ~]# docker service ls
ID            NAME          REPLICAS  IMAGE      COMMAND  
d7cygmer0yy5  my-test       3/3       nginx     /bin/bash
 
[root@manager-node ~]# docker service ps my-test
ID                         NAME             IMAGE  NODE          DESIRED STATE  CURRENT STATE            ERROR
ddkidkz0jgor751ffst55kvx4  my-test.1      nginx  node1         Running          Preparing 4 seconds ago 
1aucul1b3qwlmu6ocu312nyst   \_ my-test.1  nginx  manager-node  Shutdown       Complete 5 seconds ago  
4w9xof53f0falej9nqgq064jz   \_ my-test.1  nginx  manager-node  Shutdown       Complete 19 seconds ago 
0e9szyfbimaow9tffxfeymci2   \_ my-test.1  nginx  manager-node  Shutdown       Complete 30 seconds ago 
27aqnlclp0capnp1us1wuiaxm  my-test.2      nginx  manager-node  Running        Preparing 1 seconds ago 
7dmmmle29uuiz8ey3tq06ebb8  my-test.3      nginx  manager-node  Running        Preparing 1 seconds ago
 
docker service update 命令,也可用於直接 升級 映象等。
[root@manager-node ~]# docker service update --image nginx:new my-test
 
[root@manager-node ~]# docker service ls
ID            NAME          REPLICAS  IMAGE         COMMAND  
d7cygmer0yy5  my-test       3/3       nginx:new     /bin/bash

6)Swarm中使用Volume(掛在目錄:  --mount type=volume  或者 --mount type=bind )

檢視docker volume的幫助資訊
[root@manager-node ~]# docker volume --help
    
Usage:  docker volume COMMAND
    
Manage Docker volumes
    
Options:
      --help   Print usage
    
Commands:
  create      Create a volume
  inspect     Display detailed information on one or more volumes
  ls          List volumes
  rm          Remove one or more volumes
    
Run 'docker volume COMMAND --help' for more information on a command.
    
[root@manager-node ~]# docker volume create --name myvolume
myvolume
   
[root@manager-node ~]# docker volume ls
DRIVER              VOLUME NAME
local               11b68dce3fff0d57172e18bc4e4cfc252b984354485d747bf24abc9b11688171
local               1cd106ed7416f52d6c77ed19ee7e954df4fa810493bb7e6cf01775da8f9c475f
local               myvolume
   
引數src寫成source也可以;dst表示容器內的路徑,也可以寫成destination
[root@manager-node ~]# docker service create --replicas 2 --network ngx_net --mount type=volume,src=myvolume,dst=/wangshibo --name test-nginx nginx

====================================================
溫馨提示:
必須確保各節點伺服器的selinux永久關閉,即:
[root@manager-node ~]# cat /etc/sysconfig/selinux
SELINUX=disabled
[root@manager-node ~]# reboot
[root@manager-node ~]# getenforce
Disabled
 
必須是永久關閉,臨時關閉可能都不行,否則上面建立命令後,可能會出現如下報錯:
[root@manager-node ~]# docker service ps test-nginx
"SELinux relabeling of is not allowed"
====================================================
 
[root@manager-node ~]# docker service ls
ID            NAME        REPLICAS  IMAGE   COMMAND
8s9m0okwlhvl  test-nginx  2/2       nginx
[root@manager-node ~]# docker service ps test-nginx
ID                         NAME          IMAGE  NODE   DESIRED STATE  CURRENT STATE           ERROR
32bqjjhqcl1k5z74ijjli35z3  test-nginx.1  nginx  node1  Running        Running 23 seconds ago
48xoypunb3g401jkn690lx7xt  test-nginx.2  nginx  node2  Running        Running 23 seconds ago
    
登入node1節點的test-nginx容器檢視
[root@node1 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
d471569629b2        nginx:latest        "nginx -g 'daemon off"   2 minutes ago       Up 2 minutes        80/tcp              test-nginx.1.32bqjjhqcl1k5z74ijjli35z3
    
[root@node1 ~]# docker exec -ti d471569629b2 /bin/bash
root@d471569629b2:/# cd /wangshibo/
root@d471569629b2:/wangshibo# ls
root@d471569629b2:/wangshibo# echo "ahahha" > test
root@d471569629b2:/wangshibo# ls
test
    
[root@node1 ~]# docker volume inspect myvolume
[
    {
        "Name": "myvolume",
        "Driver": "local",
        "Mountpoint": "/var/lib/docker/volumes/myvolume/_data",
        "Labels": null,
        "Scope": "local"
    }
]
[root@node1 ~]# cd /var/lib/docker/volumes/myvolume/_data/
[root@node1 _data]# ls
test
[root@node1 _data]# cat test
ahahha
[root@node1 _data]# echo "12313" > 123
[root@node1 _data]# ls
123  test
    
root@d471569629b2:/wangshibo# ls
123  test
root@d471569629b2:/wangshibo# cat test
ahahha
    
需要注意:
1) 掛載volume後,宿主機和容器之間就可以通過volume進行雙向實時同步.
2) 如果replicas是多份,則每個節點宿主機上都會有一個volume路徑,即每個節點宿主機的/var/lib/docker/volumes/myvolume/_data和分佈到它上面的
    容器裡的/wangshibo進行實時同步.
 
============================================================
第二種方法:
  
命令格式:
docker service create --mount type=bind,source=/host_data/,destination=/container_data/
其中,引數target表示容器裡面的路徑,source表示本地硬碟路徑
  
[root@manager-node ~]# docker service create --replicas 1 --mount type=bind,source=/opt/web/,destination=/usr/share/nginx/html/ --network ngx_net --name haha-nginx -p 8880:80 nginx
[root@manager-node ~]# docker service ls
ID            NAME        REPLICAS  IMAGE  COMMAND
9t9d58b5bq4u  haha-nginx  1/1       nginx
[root@manager-node ~]# docker service ps haha-nginx
ID                         NAME              IMAGE  NODE          DESIRED STATE  CURRENT STATE            ERROR
bji4f5tikhvm7nf5ief3jk2is  haha-nginx.1      nginx  node2         Running        Running 18 seconds ago
  
登入node2節點,在掛載目錄/opt/web下寫測試資料
[root@node2 _data]# cd /opt/web/
[root@node2 web]# ls
[root@node2 web]# cat wang.html
sdfasdf
  
登入容器檢視,發現已經實現資料同步
[root@node2 ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
3618e3d1b966        nginx:latest        "nginx -g 'daemon off"   28 seconds ago      Up 24 seconds       80/tcp              haha-nginx.1.bji4f5tikhvm7nf5ief3jk2is
[root@node2 ~]# docker exec -ti 3618e3d1b966 /bin/bash
root@3618e3d1b966:/# cd /usr/share/nginx/html
root@3618e3d1b966:/usr/share/nginx/html# ls
wang.html
root@3618e3d1b966:/usr/share/nginx/html# cat wang.html
sdfasdf
root@3618e3d1b966:/usr/share/nginx/html# touch test
touch: cannot touch 'test': Permission denied
  
由此可見,以上設定後,在容器裡的同步目錄下沒有寫許可權,更新內容時只要放到宿主機的掛在目錄下即可!

總之,Swarm上手很簡單,Docker swarm可以非常方便的建立類似kubernetes那樣帶有副本的服務,確保一定數量的容器執行,保證服務的高可用。
然而,光從官方文件來說,功能似乎又有些簡單;

swarm、kubernetes、messos總體比較而言:
1)Swarm的優點和缺點都是使用標準的Docker介面,使用簡單,容易整合到現有系統,但是更困難支援更復雜的排程,比如以定製介面方式定義的排程。
2)Kubernetes 是自成體系的管理工具,有自己的服務發現和複製,需要對現有應用的重新設計,但是能支援失敗冗餘和擴充套件系統。
3)Mesos是低階別 battle-hardened排程器,支援幾種容器管理框架如Marathon, Kubernetes, and Swarm,現在Kubernetes和Mesos穩定性超過Swarm,在擴充套件性方面,Mesos已經被證明支援超大規模的系統,比如數百數千臺主機,但是,如果你需要小的叢集,比如少於一打數量的節點伺服器數量,Mesos也許過於複雜了。

相關文章