Docker Swarm 和 Docker Compose 同樣,都是 Docker 官方容器編排項目,但不一樣的是,Docker Compose 是一個在單個服務器或主機上建立多個容器的工具,而 Docker Swarm 則能夠在多個服務器或主機上建立容器集羣服務,對於微服務的部署,顯然 Docker Swarm 會更加適合。node
從 Docker 1.12.0 版本開始,Docker Swarm 已經包含在 Docker 引擎中(docker swarm),而且已經內置了服務發現工具,咱們就不須要像以前同樣,再配置 Etcd 或者 Consul 來進行服務發現配置了。web
Docker Swarm集羣中有三個角色:manager(管理者);worker(實際工做者)以及service(服務)。docker
在上面的三個角色中,其本質上與咱們公司的組織架構相似,有領導(manager),有搬磚的(worker),而領導下發給搬磚者的任務,就是Docker Swarm中的service(服務)。vim
須要注意的是,在一個Docker Swarm羣集中,每臺docker服務器的角色能夠都是manager,可是,不能夠都是worker,也就是說,不能夠羣龍無首,而且,參與羣集的全部主機名,千萬不能夠衝突。服務器
這裏經過一個案例來展現Docker Swarm集羣的配置。架構
博文大綱:
1、環境準備
2、配置主機docker01
3、配置docker02及docker03加入Swarm羣集
4、搭建registry私有倉庫
5、docker01部署docker Swarm羣集的web UI界面
6、docker Swarm羣集的service服務配置
7、實現docker容器的擴容及縮容
8、附加——docker Swarm羣集經常使用命令
9、docker Swarm總結ssh
在上述主機中,將指定主機docker01爲manager的角色,其餘主機的角色爲worker。tcp
如下操做,將初始化一個Swarm羣集,並指定docker01的角色爲manager。ide
#因爲須要在三臺主機間複製一些配置文件,因此在docker01上配置免密登陸 [root@docker01 ~]# ssh-keygen #生成密鑰對,一路按回車便可生成 [root@docker01 ~]# tail -3 /etc/hosts #配置/etc/hosts文件 #三臺主機之間要互相解析(Swarm羣集也須要此配置) 192.168.20.6 docker01 192.168.20.7 docker02 192.168.20.8 docker03 [root@docker01 ~]# ssh-copy-id docker02 #將生成的祕鑰發送到docker02 root@docker02 s password: #要輸入docker02的root密碼 [root@docker01 ~]# ssh-copy-id docker03 #將祕鑰發送到docker03,一樣須要輸入docker03的root密碼 [root@docker01 ~]# scp /etc/hosts docker02:/etc/ #將hosts文件發送到docker02 [root@docker01 ~]# scp /etc/hosts docker03:/etc/ #將hosts文件發送到docker03 [root@docker01 ~]# docker swarm init --advertise-addr 192.168.20.6 #初始化一個集羣,並指定本身爲manager
當執行上述操做,指定本身爲manager初始化一個羣組後,則會隨着命令的執行成功而返回一系列的提示信息,這些提示信息給出的是,若是其餘節點須要加入此節點,須要執行的命令,直接對其進行復制,而後,在須要加入此羣集的主機上執行,便可成功加入羣集。微服務
返回的提示信息以下:
在上述中,既然給出了相應的命令,那麼,如今開始配置須要加入羣集的docker服務器。
#docker02執行如下命令: [root@docker02 ~]# docker swarm join --token SWMTKN-1-5ofgk6fh1vey2k7qwsk4gb9yohkxja6hy8les7plecgih1xiw1-3vpemis38suwyxg3efryv5nyu 192.168.20.6:2377 #docker03也執行如下命令 [root@docker03 ~]# docker swarm join --token SWMTKN-1-5ofgk6fh1vey2k7qwsk4gb9yohkxja6hy8les7plecgih1xiw1-3vpemis38suwyxg3efryv5nyu 192.168.20.6:2377 [root@docker01 ~]# docker node promote docker02 #將docker02從worker升級爲manager。
至此,docker02及03便以worker的角色加入到了羣集當中。
若docker02或者docker03要脫離這個羣集,那麼須要如下配置(這裏以docker03爲例):
#將docker03脫離這個羣集 [root@docker03 ~]# docker swarm leave #在docker03上執行此命令 [root@docker01 ~]# docker node rm docker03 #而後在manager角色的服務器上移除docker03 [root@docker01 ~]# docker swarm leave -f #如果最後一個manager上進行刪除羣集,則須要加「-f」選項 #最後一個刪除後,這個羣集也就不存在了
在docker Swarm羣集中,私有倉庫並不影響其羣集的正常運行,只是公司的生產環境多數都是本身的私有倉庫,因此這裏模擬一下。
[root@docker01 ~]# docker run -d --name registry --restart always -p 5000:5000 registry #運行一個registry倉庫容器 [root@docker01 ~]# vim /usr/lib/systemd/system/docker.service #修改docker配置文件,以便指定私有倉庫 ExecStart=/usr/bin/dockerd -H unix:// --insecure-registry 192.168.20.6:5000 #定位到改行,指定私有倉庫IP及端口 #編輯完成後,保存退出便可 [root@docker01 ~]# systemctl daemon-reload #從新加載配置文件 [root@docker01 ~]# systemctl restart docker #重啓docker服務 #docker02及docker03也須要指定私有倉庫的位置,因此執行下面的命令將更改後的docker配置文件複製過去 [root@docker01 ~]# scp /usr/lib/systemd/system/docker.service docker02:/usr/lib/systemd/system/ [root@docker01 ~]# scp /usr/lib/systemd/system/docker.service docker03:/usr/lib/systemd/system/ #將docker的配置文件複製過去之後,須要重啓docker02及03的docker服務 #下面的命令須要在docker02及03的服務器上分別運行一次: [root@docker02 ~]# systemctl daemon-reload [root@docker02 ~]# systemctl restart docker
在私有倉庫完成後,最好測試一下是否能夠正常使用,以下:
#docker01將httpd鏡像上傳到私有倉庫 [root@docker01 ~]# docker tag httpd:latest 192.168.20.6:5000/lvjianzhao:latest [root@docker01 ~]# docker push 192.168.20.6:5000/lvjianzhao:latest #在dokcer02上進行下載,測試是否能夠正常下載 [root@docker02 ~]# docker pull 192.168.20.6:5000/lvjianzhao:latest #能夠正常下載,說明私有倉庫可用
在上面搭建私有倉庫的過程,並無實現數據的持久化,若須要基於數據持久化搭建私有倉庫,能夠參考博文:Docker之Registry私有倉庫+Harbor私有倉庫的搭建。
[root@docker01 ~]# docker run -d -p 8000:8080 -e HOST=172.16.20.6 -e PORT=8080 -v /var/run/docker.sock:/var/run/docker.sock --name visualizer dockersamples/visualizer #執行上述命令後,便可客戶端訪問其8000訪問,能夠看到羣集內的節點信息 #若節點發生故障,則會當即檢測到
訪問docker01的8000端口,便可看到如下界面(該界面只能看,不能進行任何配置):
配置至此,docker Swarm的羣集基本完善了,接下來,開始展現該羣集,究竟能夠作些什麼?也就是到了配置其service服務階段。
一、在docker01(必須在manager角色的主機)上,發佈一個任務,使用剛剛測試時上傳的httpd鏡像,運行六個容器,命令以下:
[root@docker01 ~]# docker service create --replicas 6 --name lvjianzhao -p 80 192.168.20.6:5000/lvjianzhao:latest #上述命令中,「--replicas」選項就是用來指定要運行的容器數量
當運行六個容器副本後,能夠查看羣集的web UI界面,顯示以下:
注意:docker03並無下載相應的鏡像,可是也會運行httpd服務,那麼就能夠得出一個結論:若docker主機沒有指定的鏡像,那麼它將會自動去下載相應的鏡像。
能夠看到,在進行上述配置後,羣集中的三臺服務器基於httpd鏡像運行了兩個容器。共六個:
[root@docker01 ~]# docker service ls #查看service的狀態 ID NAME MODE REPLICAS IMAGE PORTS 13zjbf5s02f8 lvjianzhao replicated 6/6 192.168.20.6:5000/lvjianzhao:latest *:30000->80/tcp
何爲擴容?何爲縮容?無非就是在容器沒法承擔當前負載壓力的狀況下,擴增幾個同樣的容器,縮容呢?也就是在大量容器資源閒置的狀況下,減小几個同樣的容器而已。
1)容器的擴容:
[root@docker01 ~]# docker service scale lvjianzhao=9 #將運行的httpd容器擴容到9個
擴容後,其web UI界面顯示以下:
2)容器的縮容
[root@docker01 ~]# docker service scale lvjianzhao=3 將9個httpd服務的容器縮減到3個
縮容後,其UI界面顯示以下:
在上述的配置中,若運行指定數量的容器,那麼將是羣集中的全部docker主機進行輪詢的方式運行,直到運行夠指定的容器數量,那麼,若是不想讓docker01這個manager角色運行容器呢?(公司領導也不會去一線搬磚的嘛),能夠進行如下配置:
[root@docker01 ~]# docker node update --availability drain docker01 #設置主機docker01之後不運行容器,但已經運行的容器並不會中止 # 「--availability」選項後面共有三個選項可配置,以下: # 「active」:工做;「pause」:暫時不工做;「drain」:永久性的不工做
[root@docker01 ~]# docker node ls #查看羣集的信息(只能夠在manager角色的主機上查看) [root@docker01 ~]# docker swarm join-token worker #若是後期須要加入worker端,能夠執行此命令查看令牌(也就是加入時須要執行的命令) [root@docker01 ~]# docker swarm join-token manager #同上,若要加入manager端,則能夠執行這條命令查看令牌。 [root@docker01 ~]# docker service scale web05=6 #容器的動態擴容及縮容 [root@docker01 ~]# docker service ps web01 #查看建立的容器運行在哪些節點 [root@docker01 ~]# docker service ls #查看建立的服務 #將docker03脫離這個羣集 [root@docker03 ~]# docker swarm leave #docker03脫離這個羣集 [root@docker01 ~]# docker node rm docker03 #而後在manager角色的服務器上移除docker03 [root@docker01 ~]# docker node promote docker02 #將docker02從worker升級爲manager。 #升級後docker02狀態會爲Reachable [root@docker01 ~]# docker node demote docker02 #將docker02從manager角色降級爲worker [root@docker01 ~]# docker node update --availability drain docker01 #設置主機docker01之後不運行容器,但已經運行的容器並不會中止 [root@docker01 ~]# docker node update --label-add mem=max docker03 #更改docker03主機的標籤爲mem=max [root@docker01 ~]# docker service update --replicas 8 --image 192.168.20.6:5000/lvjianzhao:v2.0 --container-label-add 'node.labels.mem==max' lvjianzhao05 #將服務升級爲8個容器,而且指定在mem=max標籤的主機上運行
在我對docker Swarm羣集進行必定了解後,得出的結論以下:
- 參與羣集的主機名必定不能衝突,而且能夠互相解析對方的主機名;
- 集羣內的全部節點能夠都是manager角色,可是不能夠都是worker角色;
- 當指定運行的鏡像時,若是羣集中的節點本地沒有該鏡像,那麼它將會自動下載對應的鏡像;
- 當羣集正常工做時,若一個運行着容器的docker服務器發生宕機,那麼,其所運行的全部容器,都將轉移到其餘正常運行的節點之上,並且,就算髮生宕機的服務器恢復正常運行,也不會再接管以前運行的容器;
關於docker Swarm羣集的更多功能,能夠閱讀博文:Docker Swarm羣集配置實戰(2)
———————— 本文至此結束,感謝閱讀 ————————