一、Swarm介紹
Docker Swarm是管理跨節(jié)點(diǎn)容器的編排工具,相較于Docker Compose而言,Compose只能編排單節(jié)點(diǎn)上的容器,Swarm將一群Docker節(jié)點(diǎn)虛擬化為一個(gè)主機(jī),使得用戶只要在單一主機(jī)上操作就能完成對(duì)整個(gè)容器集群的管理工作。如果下載的是最新版的Docker,那么Swarm就已經(jīng)被包含在內(nèi)了,無(wú)需再安裝。
Docker Swarm架構(gòu)包含兩種角色,manager和node,前者是Swarm Daemon工作的節(jié)點(diǎn),包含了調(diào)度器、路由、服務(wù)發(fā)現(xiàn)等功能,負(fù)責(zé)接收客戶端的集群管理請(qǐng)求,然后調(diào)度Node進(jìn)行具體的容器工作,比如容器的創(chuàng)建、擴(kuò)容與銷毀等。 manager本身也是一個(gè)node。

通常情況下,為了集群的高可用,manager個(gè)數(shù)>=3的奇數(shù),node的個(gè)數(shù)則是不限制。
二、Swarm實(shí)例
2.1 準(zhǔn)備工作
我們需要準(zhǔn)備好三個(gè)節(jié)點(diǎn),并在各自節(jié)點(diǎn)上安裝好Docker Engine,才能進(jìn)行接下來(lái)的實(shí)例搭建。
此處,我們選擇購(gòu)買阿里云的三個(gè)ECS云服務(wù)器,它們都是在一個(gè)地域里面,對(duì)應(yīng)的私有地址IP和修改的host name分別是:
172.25.206.125 ————作為node1
172.25.206.126 ————作為node2
172.22.147.207 ————作為manager
我們首先需要重置root的登錄密碼,然后ssh登錄后,確保相互之間可以ping通,然后再繼續(xù)下面的操作。一般三臺(tái)機(jī)器如果都在同一個(gè)區(qū)的話,使用私有地址相互之間肯定是聯(lián)通的。
然后登錄各個(gè)容器內(nèi)部的命令行,進(jìn)行Docker Engine的安裝,該步驟可以參考另外一篇文章:《CentOS系統(tǒng)安裝Docker》,安裝完成后可以執(zhí)行docker --version進(jìn)行查看,務(wù)必確保全部安裝成功以后再進(jìn)入下面的步驟。
2.1 創(chuàng)建集群
在創(chuàng)建集群之前,我們使用docker node ls想查看下集群中節(jié)點(diǎn)的信息,反饋目前沒(méi)有節(jié)點(diǎn)信息,并且當(dāng)前節(jié)點(diǎn)并不是manager。
[root@manager ~]# docker node ls
Error response from daemon: This node is not a swarm manager. Use "docker swarm init" or "docker swarm join" to connect this node to swarm and try again.
那么我們首先就在manager這個(gè)節(jié)點(diǎn)上執(zhí)行如下操作,表示要將它設(shè)置為manager,并且設(shè)置自己的通訊IP為172.22.147.207。
[root@manager ~]# docker swarm init --advertise-addr 172.22.147.207
Swarm initialized: current node (s0eoali1x32ly22jo85ebeb0w) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-57msikozxxt44uxz5r8hihmakp4zh1cr89v7zlxhyc8b5iojkt-5ea8uh68jcuy8m6f9ma7x0zg5 172.22.147.207:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
如上就完成了manager節(jié)點(diǎn)的設(shè)置,并且得到提示信息如下:
- 可以在其它節(jié)點(diǎn)上執(zhí)行
docker swarm join --token......來(lái)將該節(jié)點(diǎn)設(shè)置為工作node,并加入到這個(gè)swarm集群中; - 可以在其它節(jié)點(diǎn)上執(zhí)行
docker swarm join-token manager來(lái)獲取下一步執(zhí)行指令,執(zhí)行該指令后,該節(jié)點(diǎn)將設(shè)置為manager從節(jié)點(diǎn)加入到這個(gè)swarm集群中;
我們目前演示的是一個(gè)manager,兩個(gè)工作node的模式,所以在另外兩臺(tái)node1和node2上執(zhí)行第一個(gè)命令即可:
[root@node1 ~]# docker swarm join --token SWMTKN-1-57msikozxxt44uxz5r8hihmakp4zh1cr89v7zlxhyc8b5iojkt-5ea8uh68jcuy8m6f9ma7x0zg5 172.22.147.207:2377
This node joined a swarm as a worker.
如此,一個(gè)swarm集群就算搭建完成了。
2.2 使用集群
manager是我們管理集群的入口,我們的docker命令都是在manager上執(zhí)行,node節(jié)點(diǎn)上是不能執(zhí)行dockr命令的,這一點(diǎn)要十分牢記。
-
查看當(dāng)前節(jié)點(diǎn)信息;
[root@manager ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION s0eoali1x32ly22jo85ebeb0w * manager Ready Active Leader 20.10.11 7kuhm78bs3zrfkm2n28ukje25 node1 Ready Active 20.10.11 io4qmqb87yzpmmo2mpblj48fp node2 Ready Active 20.10.11 -
創(chuàng)建一個(gè)私有網(wǎng)絡(luò),供不同節(jié)點(diǎn)上的容器互通使用;網(wǎng)絡(luò)相關(guān)參考Docker網(wǎng)絡(luò)互聯(lián)原理及自定義網(wǎng)絡(luò)的使用
[root@manager ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 45f6a352dcd2 bridge bridge local 2b71198e802e docker_gwbridge bridge local 679154a40c18 host host local 1ntnd2ruk0tp ingress overlay swarm 6d6218b5a31f none null local [root@manager ~]# docker network create -d overlay niginx_network ldb1i69hxdsdo6un8yhaddhnv [root@manager ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 45f6a352dcd2 bridge bridge local 2b71198e802e docker_gwbridge bridge local 679154a40c18 host host local 1ntnd2ruk0tp ingress overlay swarm ldb1i69hxdsd niginx_network overlay swarm 6d6218b5a31f none null local -
使用指定的網(wǎng)絡(luò)部署一個(gè)服務(wù);
[root@manager ~]# docker service create --replicas 1 --network niginx_network --name my_nginx -p 80:80 nginx:latest q03ljoy94xkdeicb7d9tx422b overall progress: 1 out of 1 tasks 1/1: running [==================================================>] verify: Service converged如上使用nginx:latest鏡像創(chuàng)建了一個(gè)容器,容器名稱為my_nginx,對(duì)外暴露80端口;
-
查看運(yùn)行中的服務(wù)列表;
[root@manager ~]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS q03ljoy94xkd my_nginx replicated 1/1 nginx:latest *:80->80/tcp -
查看某個(gè)服務(wù)在哪個(gè)節(jié)點(diǎn)上運(yùn)行;
[root@manager ~]# docker service ps my_nginx ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS wf5h6u13zel6 my_nginx.1 nginx:latest manager Running Running 2 minutes ago除此之外,我們還可以在每一臺(tái)服務(wù)器上使用
docker ps來(lái)看看運(yùn)行了哪些容器; -
動(dòng)態(tài)擴(kuò)縮容某個(gè)服務(wù)的容器個(gè)數(shù);
[root@manager ~]# docker service scale my_nginx=4 my_nginx scaled to 4 overall progress: 4 out of 4 tasks 1/4: running [==================================================>] 2/4: running [==================================================>] 3/4: running [==================================================>] 4/4: running [==================================================>] verify: Service converged [root@manager ~]# docker service ls ID NAME MODE REPLICAS IMAGE PORTS q03ljoy94xkd my_nginx replicated 4/4 nginx:latest *:80->80/tcp [root@manager ~]# docker service ps my_nginx ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS wf5h6u13zel6 my_nginx.1 nginx:latest manager Running Running 8 minutes ago kke3fl9sxdjm my_nginx.2 nginx:latest node1 Running Running 27 seconds ago 0ds3p18dmc9r my_nginx.3 nginx:latest node1 Running Running 27 seconds ago 32kyyibu9j12 my_nginx.4 nginx:latest node2 Running Running 25 seconds ago使用update命令也是等價(jià)的:
docker service update --replicas 3 my_nginx; -
下線一個(gè)節(jié)點(diǎn),使之不參與任務(wù)分派;
[root@manager ~]# docker node update --availability drain node2 node2 [root@manager ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION s0eoali1x32ly22jo85ebeb0w * manager Ready Active Leader 20.10.11 7kuhm78bs3zrfkm2n28ukje25 node1 Ready Active 20.10.11 io4qmqb87yzpmmo2mpblj48fp node2 Ready Drain 20.10.11值得一提的是,如果某個(gè)節(jié)點(diǎn)被設(shè)置下線,或者因?yàn)槠渌收襄礄C(jī)了,那么它其上的容器會(huì)被轉(zhuǎn)移到其它可運(yùn)行的節(jié)點(diǎn)上,如此來(lái)保證始終有指定副本數(shù)量的容器在運(yùn)行。
-
上線一個(gè)下線中的節(jié)點(diǎn),使之參與任務(wù)分派;
[root@manager ~]# docker node update --availability active node2 node2 -
移除一個(gè)任務(wù),使得集群中所有該任務(wù)的容器都刪除;
[root@manager ~]# docker service update --replicas 4 my_nginx my_nginx overall progress: 4 out of 4 tasks 1/4: running [==================================================>] 2/4: running [==================================================>] 3/4: running [==================================================>] 4/4: running [==================================================>] verify: Service converged [root@manager ~]# docker service ps my_nginx ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS wf5h6u13zel6 my_nginx.1 nginx:latest manager Running Running 18 minutes ago q9soig9jmkik my_nginx.2 nginx:latest node2 Running Running 13 seconds ago hqti23fox6ui my_nginx.3 nginx:latest node1 Running Running 13 seconds ago wgm2xaqd147p my_nginx.4 nginx:latest node2 Running Running 13 seconds ago 32kyyibu9j12 \_ my_nginx.4 nginx:latest node2 Shutdown Shutdown 7 minutes ago [root@manager ~]# docker service rm my_nginx my_nginx [root@manager ~]# docker service ps my_nginx no such service: my_nginx -
節(jié)點(diǎn)離開(kāi)集群;
[root@node1 ~]# docker swarm leave Node left the swarm.[root@manager ~]# docker node ls ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION s0eoali1x32ly22jo85ebeb0w * manager Ready Active Leader 20.10.11 7kuhm78bs3zrfkm2n28ukje25 node1 Down Active 20.10.11 io4qmqb87yzpmmo2mpblj48fp node2 Ready Active 20.10.11 -
刪除swarm集群;
[root@manager ~]# docker swarm leave Error response from daemon: You are attempting to leave the swarm on a node that is participating as a manager. Removing the last manager erases all current state of the swarm. Use `--force` to ignore this message. [root@manager ~]# docker swarm leave -f Node left the swarm.當(dāng)最后一個(gè)manager節(jié)點(diǎn)離開(kāi),則swarm集群自動(dòng)刪除。