Docker三劍客——Swarm

一、Swarm簡介

在Docker的官方文檔當中,我們可以看到在Docker 1.12及更高版本中,Swarm模式與Docker Engine集成。那麼Dokcer Swarm到底是個什麼?

Docker Swarm是Docker官方的三劍客項目之一,提供Docker容器集羣服務,是Docker官方對容器雲生態鏡像支持的核心方案。它是Docker公司推出的官方容器集羣平臺,基於Go語言實現,代碼在https://github.com/docker/swarm

Docker Swarm是原生支持Docker集羣管理的工具。它可以把多個Docker主機組成的系統轉換爲單一的虛擬Docker主機,使得容器可以組成跨主機的子網網絡。

在很多臺機器上部署Docker,組成一個Docker集羣,並把整個集羣的資源抽象成資源池,使用者部署Docker應用的時候,只需要將應用交給Swarm,Swarm會根據整個集羣資源的使用情況來分配資源給部署的Docker應用,可以將這個集羣的資源利用率達到最大。

使用Docker CLI創建羣集,將應用程序服務部署到羣集,並管理羣體行爲。其主要的目的就是更好的幫助用戶管理多個Docker Engine,方便用戶使用,像使用Docker Engine一樣使用容器集羣服務。

二、關於集羣

1、關於集羣

前面的簡介裏,我們提到了集羣的概念。那麼這裏我們來說一下,什麼是集羣?

 集羣是一組協同工作的服務實體(可理解爲服務器),用以提供比單一服務實體更具擴展性與可用性的服務平臺。在客戶端看來,一個集羣就像是一個服務實體,但事實上集羣由一組服務實體組成。與單一服務實體相比較,集羣提供了以下兩個關鍵特性:

  • 可擴展性——集羣的性能不限於單一的服務實體,新的服務實體可以動態地加入到集羣,從而增強集羣的性能。

  • 高可用性——集羣通過服務實體冗餘使客戶端免於輕易遇到out of service的警告。在集羣中,同樣的服務可以由多個服務實體提供。如果一個服務實體失敗了,另一個服務實體會接管失敗的服務實體。集羣提供的從一個出錯的服務實體恢復到另一個服務實體的功能增強了應用的可用性。

2、Docker集羣服務概念:

在深入學習之前,我們需要明確幾個概念:

- 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中啓動一個nginx服務,使用的鏡像是 nginx:latest,副本數爲3。

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

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

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

總結一下:
swarm以節點(node)的方式組織集羣(cluster);同時每個節點上面可以部署一個或者多個服務(service),每個服務又可以包括一個或者多個容器(container)

Swarm的架構圖如下:
Swarm

三、Swarm實戰

因爲現在新版本的Docker已經結合了Swarm,所以在這裏主要結合的是新版本功能的Docker的演示。

1、Swarm基本命令


docker swarm init 創建Swarm,同時讓swarm-manager 成爲 manager node。
執行該命令後,顯示添加worker node和manager node 需要執行的命令。
–advertise-addr 指定與其他node通信的地址。

docker swarm init --advertise-addr [ip]

查看swarm worker的連接令牌

docker swarm join-token worker

查看swarm manager的連接令牌

docker swarm join-token manager

加入docker swarm集羣,這裏的token和ip更換爲具體需求下的即可。
如果忘記可以用docker swarm join-token worker查看。

docker swarm join --token SWMTKN-1-1next4gw4m7yx3j6q1f4z4ooimvp3pc1ahsnnwifu5w1h6b247-f10wphfpnyyunzphr1qp4kew1 192.168.1.245:2377

查看集羣中的節點

docker node ls

將節點升級爲manager

docker node promote work-node1

將節點降級爲worker

docker node demote work-node1

只能刪除down狀態的節點,如何要刪除active狀態的,需要加上–force

docker node rm --force worker-manager

查看服務列表

docker service ls

查看具體服務信息,這裏是web服務

docker service ps web

創建一個名稱爲web,副本爲3,開放端口爲80的nginx服務

docker service create --name web --replicas 3 -p 80:80 nginx

刪除一個服務

docker service rm web

查看集羣中節點信息

docker node inspect work-node1 --pretty

查看服務的詳細信息

docker service inspect --pretty <SERVICE-ID>/<SERVICE-NAME>

調度程序不會將新任務分配給節點。
調度程序關閉任何現有任務並在可用節點上安排它們。

docker node update --availability drain work-node1

調度程序可以將任務分配給節點

docker node update --availability active work-node1

調度程序不向節點分配新任務,但是現有任務仍然保持運行

docker node update --availability pause work-node1

爲指定的服務刪除一個開放端口

docker service update --publish-rm 8080:80 web

爲指定的服務添加一個開放端口

docker service update --publish-add 8080:80 web

回滾至之前版本

docker service update --rollback mysql

擴展或縮放服務中容器的數量

docker service scale web=5

以上是一些常用的docker swarm命令,接下來我們就進入實戰。

2、Swarm實戰

A.創建基本的集羣環境

接下來會創建三個節點的Swarm集羣。如下圖:

swarm集羣

swarm-manager 是 manager node,swarm-worker1 和 swarm-worker2 是 worker node,可以認爲是worker-node1、worker-node2節點。
swarm-manager、swarm-worker1和swarm-worker2均爲Linux系統服務器,系統爲Ubuntu 16.04。
先在swarm-manager使用docker swarm init命令

docker swarm init --advertise-addr 39.108.119.87

這裏的ip爲具體本機服務ip。
初始化爲swarm-manager節點,如下:

init

使用docker node ls 我們可以查看到創建的節點:
node
然後我們在swarm-worker1、和swarm-worker2服務器下面分別輸入剛纔初始化成功後的提示消息,比如在swarm-worker2節點下輸入下面命令:

docker swarm join --token SWMTKN-1-1nkutg1v1bwjvdsy10xgocw1hftusf51xomjj735fd9d08s0ju-5pizwmfjtttcpvaht8vsnv3s1 39.108.119.87:2377

我們可以看到提示:
tip

This node joined a swarm as a worker. 提示我們添加節點成功。

當我們去swarm-manager節點進行查看時可以發現,出現了三個節點,其中的兩個就是剛纔我們添加的。

nodes

當然我們也可以刪除某個節點,使用docker node rm , 這個只能刪除down狀態的節點,如何要刪除active狀態的。需要加上–force。

docker node rm --force sprkw7t8irlb4l3dtvwszpdjj

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

B.服務創建及伸縮

在上面我們搭建好了集羣環境。現在我們在manager節點上部署一個基本的nginx服務,服務數量爲(副本數)2個,公開指定端口是8080映射容器80,使用nginx鏡像。

docker service create --replicas 2 --name nginx --publish 8080:80  nginx

創建服務

通過docker service ls可以查看當前swarm中的服務。
啓動服務
可以看到服務正在啓動過程當中。

稍等一會我們再去查看服務,並使用docker service ps nginx查看具體的nginx服務,如下:
nginx服務

可以發現,nginx服務已經啓動起來了,並且在不同的節點裏面運行起來了。

這裏主要在swarm-manager和swarm-worker1裏面分別啓動了一個容器。

我們知道平時通常會運行多個實例。這樣可以負載均衡,同時也能實現服務器高可用。

比如現在我們想把nginx服務數目提升到5個,提高可用性,就可以使用如下命令:

docker service scale nginx=5

scale

我們可以查看到啓動了5個nginx服務,並且分佈在不同的節點,從中可以看到swarm-manager節點裏啓動了1個,swarm-worker1和swarm-worker2分別啓動了2個節點。

我們可以去相應節點服務器,通過docker ps -a 查看,比如:swarm-manager節點,只有一個容器運行:
manager

swarm-worker1節點,有兩個容器運行:
node1

swarm-worker2節點,有兩個容器運行:
node2

具體結果如下:
swarm

我們知道默認配置下manager node 也是 worker node,所以 swarm-manager 上也運行了副本。如果不希望在 manager 上運行 service,可以進行排空,就是將該節點上的容器排空。命令如下:

docker node update --availability drain [NODE-ID]

執行過後,我們再查看具體服務情況如下:
update

我們可以看到在swarm-manager上的容器nginx狀態是shutdown了,然後在swarm-worker2上啓動了一個nginx服務。

查看節點狀態,docker node ls可以發現manager上的狀態爲drain。

drain

當然如果我們要減少服務數目,直接把scale的數據設置比當前啓動的服務少即可。比如減少服務數到3個,如下命令:

docker service scale nginx=3

結果如下,shutdown爲先前排除manager節點裏的容器,可以看到只有三個運行的服務。
scale3

最後集羣服務情況如下:
swarm

C.服務之間的通信

比如我們在創建多個服務之間要通信,某個服務不要求與外部通信(比如數據庫等)。這裏就用到了服務發現。

我們就可以使用建立overlay網絡,部署 service 到 overlay網絡上去。

比如新建dev網絡環境:

docker network create --driver overlay dev

dev網絡
然後我們新建服務,就可以讓服務部署在該網絡上。比如下面我們新建nginx版本1.12.2的服務,副本爲2,開放80端口,部署到我們新建的dev網絡上。

docker service create --replicas 2 --name nginx-dev --publish 9090:80  --network dev nginx:1.12.2

nginx
我們可以看到服務正在啓動,我們可以在不同的節點下看到dev網絡有該容器,而相同網絡下的服務就可以進行通信,ip直接是可以訪問到的。

D.服務鏡像升級和回滾

在前面我們部署了多個副本的服務,如果我們要升級某個服務該怎麼辦,如下,我們對剛剛dev網絡環境下的nginx:1.12.2進行升級,升級到1.13.12版本。使用如下命令:

docker service update --image nginx:1.13.12 nginx-dev

可以看到服務狀態,新版本運行起來了,舊版本被停止了。
升級

Swarm 將按照如下步驟執行滾動更新:

  • 停止第一個副本。
  • 調度任務,選擇 worker node。
  • 在 worker 上用新的鏡像啓動副本。
  • 如果副本(容器)運行成功,繼續更新下一個副本;如果失敗,暫停整個更新過程。

默認配置下,Swarm 一次只更新一個副本,並且兩個副本之間沒有等待時間。我們可以通過 –update-parallelism 設置並行更新的副本數目,通過 –update-delay 指定滾動更新的間隔時間。

比如執行如下命令:

docker service update --replicas 6 --update-parallelism 2 --update-delay 1m30s nginx-dev

service 增加到六個副本,每次更新兩個副本,間隔時間一分半鐘。

Swarm 還有個回滾功能,如果更新後效果不理想,可以通過 –rollback 快速恢復到更新之前的狀態。

docker service update --rollback nginx-dev

rollback

可以看到服務已經回滾到先前的版本。到此docker中swarm的簡單使用就到此結束,後面再會介紹Docker三劍客的其他內容。

參考

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章