1. 程式人生 > >SWARM大法好——Docker1.12 引擎使用體驗

SWARM大法好——Docker1.12 引擎使用體驗

背景

憑藉敏捷開發部署理念的推行,相信對於很多人來說docker這項容器技術已經並不陌生,Docker 1.12引擎釋出了快兩個月,新引擎中包含了許多特性。諸如: Swarm模式,容器叢集的健康檢查,節點的身份加密,docker Service API呼叫,容器啟動的過濾匹配方式(constraint), docker的內建路由,以及支援在多平臺系統上執行docker(MAC、Windows、AWS、AZURE),以及一些外掛升級等等. 特性之多,就連Docker 自己的產品經理也表示這次的新版本可能是公司有史以來變化最大的一次產品釋出。

很長一段時間裡,docker在叢集模式的管理上一直廣受外界詬病。Docker服務自身只能在單臺host上進行操作,官方並沒有真正意義上的叢集管理方案。直到現在1.12的出現, 引擎在多主機、多容器的叢集管理上才有了進一步的改進和完善,版本自身內嵌了swarm mode叢集管理模式。

本文主要是介紹一下swarm 叢集管理模式的新特性,以及如何該模式下如何實現叢集的搭建和服務部署。

Swarm cluster 模式新特性介紹

1. 批量建立服務

1.12引擎中多了docker service命令,和之前的docker run命令類似,但不同的是它能同時對多主機中的容器進行管理操作。下面就以1臺manager節點,5臺worker節點的swarm叢集來闡述這些特性。

首先看下容器的建立:

$ docker network create -d overlay mynet

$ docker service create –replicas 3 –name frontend –network mynet –publish 80:80/tcp frontend_image:latest

$ docker service create –name redis –network mynet redis:latest

建立容器之前先建立一個overlay的網路,用來保證在不同主機上的容器網路互通的網路模式,後面兩條命令用來在同一個名叫mynet的overlay網路裡新建三個相同的web容器副本,和一個 redis副本,並且每個web容器都提供統一的埠對映關係。就像這樣:

2. 強大的叢集的容錯性

既然是叢集,當然難免會出現某幾個節點故障的情況:

當三個web副本中的其中兩臺web節點宕機後,cluster會根據自己的服務註冊發現機制,以及之前設定的值–replicas 3,在叢集中剩餘的空閒節點上,重新拉起兩個web副本。不難看出,docker service其實不僅僅是批量啟動服務這麼簡單,而是在叢集中定義了一種狀態。Cluster會持續檢測服務的健康狀態並維護叢集的高可用性。

新節點的分佈示意圖如下:

3. 服務節點的可擴充套件性

Swarm Cluster不光只是提供了優秀的高可用性,同時也提供了節點彈性擴充套件的功能。當web這個容器組想動態擴充套件至六個節點個數時,只需執行$ docker service scale frontend=6就能立刻複製出三個新的副本出來。

眼尖的朋友可能注意到了,所有擴展出來的新web副本節點都run在原先的web節點下面,如果有需求想在每臺節點上都run一個相同的副本有沒有辦法呢?答案也是肯定的:

$ docker service create –mode=global –name extend_frontend frontend_image:latest

一條命令分分鐘搞定!

4. 排程機制

Docker1.12的排程機制也值得一提。

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

還是拿剛剛那個例子來說,再加上–constraint引數,就能指定容器只run在伺服器硬碟是SSD的節點上(前提是加入到cluster的節點,在啟動daemon時,本身需要加上引數 --label com.example.storage=”ssd”):

$ docker service create –replicas 3 –name frontend –network mynet –publish 80:80/tcp –constraint engine.labels.com.example.storage=ssd frontend_image:lastest

搭建一個swarm叢集

有了以上這些介紹,我們對swarm cluster 的一些新特性應該有了初步的瞭解 ,下面再看一個模擬網站rolling_update的例項,相信這也是許多平時做版本釋出的devops們真正想要看到的東西。

1. 搭建一個swarm叢集

準備三臺機器

Node1:192.168.133.129

Node2:192.168.133.137

Node3:192.168.133.139

在構建一個swarm cluster前,需在cluster節點的防火牆上放行2377/tcp(cluster 管理埠)、7946/udp(節點間通訊埠)、4789/udp(overlay 網路埠)

首先在node1上執行 $docker swarm init 去啟動一臺cluster manager節點,然後在任意需要新增進叢集的節點上執行docker swarm join –token *** 192.168.133.129:2377 就能將節點加入到cluser(加入到叢集裡的節點身份可在後面自由設定成worker或manager)。現在swarm cluster的節點就像下面的圖一樣,箱子都準備好了,就差貨物往裡面裝了。

通過$docker node ls能看到所有swarm節點的執行狀態:

P.S.Swarm cluster的建立過程包含以下三個步驟:

  1. 發現Docker叢集中的各個節點,收集節點狀態、角色資訊,並監視節點狀態的變化

  2. 初始化內部排程(scheduler)模組

  3. 建立並啟動API監聽服務模組

一旦建立好這個cluster,就可以用命令docker service批量對叢集內的容器進行操作。搭建cluster只有兩步,是不是非常酷?

2. 製作一個演示用的demo映象

映象中存放一個python寫的簡單的http web服務:env.py,目的是顯示容器的containerID:

from flask import Flask

import os

app = Flask(__name__)

@app.route("/")

def env():

return os.environ["HOSTNAME"]

app.run(host="0.0.0.0")

3. 用swarm mode建立service task

有了這個映象,然後通過docker service create命令去建立一個名叫test的task:

$ docker service create --name test -p 5000:5000 demo python env.py

用docker ps看一眼

欸?為什麼沒有起來呢?再用docker service ls 檢視task的狀態:

注意這個REPOLICAS的值,0/1說明docker create 已經建立了一個副本但是還沒有起來,稍等一會再執行一遍命令:

補充:

一些情況下已經運行了容器,可是執行docker ps在本機還是看不到容器,為什麼呢?

其實,docker 會根據當前每個swarm節點的負載判斷,在負載最優的節點執行這個task任務,用docker service ps + taskID 可以看到任務執行在哪個節點上。

好了container已經起來了並且執行在node1上

用瀏覽器開啟地址能看到容器對應的ID:

4. 增加service節點

有了單個容器例項之後,下一步再嘗試下動態擴充套件例項個數

$ docker service scale test=6

Node1:

Node2

Node3

一條命令讓現在swarm cluster裡三臺節點,每臺都運行了兩個test副本例項。

此時你是不是已經留意到,一個天然的HA叢集出現了。docker會把對每個host的http請求依據輪詢演算法,均勻地傳送到每個task副本上。

5. 模擬其中一個swarm cluster節點離線的情況

正常來講讓一個swarm cluster中的一個node退出叢集的方式,是在要推出的節點上執行$ docker swarm leave命令,但是為了讓實驗更瘋狂,我在node3上直接stop docker的daemon

再去剩餘兩個節點上任意一個檢視task狀態:

原本在node3上執行的兩個test任務:test3、test4,分別在node1和node2兩臺host上被來起來了。整個副本遷移的過程無需人工干預,遷移後原本的叢集的load balance依舊好使!