Docker-高級篇-swarm集群

前面章節(jié)我們更多的是學習在單節(jié)點上如何通過docker來部署和管理我們的應用,在實際生產環(huán)境中一般都會為應用部署多個節(jié)點進行負載均衡,實現(xiàn)高可用。本章我們來了解docker集群的實現(xiàn)。我們還是以小需求來驅動學習的方式進行講解。需求如下:

將上面入門篇中的快速開始章節(jié)部署的【myhelloworld】應用【lazy-study-docker-0.0.1-SNAPSHOT.jar】部署3個節(jié)點,實現(xiàn)高可用。


集群方式介紹

我們要實現(xiàn)上面的需求,有以下方式:

獨立容器方式

1、準備三個節(jié)點

2、每個節(jié)點運行一個docker容器

3、前端架設軟負載均衡器(Nginx)代理到三個節(jié)點上(必須)

統(tǒng)一資源池方式(群)

1、準備三個節(jié)點

2、將三個節(jié)點連接起來作為一個資源池(群)

3、指定每個節(jié)點角色(群管理者、工作者)

4、將服務提交給群管理者節(jié)點,群內部根據每個節(jié)點資源使用情況分配運行節(jié)點

5、前端架設軟負載均衡器(可選)

上面兩種方式優(yōu)劣勢比較

獨立容器方式缺點:

1、資源使用和分配不靈活。需要自己規(guī)劃和管理資源使用情況,根據每個節(jié)點資源情況來確定部署計劃;

2、節(jié)點數(shù)量越來越多的時候,管理起來很麻煩,每個節(jié)點需要執(zhí)行重復相同的命令;

3、橫向擴展和收縮比較繁瑣。

4、某個節(jié)點宕機,該節(jié)點的容器將不可用。

5、必須自己搭建軟件負載均衡器,例如nginx apache

獨立容器方式優(yōu)點:

1、如果節(jié)點不多情況下可以直接查看容器所在主機的綁定日志,而不需要額外搭建ELK平臺。

2、不需要學習額外的組件,例如(swarm

統(tǒng)一資源池方式(群)缺點:

1、由于服務動態(tài)分配,在節(jié)點比較多的情況下我們要查看某個容器的綁定日志是很麻煩的,所以一般需要配套搭建ELK平臺。

2、我們需要額外學習集群支持組件(例如docker原生支持的swarm)的學習和使用。

統(tǒng)一資源池方式(群)優(yōu)點:

1、將節(jié)點加入群后,只需要通過集群管理器節(jié)點來管理即可,提升運維效率。

2、資源使用靈活,可配置不同服務之間的資源使用限制。

3、支持盡可能高可用,任何節(jié)點宕機,集群管理器將會為該節(jié)點的服務實例重新分配到其它存活的節(jié)點。

4、快速和方便地進行橫向擴展和收縮。

5、可以不必部署nginx作為負載均衡器,因為集群可以通過覆蓋網絡的負載均衡特性來實現(xiàn)負載均衡的效果。

?

創(chuàng)建Swarm集群

本章我們主要講解通過swarm技術支持來實現(xiàn)docker集群部署,至于獨立部署方式可以根據前面章節(jié)自行改造,無非就是多部署一個節(jié)點,然后再安裝個Nginx,配置好網絡和nginx.conf,就可以進行集群負載均衡了。

下面我們先了解一下swarm集群架構圖

?

swarm有三個角色,分別是管理者(manager)、工作者(worker)和被選舉者(Reachable),管理者管理工作者。一般管理者節(jié)點也是一個工作者。被選舉者是當管理者宕機后可被選舉為管理者的節(jié)點。

可以通過啟動多個管理者進行管理者的高可用。每個節(jié)點角色可以動態(tài)更換,通過命令:

//將node3提升為管理者,默認也是工作者docker node promote node3//將node3降級為工作者docker node demote node3節(jié)點可以隨時下線,通過命令:docker node update --availability draindocker node update --availability activedocker node update --availability pause


說明:

Active?表示調度程序可以將任務分配給節(jié)點。

Pause?表示調度程序不會將新任務分配給節(jié)點,但現(xiàn)有任務仍在運行。

Drain表示調度程序不會將新任務分配給節(jié)點。調度程序關閉所有現(xiàn)有任務并在可用節(jié)點上。


下面我們開始創(chuàng)建swarm集群:

1、準備3個節(jié)點(node1,node2,node3,部署集群計劃如下:

?

節(jié)點

?

管理者(Manager

?

工作者(Work

node1

yes

yes

node2

yes

yes

node3


yes

?

上圖可以看到,有兩個節(jié)點是管理者,三個節(jié)點是工作者。其中管理者節(jié)點包含兩個角色,既是管理者也是工作者。

2、node1上初始化swarm集群

docker swarm init


3、node2、node3加入該集群

//查看加入集群命令docker swarm join-token worker


復制stdout輸出的命令,分別切換到node1/node2上執(zhí)行。

注意,該命令包含端口2377,需要開放該防火墻,筆者這里為了方便,直接關閉三個節(jié)點的防火墻:

systemctl stop firewalld

?


備注:需要開放端口 2377/tcp7949/udp,4789/udp

firewall-cmd --zone=public --add-port=2377/tcp --permanentfirewall-cmd --zone=public --add-port=2376/tcp --permanentfirewall-cmd --zone=public --add-port=7949/udp --permanentfirewall-cmd --zone=public --add-port=4789/udp --permanentsystemctl restart firewalld


OK,我們已經創(chuàng)建好了swarm集群,沒錯,創(chuàng)建集群主要的就這幾步。

4、查看集群節(jié)點信息

//節(jié)點管理器node1節(jié)點上執(zhí)行

docker node ls

可以看到這個主機的swarm集群管理者管理了三個節(jié)點,其中node1leader,狀態(tài)均為Active活動狀態(tài)。注意,集群管理命令均需要在管理者節(jié)點執(zhí)行,工作者節(jié)點執(zhí)行會報錯如下:

?

告知你這個節(jié)點不是swarm管理者。


部署服務

1、創(chuàng)建數(shù)據卷

//創(chuàng)建數(shù)據卷docker volume create myhelloworld//檢查數(shù)據卷docker volume ls 或者cd /var/lib/docker/volumes/ && ls//提交服務到集群docker service create --replicas 3 \ --name myhelloworld \ --mount type=volume,src=myhelloworld,dst=/opt/applications/helloworld/logs \ -p 8100:8100 \ registry.laizhiy.cn/myhelloworld

-replicas 3表示啟動3個服務實例

其它選項參數(shù)讀者應該都比較熟悉了。

2、查看部署的服務

docker service ls


3、查看服務動態(tài)分配的節(jié)點

docker service ps myhelloworld

?

可以看到,運行在3個節(jié)點上,注意,(manager)管理者node1也充當工作者(worker)的角色,運行了一個服務實例,這是默認的行為。

4、查看服務信息

docker service inspect myhelloworld

5、瀏覽器訪問

http://node1:8100/visitor

http://node2:8100/visitor

http://node3:8100/visitor

?

如果慢,多刷新幾次,慢是因為鏈接不上redis,等待redis超時時間。

6、查看網絡驅動

docker network ls

docker network inspect ingress | grep Container -A 20

?

默認服務都進入到ingress覆蓋網絡中。

7、查看數(shù)據卷

docker volume ls

8、查看日志

docker service logs -f myhelloworld或者按平常查看容器日志方式docker psdocker logs -f containerId

直接查看數(shù)據卷

less /var/lib/docker/volumes/myhelloworld/_data/info.loginfo.log是應用logback定義的文件名稱。


更新服務

1、更新服務副本數(shù)量

//查看服務現(xiàn)在副本數(shù)量

docker?service?l

//擴容到5個副本
docker service update --replicas 5 myhelloworld//查看服務副本數(shù)量docker service ls

2、查看服務運行節(jié)點信息

docker service ps myhelloworld

?

node1node2分別運行2個服務實例其中node3運行一個服務實例。細心讀者應該想到,現(xiàn)在我們在同一節(jié)點運行兩個相同的應用,端口不會沖突,這就是docker隔離技術帶來的便利。那這兩個實例在同一主機是怎么接口請求的呢?

我們下面做個試驗:

a、通過docker ps找到兩個容器ID

b、分別打開兩個SSH窗口

c、通過docker logs -f containerId來實時接收日志輸出

d、打開postmain之類的http請求工具類,用post方式請求http://node1:8100/visitor,這樣可以看到報錯信息【Request method 'POST' not supported

e、瘋狂請求,可以看到,本地兩個實例一個輸出比較多,另一個偶爾也接收到請求,進行輸出。


結論:筆者猜想內部可能根據服務實例隨機選擇一個來處理一定數(shù)量的請求。

更新服務不僅僅可以更新副本數(shù)量,還可以更新網絡驅動、數(shù)據卷、端口綁定、硬件資源限制、節(jié)點分配等等信息。這里筆者就不一一演示,讀者在需要時可以翻閱官方文檔。

https://docs.docker.com/engine/reference/commandline/service_update/


服務節(jié)點分布

我們通過下面命令可以知道服務動態(tài)分配到哪些節(jié)點

docker service ps myhelloworld

這種方式不太友好,下面推薦一款支持UI界面展示服務節(jié)點分布情況的應用鏡像。

直接向集群提交visualizer服務。

docker service create --name=viz \--publish=8089:8080/tcp \ --constraint=node.role==manager \--mount=type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock \dockersamples/visualizer:latest


--constraint=node.role==manager表示只能在管理者節(jié)點上執(zhí)行。鏡像下載慢的話,修改/etc/docker/daemon.json,內容如下:

{  "registry-mirrors": ["https://9cpn8tt6.mirror.aliyuncs.com"]}

更新daemon配置

systemctl daemon-reloadsystemctl restart docker

瀏覽器訪問:

http://node1:8089/

就可以看到你的服務分布在哪些節(jié)點上了。還支持搜索功能

?


集群和獨立容器共存

單個節(jié)點參與了集群之后,獨立容器還能繼續(xù)部署嗎?答案是“能”。我們現(xiàn)在就在node3部署一個myredis獨立容器,步驟如下:

1、創(chuàng)建自定義覆蓋網絡

//在node1執(zhí)行docker network create --opt encrypted --attachable -d overlay  my-overlay


其中--opt encrypted --attachable表示支持獨立容器加入到覆蓋網絡中。注意,其它工作者節(jié)點也會同步創(chuàng)建該網絡驅動。

2、更新myhelloworld服務網絡

//添加一個覆蓋網絡驅動docker service update --network-add my-overlay myhelloworld//移除默認的覆蓋網絡驅動docker service update --network-rm ingress myhelloworld

3、運行redis容器

docker run --rm --name myredis -d --network my-overlay  redis

注意,這里加入到的網絡是my-overlay,這是因為我們創(chuàng)建時增加了--opt encrypted --attachable選項才能使獨立容器加入到集群覆蓋網絡中。

我們通過訪問:

http://node1:8100/visitor

http://node2:8100/visitor

http://node3:8100/visitor

這里不截圖了,自己查看返回結果是不是【Hello World 你是第[1]個訪客】而不再是【Hello World connection to redis error】。還記得我們之前應用application.properties配置文件中配置的redis hostmyredis,它對應的是容器名稱。docker在同一個網絡驅動內部通過容器名稱做類似dns功能。如果是覆蓋網絡還支持負載均衡特性。


繼續(xù)部署其它服務

1、先停掉上面node3部署的獨立容器myredis

docker stop myredis

訪問任何一個:

http://node2:8100/visitor

測試停用成功。返回應該是【Hello World connection to redis error

2、node1上提交服務

docker service create\ --name myredis \--network my-overlay \ redis


注意我們這里手工指定網絡,因為我們上面對原來的myhelloword網絡做了變更,這里筆者發(fā)現(xiàn)對ingress進行變更(--network-rm ingress)不生效,也就是說默認所有集群都會加入到ingress網絡驅動中,無法刪除。

另外,上面沒有對redis數(shù)據目錄做持久化綁定主機操作,由于這是演示,一般生產環(huán)境必須做持久化綁定的。

2、驗證

http://node1:8100/visitor

http://node2:8100/visitor

http://node3:8100/visitor

你應該收到:【Hello World 你是第[1]個訪客


負載均衡

我們前面說過,使用swarm進行集群管理的優(yōu)點其中有一個說的就是可以通過覆蓋網絡驅動的負載均衡特性,不需要額外部署nginx進行代理。下面我們來驗證一下。

1、查看目前服務

docker service ls

2、查看myhelloworld服務節(jié)點信息

docker service ps myhelloworld


實際運行狀態(tài)的有node1node2、node3,其它均shutdown狀態(tài)。

3、我們下線所有node1節(jié)點中的服務實例

docker node lsdocker node update --availability drain node1docker node ls

4、查看myhelloworld服務運行節(jié)點信息

docker service ps myhelloworld

可以看到,node1相關的實例已經shutdown,但是myhelloworld運行的實例保持3個不變,把原來node1轉到了node2,現(xiàn)在node2運行兩個實例。

5、驗證

訪問:

http://node1:8100/visitor

?

node1根本就沒有運行實例,但依然可以訪問。我們繼續(xù)把node3運行的服務實例下線掉。

docker node update --availability drain node3docker service ps myhelloworld



?此時訪問:

http://node3:8100/visitor

?

可以看到,node3也可以訪問。redis估計是啟動失敗了,因為我們的虛擬機資源有限。沒有內存可用。但是我們只要測試能夠訪問即可。測試完成后,我們把所有節(jié)點狀態(tài)改回active

docker node update --availability active node3docker node update --availability active node1

結論:swarm通過overlay覆蓋網絡驅動的DNS負載均衡特性實現(xiàn)負載均衡。


管理者高可用

按照我們前面的部署計劃有兩個管理角色節(jié)點,分別是node1、node2,實現(xiàn)高可用,具體操作很簡單,直接在node1節(jié)點上執(zhí)行:

docker node promote node2//查看服務節(jié)點docker service ls

Reachable代表被選舉者角色

?

至此,簡單入門級使用swarm我們就講解到這里,更多配置使用請閱讀官方文檔。


?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

  • swarm簡介 ??Swarm是Docker公司在2014年12月初發(fā)布的一套較為簡單的工具,用來管理Docker...
  • 背景 憑借敏捷開發(fā)部署理念的推行,相信對于很多人來說docker這項容器技術已經并不陌生,Docker 1.12引...
    點融黑幫閱讀 3,320評論 3 14
  • 通信場景 本章我們繼續(xù)講解docker網絡驅動,在學習docker網絡驅動之前我們先思考下面幾個docker容器之...
    laizhiy閱讀 4,288評論 0 0
  • 容器集群 swarm 容器生態(tài)包含三個部分 容器核心知識 架構、鏡像、容器、網絡、存儲容器平臺技術 容...
    why_not_閱讀 2,043評論 0 2
  • 都喜歡繁花萬種 可是我只有枝干上那朵朵的小芯 我也喜歡春里那嫩嫩的綠 只可惜那綠中少了你的幾許 我也喜歡夏的艷麗 ...
    文壽閱讀 854評論 7 26

友情鏈接更多精彩內容