上面已經介紹了如何安裝Docker兽赁、拉取鏡像以及使用容器,接下來需要探討的話題將是關于規(guī)模(Scale)方面的,這時候輪到Docker Swarm登場了霉涨。
10.1 Docker Swarm——簡介
Docker Swarm包含兩方面:一個企業(yè)級的Docker安全集群按价,以及一個微服務應用編排引擎。
集群方面笙瑟,Swarm將一個或多個Docker節(jié)點組織起來楼镐,使得用戶能夠以集群方式管理它們。Swarm默認內置有加密的分布式集群存儲往枷、加密網絡框产、公用TLS、安全集群介入令牌以及一套簡化數字證書管理的PKI错洁。用戶可以自如地添加或刪除節(jié)點秉宿,這非常棒。
編排方面屯碴,Swarm提供了一套豐富的API使得部署和管理復雜的微服務應用變得易如反掌描睦。通過將應用定義在聲明式配置文件中,就可以使用原生的Docker命令完成部署导而。此外酌摇,甚至還可以執(zhí)行滾動升級、回滾以及擴縮容操作嗡载、同樣基于簡單的命令即可完成窑多。
以往,Docker Swarm是一個基于Docker 引擎之上的獨立產品洼滚。自Docker 1.12版本之后埂息,它已經完全集成在Docker引擎中,執(zhí)行一條命令即可啟用遥巴。到2018年千康,除了原生Swarm應用,他還可以部署和管理k8S應用铲掐。即便在本書撰寫時拾弃,對k8s應用的支持也是新特性。
10.2 Docker Swarm——詳解
10.2.1 Swarm的初步介紹
從集群角度來說摆霉,一個Swarm由一個或多個Docker節(jié)點組成豪椿。節(jié)點會被配置為管理節(jié)點(Manager)或者工作節(jié)點(Worker)。管理節(jié)點負責集群控制面(Control Plane)携栋,進行諸如監(jiān)控集群狀態(tài)搭盾、分發(fā)任務至工作節(jié)點等操作。工作節(jié)點接收來自管理節(jié)點的任務并執(zhí)行婉支。
Swarm的配置和狀態(tài)信息保存在一套位于所有管理節(jié)點上的分布式etcd數據庫中鸯隅。該數據庫運行于內存中,并保持數據的最新狀態(tài)向挖。關于該數據庫最棒的是蝌以,他幾乎不需要任何配置——作為Swarm的一部分被安裝炕舵、無需管理。
關于集群管理跟畅,最大的挑戰(zhàn)在于保證其安全性咽筋。搭建Swarm集群時將不可避免地使用TLS,因為它被Swarm緊密集成碍彭。在安全意識日盛的今天晤硕,這樣的工具值得大力推廣悼潭。Swarm使用TLS進行通信通信庇忌、節(jié)點認證和角色授權。自動密鑰輪換更是錦上添花舰褪!其在后臺默默進行皆疹,用戶甚至感知不到這一功能的存在。
關于應用編排占拍,Swarm中的最小調度單元是服務略就。它是隨Swarm引入的,在API中是一個新的對象元素晃酒,它基于容器封裝了一些高級特征啤咽,是一個更高層次的概念清寇。
當容器被封裝在一個服務中時,我們稱之為一個任務或者一個副本,服務中增加了諸如擴縮容厚脉、滾動升級以及簡單回滾等特征。
10.2.2 搭建安全的Swarm集群
書本的示例一共有6個節(jié)點门驾,包括3個管理節(jié)點和3個工作節(jié)點充包。我這里沒有那么多的主機資源,一共3個節(jié)點山析,分別包括1個管理節(jié)點和2個工作節(jié)點堰燎。(實際上你可以使用docker machine 輕松搭建多套docker的運行環(huán)境)
這里的每個節(jié)點都要安裝Docker,并且能夠與Swarm的其他節(jié)點通信笋轨。因為都是同一個局域網內秆剪,所以我放行了內網的所有防火墻規(guī)則。運行Swarm會開啟3個端口爵政,分別是:
- 2377/tcp:用于客戶端于Swarm進行安全通信
- 7946/tcp 與 7946/udp:用于控制面gossip分發(fā)
- 4789/udp:用于基于VXLAN的覆蓋網絡鸟款。
下面我們開始搭建Swarm吧。搭建Swarm的大體流程如下:初始化第一個管理節(jié)點——>加入額外的管理節(jié)點——>加入工作節(jié)點——>完成茂卦。
- 初始化一個全新的Swarm
不包含在任何Swarm中的Docker節(jié)點何什,稱為運行于單引擎(Single-Engine)模式。一旦被加入Swarm集群等龙,則切換為Swarm模式处渣。
在單引擎模式下的Docker主機上運行 docker swarm init 會將其切換到Swarm模式伶贰,并創(chuàng)建一個新的Swarm,將自身設置為Swarm的第一個管理節(jié)點罐栈。然后其他的節(jié)點就可以加入進來了黍衙,新加入的節(jié)點也會切換為swarm模式。
節(jié)點 192.168.113.70 上初始化:
[pangcm@docker01 ~]$ docker swarm init --advertise-addr 192.168.113.70:2377 --listen-addr 192.168.113.70:2377
Swarm initialized: current node (liokj5021pc9ls40fj3tcebxq) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-59xcha9v3tw180c64c0zg0ic2418qw69ns6ics4t6cj2t0wl6x-b5mlt9leakzj4gpo9qa9souc1 192.168.113.70:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
這條命令解析如下:
docker swarm init 會通知Docker來初始化一個新的Swarm荠诬,并將自身設置為第一個管理節(jié)點琅翻。同時也會使得該節(jié)點開啟Swarm模式。
后面的兩個和IP相關的參數是可選的柑贞,在多IP的Docker主機上需要配置方椎。這里還是建議在執(zhí)行命令的時候加上著兩個參數。
- 列出Swarm中的節(jié)點,docker node ls
[pangcm@docker01 ~]$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
liokj5021pc9ls40fj3tcebxq * docker01 Ready Active Leader 19.03.5
這里可以看到目前只有一個節(jié)點钧嘶,該節(jié)點是一個leader的角色棠众。
- 在 192.168.113.71和192.168.113.72節(jié)點上把這兩個節(jié)點加入到上面創(chuàng)建的swarm。
##這個命令在我們初始化swarm的時候系統(tǒng)生成的有决,同理添加管理節(jié)點的命令也在初始化的時候給出了
docker swarm join --token SWMTKN-1-59xcha9v3tw180c64c0zg0ic2418qw69ns6ics4t6cj2t0wl6x-b5mlt9leakzj4gpo9qa9souc1 192.168.113.70:2377
- 這時候我們回到管理節(jié)點上查看swarm節(jié)點的情況闸拿。
[pangcm@docker01 ~]$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
liokj5021pc9ls40fj3tcebxq * docker01 Ready Active Leader 19.03.5
qg63e8vx18v1rhnv9hjmwml16 docker02 Ready Active 19.03.4
yle6i7nhhxglc2qva49i91x1v docker03 Ready Active 19.03.5
就這樣,Swarm集群我們就創(chuàng)建好了书幕。其中包含了1個管理節(jié)點和2個工作節(jié)點新荤,每個節(jié)點的Docker引擎都被切換到Swarm模式下,并且自動啟動了TLS安全台汇。如果你有多個管理節(jié)點苛骨,那么有的節(jié)點會是 Reachable
狀態(tài),有一個是 Leader
狀態(tài)励七。Leader那個就是主節(jié)點了智袭,后面我們會介紹到。
10.2.3 Swarm 管理器的高可用(HA)掠抬。
雖然我這里只用到一個管理節(jié)點吼野,但是官方是建議3個的,為什么是3個呢两波?了解集群系統(tǒng)的人都知道瞳步,集群工作的時候3或5個節(jié)點都是一個比較好的選擇。
Swarm的管理節(jié)點內置有對HA的支持腰奋。這意味著单起,即使有一個或者多個節(jié)點發(fā)生了故障,剩余管理節(jié)點也會繼續(xù)保證Swarm的運轉劣坊。
從技術上來說嘀倒,Swarm實現了一種主從方式的多管理節(jié)點的HA。也就是說,你可能有多個管理節(jié)點测蘑,但是只有一個處于活動狀態(tài)灌危。通常處于活動狀態(tài)的節(jié)點被稱為主節(jié)點,而主節(jié)點也是唯一一個會對Swarm發(fā)送控制命令的節(jié)點碳胳。也就是說勇蝙,只有主節(jié)點才會變更配置,或發(fā)送任務到工作節(jié)點挨约。如果一個備用管理節(jié)點接收到了Swarm命令味混,則它會將其轉發(fā)給主節(jié)點。
Swarm使用Raft算法來實現支持管理節(jié)點的HA诫惭,Raft協議在選舉Leader的時候遵循少數服從多數的原則翁锡。所以使用奇數個節(jié)點的好處就是避免腦裂現象的出現。而不建議部署太多管理節(jié)點的原因是過多的節(jié)點數據同步的效率太低了贝攒,并且選舉耗時會更長盗誊,所以一般建議3個或者5個时甚。
10.2.4 Swarm的安全
Swarm集群內置了眾多的安全機制隘弊,并提供了開箱即用的合理默認配置——如CA設置、接入Token荒适、公用TLS梨熙、加密集群存儲、加密網絡刀诬、加密節(jié)點ID等等咽扇。更多內容會在第15章介紹。
盡管內置有如此多的原生安全機制陕壹,重啟一個舊的管理節(jié)點或者進行備份恢復仍有可能對集群造成影響质欲。一個舊的管理節(jié)點重新接入Swarm會自動解密并獲得Raft數據庫中長時間序列的訪問權,這回帶來安裝隱患糠馆。進行本非恢復可能會抹掉最新的Swarm配置嘶伟。
為了避免以上問題,Docker提供了自動鎖機制來鎖定Swarm又碌,這會強制要求重啟的管理節(jié)點在提供一個集群解鎖碼之后才有權重新接入集群九昧。
在創(chuàng)建Swarm集群的時候可以直接加上 --autolock 參數啟用鎖。我們前面并沒有這么操作毕匀,那就需要使用 docker swarm update 命令來啟動鎖铸鹰。
在管理節(jié)點上
[pangcm@docker01 ~]$ docker swarm update --autolock=true
Swarm updated.
To unlock a swarm manager after it restarts, run the `docker swarm unlock`
command and provide the following key:
SWMKEY-1-8bDcdp+PQ1IYuind8XanEVCxcdsne0OJ6rIYoqQRiPI
Please remember to store this key in a password manager, since without it you
will not be able to restart the manager.
這時候重啟其他的管理節(jié)點,管理節(jié)點不會自動重新接入集群皂岔。要接入集群那就要先解鎖蹋笼,使用 docker swarm unlock
命令進行解鎖。這里看到剖毯,這個key非常重要,請妥善保管速兔。因為我的是測試環(huán)境,所以我會把這個鎖機制給關閉涣狗,以免我自己忘了這個key.
docker swarm update --autolock=false
10.2.5 Swarm服務
本節(jié)介紹的內容可以使用Docker Stack(第14章)進一步改進。然而镀钓,本章的概念對于準備第14章的學習是非常重要的穗熬。
就像在Swarm初步介紹中提到的,服務是自Docker 1.12后新引進的概念丁溅,并且僅適用于Swarm模式唤蔗。使用服務仍能夠配置大多數熟悉的容器熟悉,比如容器名窟赏、端口映射妓柜、接入網絡和鏡像。此外還增加了額外的特性涯穷,比如可以聲明應用服務的期望狀態(tài)棍掐,將其告知Docker后,Docker會負責進行服務的部署和管理拷况。
舉例說明作煌,加入某個應用的web前端服務,這個服務經過測試我們使用5個實例能夠應對正常的流量赚瘦。那么我們就可以把這個需求轉換為一個服務粟誓,該服務聲明了容器使用的鏡像,并且服務應該總是有5個運行中的副本起意。
下面鹰服,我們來看下怎么去創(chuàng)建一個新的服務吧。
##鏡像比較大杜恰,拉取需要一定的時間
docker service create --name web-fe -p 8080:8080 --replicas 5 nigelpoulton/pluralsight-docker-ci
該命令的參數于 docker container run 命令大致相同获诈,這里我們使用 --name 和 -p 定義服務的方式,與單機啟動容器的定義方式一樣的心褐。
使用docker service create 命令告知Docker正在聲明一個新服務舔涎,并傳遞--name 參數將其命名為web-fe。將每個節(jié)點上的8080端口映射到服務副本內部的8080端口逗爹。接下來亡嫌,使用 --replicas 參數告訴Docker應該總是有5個此服務的副本嚎于。最后,告知Docker哪個鏡像用于副本——重要的是挟冠,要了解所有的服務副本使用相同的鏡像和配置于购。
這還沒有結束,所有的服務都會被Swarm持續(xù)監(jiān)控——Swarm會在后臺進行輪詢檢查知染,來次序比較服務的實際狀態(tài)和期望狀態(tài)是否一致肋僧。如果不一致,Swarm會使其一致控淡。比如嫌吠,web-fe還有某個節(jié)點宕機了,副本數量從5下降到4個辫诅,Docker會馬上啟動一個新的web-fe副本來使實際狀態(tài)和期望狀態(tài)保持一致涧狮。這一功能非常強大,使得服務在面對節(jié)點宕機等問題的時候具有自愈的能力肤视。
- 查看服務
使用 docker service ls 命令可以查看Swarm中的所有運行中的服務譬嚣。
[pangcm@docker01 ~]$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
kiyro8y0wbj7 web-fe replicated 5/5 nigelpoulton/pluralsight-docker-ci:latest *:8080->8080/tcp
使用docker service ps 可以查看服務副本列表及各副本的狀態(tài)钞它,
[pangcm@docker01 ~]$ docker service ps web-fe
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
rncmk0pcakm2 web-fe.1 nigelpoulton/pluralsight-docker-ci:latest docker02 Running Running 30 minutes ago
mchv3wizclfa web-fe.2 nigelpoulton/pluralsight-docker-ci:latest docker03 Running Running 18 minutes ago
xaeqa2lehef2 web-fe.3 nigelpoulton/pluralsight-docker-ci:latest docker02 Running Running 30 minutes ago
slq06rv4xuac web-fe.4 nigelpoulton/pluralsight-docker-ci:latest docker03 Running Running 18 minutes ago
j3xtrie3s8jb web-fe.5 nigelpoulton/pluralsight-docker-ci:latest docker01 Running Running 30 minutes ago
這里可以看到各個副本分別運行在Swarm的哪個節(jié)點上尼桶,以及期望的狀態(tài)和實際狀態(tài)锯仪。
要查看更加詳細的服務信息,可以使用 docker service inspect 命令查看小腊。
[pangcm@docker01 ~]$ docker service inspect web-fe --pretty
ID: kiyro8y0wbj7lxbtzmf3iudrc
Name: web-fe
Service Mode: Replicated
Replicas: 5
Placement:
UpdateConfig:
Parallelism: 1
On failure: pause
Monitoring Period: 5s
Max failure ratio: 0
Update order: stop-first
RollbackConfig:
Parallelism: 1
On failure: pause
Monitoring Period: 5s
Max failure ratio: 0
Rollback order: stop-first
ContainerSpec:
Image: nigelpoulton/pluralsight-docker-ci:latest@sha256:7a6b0125fe7893e70dc63b2c42ad779e5866c6d2779ceb9b12a28e2c38bd8d3d
Init: false
Resources:
Endpoint Mode: vip
Ports:
PublishedPort = 8080
Protocol = tcp
TargetPort = 8080
PublishMode = ingress
使用 --pretty 只顯示我們感興趣的信息秩冈,便于閱讀斥扛。強烈建議能通讀docker inspect 命令的信息,其中包含了大量的信息芬失,是我們了解底層運行機制的一個途徑。
- 副本服務 VS 全局服務
服務的默認復制方式是副本模式棱烂,這種模式會部署期望數量的服務副本,并盡可能均勻地將各個副本分布在整個集群中窜锯。另外一種模式是全局模式芭析,這種模式下,每個節(jié)點僅運行一個副本驾孔。
可以通過 docker service create 命令傳遞 --mode global 參數來部署一個全局服務惯疙。
- 服務的擴縮容
服務的另外一個強大的特征就是能夠方便地進行擴縮容。在業(yè)務發(fā)展的時候对碌,我們會增加副本的數量蒿偎。
docker service scale web-fe=10
在服務流量低的時候,我們可以降低副本的數量骑脱。
docker service scale web-fe=3
- 刪除服務
刪除一個服務的操作非常簡單苍糠, 正是由于太簡單了,請慎用拥娄,刪除服務的時候不會進行確認的稚瘾。
docker service rm web-fe
- 滾動升級
擁有多個副本的服務可以輕松實現滾動升級乏矾,這對運維和開發(fā)人員太友好了迁杨。滾動升級非常簡單铅协,只需要執(zhí)行 docker service update 命令即可摊沉。
這里只是為了示例怎么使用命令滾動升級,由于書本的例子很長骏全,這里我就使用 tomcat的鏡像直接對上面我們創(chuàng)建的服務進行滾動升級姜贡。(書本的例子涉及到覆蓋網絡的創(chuàng)建棺棵,后面我們會有介紹)
docker service update --image tomcat --update-parallelism 2 --update-delay 20s web-fe
這里說明下這兩個參數 --update-parallelism 和 --update-delay 聲明名詞使用新鏡像更新2個副本,期間有20s的延遲母怜。升級的過程可以通過 docker service ps web-fe 去查看缚柏。
滾動升級完成后币喧,可以使用瀏覽器檢查下結果,這時候頁面應該是tomcat的歡迎頁面疙挺。此外怜浅,如果你使用 docker service inspect 命令恶座,還可以看到我們前面配置的兩個參數也保存在里面了跨琳。
10.2.7 故障排除
日志是我們排錯的好助手,docker service logs 可以查看Swarm的服務日志脉让。然而并非所有的日志驅動都支持該命令。
Docker節(jié)點默認的配置是术唬,服務使用json-file日志驅動粗仓,其他的驅動還有 journald(Linux特有)设捐、syslog、splunk和gelf蚂斤。
10.3 Docker Swarm——命令
- docker swarm init 命令用戶創(chuàng)建一個新的Swarm橡淆。
- docker swarm join-token 命令用于查詢加入管理節(jié)點和工作節(jié)點到現有Swarm時使用的命令和Token.
- docker node ls 命令用于列出Swarm中所有節(jié)點及相關信息逸爵。
- docker service create 命令用于創(chuàng)建一個新的服務
- docker service ls 命令用于列出Swarm中運行的服務,以及諸如服務狀態(tài)师倔、服務副本等基本信息趋艘。
- docker service ps 命令會給出更多關于某個服務副本的信息
- docker service scale 命令用于對服務副本個數進行增減
- docker service update 命令用于對運行中國的服務的屬性進行變更
- docker service logs 命令用于查看服務的日志
- docker service rm 用于刪除從Swarm中刪除某服務凶朗,這會直接刪除所有副本棚愤,不做確認,慎用瘸洛。
10.4 本章小結
Docker Swarm 是使Docker規(guī)拇魏停化的關鍵方案。Docker Swarm 的核心包含一個安全集群組件和一個編排組件石蔗。
安全集群管理組件是一個企業(yè)級的安全套件,提供了豐富的安全機制以及HA特性养距,這些都是自動配置好的铃在,并且非常容易調整。
編排組件允許用戶以一種簡單的聲明式的方式來部署和管理微服務應用阳液。它不僅支持原生的Docker Swarm應用揣炕,還支持K8s應用畸陡。
第14章會對如何使用聲明式的方式部署微服務展開更加深入的討論丁恭。