實踐中會發現,生產環境中使用單個 Docker 節點是遠遠不夠的,搭建 Docker 集羣勢在必行。然而,面對 Kubernetes, Mesos 以及 Swarm 等衆多容器集羣系統,咱們該如何選擇呢?它們之中,Swarm 是 Docker 原生的,同時也是最簡單,最易學,最節省資源的,比較適合中小型公司使用。html
Swarm 在 Docker 1.12 版本以前屬於一個獨立的項目,在 Docker 1.12 版本發佈以後,該項目合併到了 Docker 中,成爲 Docker 的一個子命令。目前,Swarm 是 Docker 社區提供的惟一一個原生支持 Docker 集羣管理的工具。它能夠把多個 Docker 主機組成的系統轉換爲單一的虛擬 Docker 主機,使得容器能夠組成跨主機的子網網絡。node
Docker Swarm 是一個爲 IT 運維團隊提供集羣和調度能力的編排工具。用戶能夠把集羣中全部 Docker Engine 整合進一個「虛擬 Engine」的資源池,經過執行命令與單一的主 Swarm 進行溝通,而沒必要分別和每一個 Docker Engine 溝通。在靈活的調度策略下,IT 團隊能夠更好地管理可用的主機資源,保證應用容器的高效運行。docker
任何規模都有高性能表現數據庫
對於企業級的 Docker Engine 集羣和容器調度而言,可拓展性是關鍵。任何規模的公司——不管是擁有五個仍是上千個服務器——都能在其環境下有效使用 Swarm。
通過測試,Swarm 可拓展性的極限是在 1000 個節點上運行 50000 個部署容器,每一個容器的啓動時間爲亞秒級,同時性能無減損。bash
靈活的容器調度服務器
Swarm 幫助 IT 運維團隊在有限條件下將性能表現和資源利用最優化。Swarm 的內置調度器(scheduler)支持多種過濾器,包括:節點標籤,親和性和多種容器部策略如 binpack、spread、random 等等。網絡
服務的持續可用性運維
Docker Swarm 由 Swarm Manager 提供高可用性,經過建立多個 Swarm master 節點和制定主 master 節點宕機時的備選策略。若是一個 master 節點宕機,那麼一個 slave 節點就會被升格爲 master 節點,直到原來的 master 節點恢復正常。
此外,若是某個節點沒法加入集羣,Swarm 會繼續嘗試加入,並提供錯誤警報和日誌。在節點出錯時,Swarm 如今能夠嘗試把容器從新調度到正常的節點上去。dom
和 Docker API 及整合支持的兼容性
Swarm 對 Docker API 徹底支持,這意味着它能爲使用不一樣 Docker 工具(如 Docker CLI,Compose,Trusted Registry,Hub 和 UCP)的用戶提供無縫銜接的使用體驗。ssh
Docker Swarm 爲 Docker 化應用的核心功能(諸如多主機網絡和存儲卷管理)提供原生支持。開發的 Compose 文件能(經過 docker-compose up )輕易地部署到測試服務器或 Swarm 集羣上。Docker Swarm 還能夠從 Docker Trusted Registry 或 Hub 裏 pull 並 run 鏡像。
綜上所述,Docker Swarm 提供了一套高可用 Docker 集羣管理的解決方案,徹底支持標準的 Docker API,方便管理調度集羣 Docker 容器,合理充分利用集羣主機資源。
** 並不是全部服務都應該部署在Swarm集羣內。數據庫以及其它有狀態服務就不適合部署在Swarm集羣內。**
運行 Docker 的主機能夠主動初始化一個 Swarm 集羣或者加入一個已存在的 Swarm 集羣,這樣這個運行 Docker 的主機就成爲一個 Swarm 集羣的節點 (node) 。節點分爲管理 (manager) 節點和工做 (worker) 節點。
管理節點用於 Swarm 集羣的管理,docker swarm 命令基本只能在管理節點執行(節點退出集羣命令 docker swarm leave 能夠在工做節點執行)。一個 Swarm 集羣能夠有多個管理節點,但只有一個管理節點能夠成爲 leader,leader 經過 raft 協議實現。
工做節點是任務執行節點,管理節點將服務 (service) 下發至工做節點執行。管理節點默認也做爲工做節點。你也能夠經過配置讓服務只運行在管理節點。下圖展現了集羣中管理節點與工做節點的關係。
任務 (Task)是 Swarm 中的最小的調度單位,目前來講就是一個單一的容器。
服務 (Services) 是指一組任務的集合,服務定義了任務的屬性。服務有兩種模式:
兩種模式經過 docker service create 的 --mode 參數指定。下圖展現了容器、任務、服務的關係。
咱們知道 Swarm 集羣由管理節點和工做節點組成。咱們來建立一個包含一個管理節點和兩個工做節點的最小 Swarm 集羣。
查看虛擬主機,如今沒有
docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
使用 virtualbox 建立管理節點
docker-machine create --driver virtualbox manager1 #進入管理節點 docker-machine ssh manager1
執行 sudo -i 能夠進入Root 權限
咱們使用 docker swarm init 在 manager1 初始化一個 Swarm 集羣。
docker@manager1:~$ docker swarm init --advertise-addr 192.168.99.100 Swarm initialized: current node (j0o7sykkvi86xpc00w71ew5b6) is now a manager. To add a worker to this swarm, run the following command: docker swarm join --token SWMTKN-1-47z6jld2o465z30dl7pie2kqe4oyug4fxdtbgkfjqgybsy4esl-8r55lxhxs7ozfil45gedd5b8a 192.168.99.100:2377 To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
若是你的 Docker 主機有多個網卡,擁有多個 IP,必須使用 --advertise-addr 指定 IP。
執行 docker swarm init 命令的節點自動成爲管理節點。
命令 docker info
能夠查看 swarm 集羣狀態:
Containers: 0 Running: 0 Paused: 0 Stopped: 0 ...snip... Swarm: active NodeID: dxn1zf6l61qsb1josjja83ngz Is Manager: true Managers: 1 Nodes: 1 ...snip...
命令 docker node ls
能夠查看集羣節點信息:
docker@manager1:~$ docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS 1ipck4z2uuwf11f4b9mnon2ul * manager1 Ready Active Leader
退出虛擬主機
docker@manager1:~$ exit
上一步初始化了一個 Swarm 集羣,擁有了一個管理節點,在 Docker Machine 一節中咱們瞭解到 Docker Machine 能夠在數秒內建立一個虛擬的 Docker 主機,下面咱們使用它來建立兩個 Docker 主機,並加入到集羣中。
建立虛擬主機 worker1
建立主機
$ docker-machine create -d virtualbox worker1
進入虛擬主機 worker1
$ docker-machine ssh worker1
加入 swarm 集羣
docker@worker1:~$ docker swarm join \ --token SWMTKN-1-47z6jld2o465z30dl7pie2kqe4oyug4fxdtbgkfjqgybsy4esl-8r55lxhxs7ozfil45gedd5b8a \ 192.168.99.100:2377 This node joined a swarm as a worker.
退出虛擬主機
docker@worker1:~$ exit
建立虛擬主機 worker2
建立
$ docker-machine create -d virtualbox worker2
入虛擬主機worker2
$ docker-machine ssh worker2
加入 swarm 集羣
docker@worker2:~$ docker swarm join \ --token SWMTKN-1-47z6jld2o465z30dl7pie2kqe4oyug4fxdtbgkfjqgybsy4esl-8r55lxhxs7ozfil45gedd5b8a \ 192.168.99.100:2377 This node joined a swarm as a worker.
退出虛擬主機
docker@worker2:~$ exit
兩個工做節點添加完成
進入管理節點:
docker-machine ssh manager1
宿主機子上查看虛擬主機
docker@manager1:~$ docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS manager1 * virtualbox Running tcp://192.168.99.100:2376 v17.12.1-ce worker1 - virtualbox Running tcp://192.168.99.101:2376 v17.12.1-ce worker2 - virtualbox Running tcp://192.168.99.102:2376 v17.12.1-ce
在主節點上面執行 docker node ls 查詢集羣主機信息
docker@manager1:~$ docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS 1ipck4z2uuwf11f4b9mnon2ul * manager1 Ready Active Leader rtcpqgcn2gytnvufwfveukgrv worker1 Ready Active te2e9tr0qzbetjju5gyahg6f7 worker2 Ready Active
這樣咱們就建立了一個最小的 Swarm 集羣,包含一個管理節點和兩個工做節點。
咱們使用 docker service 命令來管理 Swarm 集羣中的服務,該命令只能在管理節點運行。
進入集羣管理節點:
docker-machine ssh manager1
使用 docker 中國鏡像
docker search alpine docker pull registry.docker-cn.com/library/alpine
如今咱們在上一節建立的 Swarm 集羣中運行一個名爲 helloworld 服務。
docker@manager1:~$ docker service create --replicas 1 --name helloworld alpine ping ityouknow.com rwpw7eij4v6h6716jvqvpxbyv overall progress: 1 out of 1 tasks 1/1: running [==================================================>] verify: Service converged
命令解釋:
docker service create
命令建立一個服務--name
服務名稱命名爲 helloworld
--replicas
設置啓動的示例數alpine
指的是使用的鏡像名稱,ping ityouknow.com
指的是容器運行的bash使用命令 docker service ps rwpw7eij4v6h6716jvqvpxbyv
能夠查看服務進展
docker@manager1:~$ docker service ps rwpw7eij4v6h6716jvqvpxbyv ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS rgroe3s9qa53 helloworld.1 alpine:latest worker1 Running Running about a minute ago
使用 docker service ls 來查看當前 Swarm 集羣運行的服務。
docker@manager1:~$ docker service ls ID NAME MODE REPLICAS IMAGE PORTS yzfmyggfky8c helloworld replicated 0/1 alpine:latest
登陸管理節點 manager1
docker-machine ssh manager1
運行 docker service inspect --pretty <SERVICE-ID>
查詢服務概要狀態,以 helloworld 服務爲例:
docker@manager1:~$ docker service inspect --pretty helloworld ID: rwpw7eij4v6h6716jvqvpxbyv Name: helloworld Service Mode: Replicated Replicas: 1 Placement: UpdateConfig: Parallelism: 1 On failure: pause Monitoring Period: 5s Max failure ratio: 0 ... Rollback order: stop-first ContainerSpec: Image: alpine:latest@sha256:7b848083f93822dd21b0a2f14a110bd99f6efb4b838d499df6d04a49d0debf8b Args: ping ityouknow.com Resources: Endpoint Mode: vip
運行
docker service inspect helloworld
查詢服務詳細信息。
運行docker service ps <SERVICE-ID>
查看那個節點正在運行服務:
docker@manager1:~$ docker service ps helloworld NAME IMAGE NODE DESIRED STATE LAST STATE helloworld.1.8p1vev3fq5zm0mi8g0as41w35 alpine worker1 Running Running 3 minutes
在工做節點查看任務的執行狀況
docker-machine ssh worker1
在節點執行docker ps
查看容器的運行狀態。
docker@worker1:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 96bf5b1d8010 alpine:latest "ping ityouknow.com" 4 minutes ago Up 4 minutes helloworld.1.rgroe3s9qa53lf4u4ky0tzcb8
這樣的話,咱們在 Swarm 集羣中成功的運行了一個 helloworld 服務,根據命令能夠看出在 worker1 節點上運行。
咱們來作一組實驗來感覺 Swarm 強大的動態水平擴展特性,首先動態調整服務實例個數。
增長或者減小服務的節點數
調整 helloworld 的服務實例數爲2個
docker service update --replicas 2 helloworld
查看那個節點正在運行服務:
docker service ps helloworld ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS rgroe3s9qa53 helloworld.1 alpine:latest manager1 Running Running 8 minutes ago a61nqrmfhyrl helloworld.2 alpine:latest worker2 Running Running 9 seconds ago
調整 helloworld 的服務實例數爲1個
docker service update --replicas 1 helloworld
再次查看節點運行狀況:
docker service ps helloworld ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS a61nqrmfhyrl helloworld.2 alpine:latest worker2 Running Running about a minute ago
再次調整 helloworld 的服務實例數爲3個
docker service update --replicas 3 helloworld helloworld overall progress: 3 out of 3 tasks 1/3: running [==================================================>] 2/3: running [==================================================>] 3/3: running [==================================================>] verify: Service converged
查看節點運行狀況:
docker@manager1:~$ docker service ps helloworld ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS mh7ipjn74o0d helloworld.1 alpine:latest worker2 Running Running 40 seconds ago 1w4p9okvz0xw helloworld.2 alpine:latest manager1 Running Running 2 minutes ago snqrbnh4k94y helloworld.3 alpine:latest worker1 Running Running 32 seconds ago
刪除集羣服務
docker service rm helloworld
動態調整 Swarm 集羣的工做節點。
添加集羣
建立虛擬主機 worker3
$ docker-machine create -d virtualbox worker3
入虛擬主機 worker3
$ docker-machine ssh worker3
加入swarm 集羣
docker@worker3:~$ docker swarm join \ --token SWMTKN-1-47z6jld2o465z30dl7pie2kqe4oyug4fxdtbgkfjqgybsy4esl-8r55lxhxs7ozfil45gedd5b8a \ 192.168.99.100:2377 This node joined a swarm as a worker.
退出虛擬主機
docker@worker3:~$exit
在主節點上面執行 docker node ls 查詢集羣主機信息
登陸主節點
docker-machine ssh manager1
查看集羣節點
docker@manager1:~$ docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS j0o7sykkvi86xpc00w71ew5b6 * manager1 Ready Active Leader xwv8aixasqraxwwpox0d0bp2i worker1 Ready Active ij3z1edgj7nsqvl8jgqelrfvy worker2 Ready Active i31yuluyqdboyl6aq8h9nk2t5 worker3 Ready Active
能夠看出集羣節點多了 worker3
退出 Swarm 集羣
若是 Manager 想要退出 Swarm 集羣, 在 Manager Node 上執行以下命令:
docker swarm leave
就能夠退出集羣,若是集羣中還存在其它的 Worker Node,還但願 Manager 退出集羣,則加上一個強制選項,命令行以下所示:
docker swarm leave --force
在 Worker2 上進行退出測試,登陸 worker2 節點
docker-machine ssh worker2
執行退出命令
docker swarm leave
查看集羣節點狀況:
docker@manager1:~$ docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS j0o7sykkvi86xpc00w71ew5b6 * manager1 Ready Active Leader xwv8aixasqraxwwpox0d0bp2i worker1 Ready Active ij3z1edgj7nsqvl8jgqelrfvy worker2 Down Active i31yuluyqdboyl6aq8h9nk2t5 worker3 Ready Active
能夠看出集羣節點 worker2 狀態已經下線
也能夠再次加入
docker@worker2:~$ docker swarm join \ > --token SWMTKN-1-47z6jld2o465z30dl7pie2kqe4oyug4fxdtbgkfjqgybsy4esl-8r55lxhxs7ozfil45gedd5b8a \ > 192.168.99.100:2377 This node joined a swarm as a worker.
再次查看
docker@manager1:~$ docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS j0o7sykkvi86xpc00w71ew5b6 * manager1 Ready Active Leader xwv8aixasqraxwwpox0d0bp2i worker1 Ready Active 0agpph1vtylm421rhnx555kkc worker2 Ready Active ij3z1edgj7nsqvl8jgqelrfvy worker2 Down Active i31yuluyqdboyl6aq8h9nk2t5 worker3 Ready Active
能夠看出集羣節點 worker2 又從新加入到了集羣中
從新搭建命令
使用 VirtualBox 作測試的時候,若是想重複實驗能夠將實驗節點刪掉再重來。
//中止虛擬機 docker-machine stop [arg...] //一個或多個虛擬機名稱 docker-machine stop manager1 worker1 worker2
//移除虛擬機 docker-machine rm [OPTIONS] [arg...] docker-machine rm manager1 worker1 worker2
中止、刪除虛擬主機後,再從新建立便可。
經過對 Swarm 的學習,強烈感受到自動化水平擴展的魅力,這樣在公司流量爆發的時候,只須要執行一個命令就能夠完成實例上線。若是再根據公司的業務流量作自動化控制,那就真正實現了徹底自動的動態伸縮。
舉個例子,咱們能夠利用腳本監控公司的業務流量,當流量是某個級別的時候咱們啓動對應的N個節點數,當流量減小的時候咱們也動態的減小服務實例個數,既能夠節省公司資源,也不用操心業務爆發被流量擊垮。Docker 能發展的這麼好仍是有緣由的,容器化是 DevOps 最重要的一個環節,將來容器化的技術會愈來愈豐富和完善,智能化運維可期待。
Getting started with swarm mode
Docker — 從入門到實踐
關於Docker Swarm的用途詳細介紹