Docker(六):Docker 三剑客之 Docker Swarm
實踐中會發(fā)現(xiàn),生產(chǎn)環(huán)境中使用單個 Docker 節(jié)點是遠遠不夠的,搭建 Docker 集群勢在必行。然而,面對 Kubernetes, Mesos 以及 Swarm 等眾多容器集群系統(tǒng),我們該如何選擇呢?它們之中,Swarm 是 Docker 原生的,同時也是最簡單,最易學(xué),最節(jié)省資源的,比較適合中小型公司使用。
Docker Swarm 介紹
Swarm 在 Docker 1.12 版本之前屬于一個獨立的項目,在 Docker 1.12 版本發(fā)布之后,該項目合并到了 Docker 中,成為 Docker 的一個子命令。目前,Swarm 是 Docker 社區(qū)提供的唯一一個原生支持 Docker 集群管理的工具。它可以把多個 Docker 主機組成的系統(tǒng)轉(zhuǎn)換為單一的虛擬 Docker 主機,使得容器可以組成跨主機的子網(wǎng)網(wǎng)絡(luò)。
Docker Swarm 是一個為 IT 運維團隊提供集群和調(diào)度能力的編排工具。用戶可以把集群中所有 Docker Engine 整合進一個「虛擬 Engine」的資源池,通過執(zhí)行命令與單一的主 Swarm 進行溝通,而不必分別和每個 Docker Engine 溝通。在靈活的調(diào)度策略下,IT 團隊可以更好地管理可用的主機資源,保證應(yīng)用容器的高效運行。
Docker Swarm 優(yōu)點
任何規(guī)模都有高性能表現(xiàn)
對于企業(yè)級的 Docker Engine 集群和容器調(diào)度而言,可拓展性是關(guān)鍵。任何規(guī)模的公司——不論是擁有五個還是上千個服務(wù)器——都能在其環(huán)境下有效使用 Swarm。?
經(jīng)過測試,Swarm 可拓展性的極限是在 1000 個節(jié)點上運行 50000 個部署容器,每個容器的啟動時間為亞秒級,同時性能無減損。
靈活的容器調(diào)度
Swarm 幫助 IT 運維團隊在有限條件下將性能表現(xiàn)和資源利用最優(yōu)化。Swarm 的內(nèi)置調(diào)度器(scheduler)支持多種過濾器,包括:節(jié)點標(biāo)簽,親和性和多種容器部策略如 binpack、spread、random 等等。
服務(wù)的持續(xù)可用性
Docker Swarm 由 Swarm Manager 提供高可用性,通過創(chuàng)建多個 Swarm master 節(jié)點和制定主 master 節(jié)點宕機時的備選策略。如果一個 master 節(jié)點宕機,那么一個 slave 節(jié)點就會被升格為 master 節(jié)點,直到原來的 master 節(jié)點恢復(fù)正常。?
此外,如果某個節(jié)點無法加入集群,Swarm 會繼續(xù)嘗試加入,并提供錯誤警報和日志。在節(jié)點出錯時,Swarm 現(xiàn)在可以嘗試把容器重新調(diào)度到正常的節(jié)點上去。
和 Docker API 及整合支持的兼容性?
Swarm 對 Docker API 完全支持,這意味著它能為使用不同 Docker 工具(如 Docker CLI,Compose,Trusted Registry,Hub 和 UCP)的用戶提供無縫銜接的使用體驗。
Docker Swarm 為 Docker 化應(yīng)用的核心功能(諸如多主機網(wǎng)絡(luò)和存儲卷管理)提供原生支持。開發(fā)的 Compose 文件能(通過 docker-compose up )輕易地部署到測試服務(wù)器或 Swarm 集群上。Docker Swarm 還可以從 Docker Trusted Registry 或 Hub 里 pull 并 run 鏡像。
綜上所述,Docker Swarm 提供了一套高可用 Docker 集群管理的解決方案,完全支持標(biāo)準(zhǔn)的 Docker API,方便管理調(diào)度集群 Docker 容器,合理充分利用集群主機資源。
* 并非所有服務(wù)都應(yīng)該部署在Swarm集群內(nèi)。數(shù)據(jù)庫以及其它有狀態(tài)服務(wù)就不適合部署在Swarm集群內(nèi)。*
相關(guān)概念
節(jié)點
運行 Docker 的主機可以主動初始化一個 Swarm 集群或者加入一個已存在的 Swarm 集群,這樣這個運行 Docker 的主機就成為一個 Swarm 集群的節(jié)點 (node) 。節(jié)點分為管理 (manager) 節(jié)點和工作 (worker) 節(jié)點。
管理節(jié)點用于 Swarm 集群的管理,docker swarm 命令基本只能在管理節(jié)點執(zhí)行(節(jié)點退出集群命令 docker swarm leave 可以在工作節(jié)點執(zhí)行)。一個 Swarm 集群可以有多個管理節(jié)點,但只有一個管理節(jié)點可以成為 leader,leader 通過 raft 協(xié)議實現(xiàn)。
工作節(jié)點是任務(wù)執(zhí)行節(jié)點,管理節(jié)點將服務(wù) (service) 下發(fā)至工作節(jié)點執(zhí)行。管理節(jié)點默認(rèn)也作為工作節(jié)點。你也可以通過配置讓服務(wù)只運行在管理節(jié)點。下圖展示了集群中管理節(jié)點與工作節(jié)點的關(guān)系。
服務(wù)和任務(wù)
任務(wù) (Task)是 Swarm 中的最小的調(diào)度單位,目前來說就是一個單一的容器。?
服務(wù) (Services) 是指一組任務(wù)的集合,服務(wù)定義了任務(wù)的屬性。服務(wù)有兩種模式:
- replicated services 按照一定規(guī)則在各個工作節(jié)點上運行指定個數(shù)的任務(wù)。
- global services 每個工作節(jié)點上運行一個任務(wù)
兩種模式通過 docker service create 的 –mode 參數(shù)指定。下圖展示了容器、任務(wù)、服務(wù)的關(guān)系。
創(chuàng)建 Swarm 集群
我們知道 Swarm 集群由管理節(jié)點和工作節(jié)點組成。我們來創(chuàng)建一個包含一個管理節(jié)點和兩個工作節(jié)點的最小 Swarm 集群。
初始化集群
查看虛擬主機,現(xiàn)在沒有
docker-machine ls NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS- 1
- 2
使用 virtualbox 創(chuàng)建管理節(jié)點
docker-machine create --driver virtualbox manager1 #進入管理節(jié)點 docker-machine ssh manager1- 1
- 2
- 3
執(zhí)行 sudo -i 可以進入Root 權(quán)限
我們使用 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:2377To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
如果你的 Docker 主機有多個網(wǎng)卡,擁有多個 IP,必須使用 –advertise-addr 指定 IP。?
執(zhí)行 docker swarm init 命令的節(jié)點自動成為管理節(jié)點。
命令?docker info?可以查看 swarm 集群狀態(tài):
Containers: 0 Running: 0 Paused: 0 Stopped: 0...snip... Swarm: activeNodeID: dxn1zf6l61qsb1josjja83ngzIs Manager: trueManagers: 1Nodes: 1...snip...- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
命令?docker node ls?可以查看集群節(jié)點信息:
docker@manager1:~$ docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS 1ipck4z2uuwf11f4b9mnon2ul * manager1 Ready Active Leader- 1
- 2
- 3
退出虛擬主機
docker@manager1:~$ exit- 1
增加工作節(jié)點
上一步初始化了一個 Swarm 集群,擁有了一個管理節(jié)點,在 Docker Machine 一節(jié)中我們了解到 Docker Machine 可以在數(shù)秒內(nèi)創(chuàng)建一個虛擬的 Docker 主機,下面我們使用它來創(chuàng)建兩個 Docker 主機,并加入到集群中。
創(chuàng)建虛擬主機 worker1
創(chuàng)建主機
$ docker-machine create -d virtualbox worker1- 1
進入虛擬主機 worker1
$ docker-machine ssh worker1- 1
加入 swarm 集群
docker@worker1:~$ docker swarm join \--token SWMTKN-1-47z6jld2o465z30dl7pie2kqe4oyug4fxdtbgkfjqgybsy4esl-8r55lxhxs7ozfil45gedd5b8a \192.168.99.100:2377This node joined a swarm as a worker.- 1
- 2
- 3
- 4
- 5
退出虛擬主機
docker@worker1:~$ exit- 1
創(chuàng)建虛擬主機 worker2
創(chuàng)建
$ docker-machine create -d virtualbox worker2- 1
入虛擬主機worker2
$ docker-machine ssh worker2- 1
加入 swarm 集群
docker@worker2:~$ docker swarm join \--token SWMTKN-1-47z6jld2o465z30dl7pie2kqe4oyug4fxdtbgkfjqgybsy4esl-8r55lxhxs7ozfil45gedd5b8a \192.168.99.100:2377This node joined a swarm as a worker.- 1
- 2
- 3
- 4
- 5
退出虛擬主機
docker@worker2:~$ exit- 1
兩個工作節(jié)點添加完成
查看集群
進入管理節(jié)點:
docker-machine ssh manager1- 1
宿主機子上查看虛擬主機
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- 1
- 2
- 3
- 4
- 5
在主節(jié)點上面執(zhí)行 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- 1
- 2
- 3
- 4
- 5
這樣我們就創(chuàng)建了一個最小的 Swarm 集群,包含一個管理節(jié)點和兩個工作節(jié)點。
部署服務(wù)
我們使用 docker service 命令來管理 Swarm 集群中的服務(wù),該命令只能在管理節(jié)點運行。
新建服務(wù)
進入集群管理節(jié)點:
docker-machine ssh manager1- 1
使用 docker 中國鏡像
docker search alpine docker pull registry.docker-cn.com/library/alpine- 1
- 2
現(xiàn)在我們在上一節(jié)創(chuàng)建的 Swarm 集群中運行一個名為 helloworld 服務(wù)。
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- 1
- 2
- 3
- 4
- 5
命令解釋:
- docker service create?命令創(chuàng)建一個服務(wù)
- --name?服務(wù)名稱命名為?helloworld
- --replicas?設(shè)置啟動的示例數(shù)
- alpine指的是使用的鏡像名稱,ping ityouknow.com指的是容器運行的bash
使用命令?docker service ps rwpw7eij4v6h6716jvqvpxbyv?可以查看服務(wù)進展
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- 1
- 2
- 3
使用 docker service ls 來查看當(dāng)前 Swarm 集群運行的服務(wù)。
docker@manager1:~$ docker service ls ID NAME MODE REPLICAS IMAGE PORTS yzfmyggfky8c helloworld replicated 0/1 alpine:latest- 1
- 2
- 3
監(jiān)控集群狀態(tài)
登錄管理節(jié)點 manager1
docker-machine ssh manager1- 1
運行?docker service inspect --pretty <SERVICE-ID>?查詢服務(wù)概要狀態(tài),以 helloworld 服務(wù)為例:
docker@manager1:~$ docker service inspect --pretty helloworldID: rwpw7eij4v6h6716jvqvpxbyv Name: helloworld Service Mode: ReplicatedReplicas: 1 Placement: UpdateConfig:Parallelism: 1On failure: pauseMonitoring Period: 5sMax failure ratio: 0...Rollback order: stop-first ContainerSpec:Image: alpine:latest@sha256:7b848083f93822dd21b0a2f14a110bd99f6efb4b838d499df6d04a49d0debf8bArgs: ping ityouknow.com Resources: Endpoint Mode: vip- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
運行?docker service inspect helloworld?查詢服務(wù)詳細信息。
運行docker service ps <SERVICE-ID>?查看那個節(jié)點正在運行服務(wù):
docker@manager1:~$ docker service ps helloworld NAME IMAGE NODE DESIRED STATE LAST STATE helloworld.1.8p1vev3fq5zm0mi8g0as41w35 alpine worker1 Running Running 3 minutes- 1
- 2
- 3
在工作節(jié)點查看任務(wù)的執(zhí)行情況
docker-machine ssh worker1- 1
在節(jié)點執(zhí)行docker ps?查看容器的運行狀態(tài)。
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- 1
- 2
- 3
這樣的話,我們在 Swarm 集群中成功的運行了一個 helloworld 服務(wù),根據(jù)命令可以看出在 worker1 節(jié)點上運行。
彈性伸縮實驗
我們來做一組實驗來感受 Swarm 強大的動態(tài)水平擴展特性,首先動態(tài)調(diào)整服務(wù)實例個數(shù)。
調(diào)整實例個數(shù)
增加或者減少服務(wù)的節(jié)點數(shù)
調(diào)整 helloworld 的服務(wù)實例數(shù)為2個
docker service update --replicas 2 helloworld- 1
查看那個節(jié)點正在運行服務(wù):
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- 1
- 2
- 3
- 4
調(diào)整 helloworld 的服務(wù)實例數(shù)為1個
docker service update --replicas 1 helloworld- 1
再次查看節(jié)點運行情況:
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- 1
- 2
- 3
再次調(diào)整 helloworld 的服務(wù)實例數(shù)為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- 1
- 2
- 3
- 4
- 5
- 6
- 7
查看節(jié)點運行情況:
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- 1
- 2
- 3
- 4
- 5
刪除集群服務(wù)
docker service rm helloworld- 1
調(diào)整集群大小
動態(tài)調(diào)整 Swarm 集群的工作節(jié)點。
添加集群
創(chuàng)建虛擬主機 worker3
$ docker-machine create -d virtualbox worker3- 1
入虛擬主機 worker3
$ docker-machine ssh worker3- 1
加入swarm 集群
docker@worker3:~$ docker swarm join \--token SWMTKN-1-47z6jld2o465z30dl7pie2kqe4oyug4fxdtbgkfjqgybsy4esl-8r55lxhxs7ozfil45gedd5b8a \192.168.99.100:2377This node joined a swarm as a worker.- 1
- 2
- 3
- 4
- 5
退出虛擬主機
docker@worker3:~$exit- 1
在主節(jié)點上面執(zhí)行 docker node ls 查詢集群主機信息
登錄主節(jié)點
docker-machine ssh manager1- 1
查看集群節(jié)點
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- 1
- 2
- 3
- 4
- 5
- 6
可以看出集群節(jié)點多了 worker3
退出 Swarm 集群
如果 Manager 想要退出 Swarm 集群, 在 Manager Node 上執(zhí)行如下命令:
docker swarm leave- 1
就可以退出集群,如果集群中還存在其它的 Worker Node,還希望 Manager 退出集群,則加上一個強制選項,命令行如下所示:
docker swarm leave --force- 1
在 Worker2 上進行退出測試,登錄 worker2 節(jié)點
docker-machine ssh worker2- 1
執(zhí)行退出命令
docker swarm leave- 1
查看集群節(jié)點情況:
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- 1
- 2
- 3
- 4
- 5
- 6
可以看出集群節(jié)點 worker2 狀態(tài)已經(jīng)下線
也可以再次加入
docker@worker2:~$ docker swarm join \ > --token SWMTKN-1-47z6jld2o465z30dl7pie2kqe4oyug4fxdtbgkfjqgybsy4esl-8r55lxhxs7ozfil45gedd5b8a \ > 192.168.99.100:2377 This node joined a swarm as a worker.- 1
- 2
- 3
- 4
再次查看
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- 1
- 2
- 3
- 4
- 5
- 6
- 7
可以看出集群節(jié)點 worker2 又重新加入到了集群中
重新搭建命令
使用 VirtualBox 做測試的時候,如果想重復(fù)實驗可以將實驗節(jié)點刪掉再重來。
//停止虛擬機 docker-machine stop [arg...] //一個或多個虛擬機名稱docker-machine stop manager1 worker1 worker2- 1
- 2
- 3
- 4
- 1
- 2
- 3
- 4
停止、刪除虛擬主機后,再重新創(chuàng)建即可。
總結(jié)
通過對 Swarm 的學(xué)習(xí),強烈感覺到自動化水平擴展的魅力,這樣在公司流量爆發(fā)的時候,只需要執(zhí)行一個命令就可以完成實例上線。如果再根據(jù)公司的業(yè)務(wù)流量做自動化控制,那就真正實現(xiàn)了完全自動的動態(tài)伸縮。
舉個例子,我們可以利用腳本監(jiān)控公司的業(yè)務(wù)流量,當(dāng)流量是某個級別的時候我們啟動對應(yīng)的N個節(jié)點數(shù),當(dāng)流量減少的時候我們也動態(tài)的減少服務(wù)實例個數(shù),既可以節(jié)省公司資源,也不用操心業(yè)務(wù)爆發(fā)被流量擊垮。Docker 能發(fā)展的這么好還是有原因的,容器化是 DevOps 最重要的一個環(huán)節(jié),未來容器化的技術(shù)會越來越豐富和完善,智能化運維可期待。
總結(jié)
以上是生活随笔為你收集整理的Docker(六):Docker 三剑客之 Docker Swarm的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Docker(五):Docker 三剑客
- 下一篇: Spring Boot 2.0(四):使