大規(guī)模場(chǎng)景下的多服務(wù)部署和管理是一件很難的事情延刘。幸運(yùn)的是镣隶,Docker Stack為解決該問題而生极谊。Docker Stack 通過提供期望狀態(tài)、滾動(dòng)升級(jí)安岂、簡(jiǎn)單易用轻猖、擴(kuò)縮容、健康檢查等特性簡(jiǎn)化了應(yīng)用的管理域那。這些功能都封裝在一個(gè)完美的聲明式模型當(dāng)中咙边。
14.1 使用Docker Stack 部署應(yīng)用——簡(jiǎn)介
在筆記本上測(cè)試和部署應(yīng)用很簡(jiǎn)單。但是這只能算是業(yè)余選手次员。在真實(shí)的生產(chǎn)環(huán)境進(jìn)行多服務(wù)的應(yīng)用部署和管理败许,這才是專業(yè)選手的水平。
幸運(yùn)的是淑蔚,Stack正為此而生市殷!Stack能夠在單個(gè)聲明文件中定義復(fù)雜的多服務(wù)應(yīng)用。Stack還提供了簡(jiǎn)單的方式來部署應(yīng)用并管理完整的生命周期:初始化部署—>健康檢查—>擴(kuò)容—>更新—>回滾刹衫,以及其他功能醋寝。
步驟很簡(jiǎn)單搞挣。在Compose文件中定義應(yīng)用,然后通過 docker stack deploy 命令完成部署和管理音羞。Compose文件中包含了構(gòu)成應(yīng)用所需的完整服務(wù)棧囱桨,此外還包括了卷、網(wǎng)絡(luò)嗅绰、安全以及應(yīng)用所需的其他架構(gòu)舍肠。然后基于該文件使用docker stack deploy 命令來部署應(yīng)用。
Stack是基于Docker Swarm之上來完成應(yīng)用的部署办陷。因此諸如安全等高級(jí)特性貌夕,其實(shí)都是來自Swarm。簡(jiǎn)而言之民镜,Docker適用于開發(fā)和測(cè)試啡专。Docker Stack則適用于大規(guī)模場(chǎng)景和生產(chǎn)環(huán)境。
14.2 使用Docker Stack 部署應(yīng)用——詳解
從體系結(jié)構(gòu)上來講制圈,Stack位于Docker應(yīng)用層級(jí)的最頂端们童。Stack基于服務(wù)進(jìn)行構(gòu)建,而服務(wù)又基于容器鲸鹦,如下圖所示慧库。
14.2.1 簡(jiǎn)單應(yīng)用
本章的示例使用的應(yīng)用是 AtSea Shop,這個(gè)應(yīng)用我們?cè)谇懊嬖?jīng)下載過了(多階段構(gòu)建Docker)馋嗜。該應(yīng)用是個(gè)多服務(wù)應(yīng)用齐板,并且利用了認(rèn)證和安全相關(guān)的技術(shù)。應(yīng)用的架構(gòu)圖如下:
如果還沒有下載這個(gè)項(xiàng)目葛菇,請(qǐng)使用git來下載甘磨。
git clone https://github.com/nigelpoulton/atsea-sample-shop-app.git
該應(yīng)用代碼由若干的目錄和源碼文件組成,我們重點(diǎn)關(guān)注 docker-stack.yml 這個(gè)文件眯停。該文件通常被稱為Stack文件济舆,在該文件中定義了應(yīng)用及其依賴。
在該文件整體結(jié)構(gòu)中莺债,定義了4種關(guān)鍵字滋觉。其中包括 version、services齐邦、networks椎侠、secrets。與我們之前在Swarm章節(jié)介紹的一樣措拇,前3個(gè)關(guān)鍵字是同樣的含義肺蔚。secrets定義的是應(yīng)用用到的密鑰。
我們展開頂級(jí)菜單,就會(huì)看到5個(gè)服務(wù)宣羊,3個(gè)網(wǎng)絡(luò)和4個(gè)密鑰。
version: "3.2"
services:
reverse_proxy:
database:
appserver:
visualizer:
payment_gateway:
networks:
front-tier:
back-tier:
payment:
secrets:
postgres_password:
staging_token:
revprox_key:
revprox_cert:
14.2.2 深入分析Stack文件
Stack文件就是Docker Compose文件汰蜘。唯一的要求就是version:一項(xiàng)需要是3.0或者更高的值仇冯。在Docker根據(jù)某個(gè)Stack文件部署應(yīng)用的時(shí)候,首先會(huì)檢查并創(chuàng)建networks:關(guān)鍵字對(duì)應(yīng)網(wǎng)絡(luò)族操。如果網(wǎng)絡(luò)不存在苛坚,Docker會(huì)進(jìn)行創(chuàng)建。下面我們?cè)敿?xì)看下這幾個(gè)模塊色难。
- 網(wǎng)絡(luò)
networks:
front-tier:
back-tier:
payment:
driver: overlay
driver_opts:
encrypted: 'yes'
這里定義了3個(gè)網(wǎng)絡(luò)泼舱,默認(rèn)情況下網(wǎng)絡(luò)都是使用overlay驅(qū)動(dòng),新建對(duì)應(yīng)的覆蓋類型的網(wǎng)絡(luò)枷莉。但是payment網(wǎng)絡(luò)比較特殊娇昙,需要對(duì)數(shù)據(jù)層加密。
默認(rèn)情況下笤妙,覆蓋網(wǎng)絡(luò)的所有控制層都是加密的冒掌。如果需要加密數(shù)據(jù)層,有兩種選擇蹲盘。
- 在 docker network create 命令中指定 -o encrypted 參數(shù)股毫。
- 在stack文件中的 driver_opts 之下指定 encrypted:'yes'
數(shù)據(jù)層加密會(huì)導(dǎo)致額外開銷,而影響額外開銷大小的因素有很多召衔,比如流量的類型和流量的多少铃诬。但是,通常額外開銷會(huì)在10%的范圍之內(nèi)苍凛。
正如前面提到的趣席,全部的3個(gè)網(wǎng)絡(luò)均會(huì)先于密鑰和服務(wù)被創(chuàng)建。
- 密鑰
密鑰數(shù)據(jù)頂級(jí)對(duì)象毫深,在當(dāng)前Stack文件中定義了4個(gè)吩坝。
secrets:
postgres_password:
external: true
staging_token:
external: true
revprox_key:
external: true
revprox_cert:
external: true
注意,4個(gè)密鑰都被定義為external哑蔫。這意味著在Stack部署之前钉寝,這些密鑰必須存在。當(dāng)然在應(yīng)用部署時(shí)按需創(chuàng)建密鑰也是可以的闸迷,只需要將 file: <filename> 替換為external:true>嵌纲。但該方式生效的前提是,需要在主機(jī)文件系統(tǒng)對(duì)應(yīng)路徑下有一個(gè)文本文件腥沽,其中包含密鑰所需的值逮走,并且是未加密的。這種方式存在明顯的安全隱患今阳。稍后會(huì)介紹如何創(chuàng)建密鑰师溅。
- 服務(wù)
部署中主要的操作都在服務(wù)這個(gè)環(huán)節(jié)茅信。每個(gè)服務(wù)都是一個(gè)JSON集合,其中包含了一系列關(guān)鍵字墓臭。下面分別介紹著5個(gè)服務(wù)蘸鲸。
(1) reverse_proxy 服務(wù)
reverse_proxy:
image: dockersamples/atseasampleshopapp_reverse_proxy
ports:
- "80:80"
- "443:443"
secrets:
- source: revprox_cert
target: revprox_cert
- source: revprox_key
target: revprox_key
networks:
- front-tier
reverse_proxy服務(wù)定義了鏡像、端口窿锉、密鑰和網(wǎng)絡(luò)酌摇。
image關(guān)鍵字是服務(wù)對(duì)象中唯一的必填項(xiàng),這個(gè)關(guān)鍵字定義了將要用于構(gòu)建服務(wù)副本的Docker鏡像嗡载。默認(rèn)情況下會(huì)從Docker Hub拉取鏡像窑多,如果要從第三方服務(wù)中拉取,則需要自己添加對(duì)應(yīng)的第三方鏡像倉庫服務(wù)API的DNS名稱洼滚。
Docker Stack和Docker Compose的一個(gè)區(qū)別是埂息,Stack不支持構(gòu)建。這意味著在部署Stack之前判沟,所有鏡像都必須提前構(gòu)建完成耿芹。
ports關(guān)鍵字定義了兩個(gè)關(guān)鍵字。默認(rèn)情況下挪哄,所有端口映射都采用Ingress模式吧秕。這意味著Swarm集群中每個(gè)節(jié)點(diǎn)的對(duì)應(yīng)端口都會(huì)映射并且是可以訪問的,即使那些沒有運(yùn)行副本的節(jié)點(diǎn)迹炼。另一種方式是Host模式砸彬,端口只映射了運(yùn)行副本的Swarm節(jié)點(diǎn)上。但是Host模式需要使用完整的格式去配置斯入,我們?cè)谇懊嬖?jīng)介紹過砂碉。
secrets 關(guān)鍵字定義了兩個(gè)密鑰,這兩個(gè)密鑰必須在頂級(jí)關(guān)鍵字 secerts 下定義刻两,并且必須在系統(tǒng)中已經(jīng)存在增蹭。密鑰以普通文件的形式被掛載到服務(wù)副本當(dāng)中。文件的名稱就是stack文件中定義的 target 屬性的值磅摹,其在Linux下的路徑為 /run/secrets滋迈,Linux將 /run/secrets作為內(nèi)存文件系統(tǒng)掛載。
networks關(guān)鍵字確保服務(wù)所有副本都會(huì)連接到front-tier網(wǎng)絡(luò)。網(wǎng)絡(luò)相關(guān)定義必須位于頂級(jí)關(guān)鍵字networks之下,如果定義的網(wǎng)絡(luò)不存在绒疗,Docker會(huì)以O(shè)verlay網(wǎng)絡(luò)方式新建一個(gè)網(wǎng)絡(luò)。
(2)database服務(wù)
數(shù)據(jù)庫服務(wù)除了定義上述的內(nèi)容之外碍彭,還應(yīng)用了環(huán)境變量和部署約束。
database:
image: dockersamples/atsea_db
environment:
POSTGRES_USER: gordonuser
POSTGRES_DB_PASSWORD_FILE: /run/secrets/postgres_password
POSTGRES_DB: atsea
networks:
- back-tier
secrets:
- postgres_password
deploy:
placement:
constraints:
- 'node.role == worker'
environment關(guān)鍵字允許在服務(wù)副本中注入環(huán)境變量。在該服務(wù)中庇忌,使用了3個(gè)環(huán)境變量來定義數(shù)據(jù)庫用戶舞箍、數(shù)據(jù)庫密碼的位置(掛載到每個(gè)服務(wù)副本的密鑰)以及數(shù)據(jù)庫服務(wù)的名稱。
該服務(wù)還在deploy關(guān)鍵字下定義了部署約束皆疹。這樣保證了當(dāng)前服務(wù)只會(huì)運(yùn)行在Swarm集群的worker節(jié)點(diǎn)之上创译。部署約束是一種拓?fù)涓兄〞r(shí)任務(wù),是一種很好的優(yōu)化調(diào)度選擇的方式墙基。Swarm目前允許通過如下幾種方式進(jìn)行調(diào)度。
- 節(jié)點(diǎn)ID刷喜,如 node.id == qwertyuasdads
- 節(jié)點(diǎn)名稱残制,如 node.hostname==wrk-12
- 節(jié)點(diǎn)角色,如 node.role != manager
- 節(jié)點(diǎn)引擎標(biāo)簽掖疮,如 engine.labels.operatingsystem==ubuntu16.04
- 節(jié)點(diǎn)自定義標(biāo)簽初茶,如 node.labels.zone==prod1
(3) appserver 服務(wù)
appserver:
image: dockersamples/atsea_app
networks:
- front-tier
- back-tier
- payment
deploy:
replicas: 2
update_config:
parallelism: 2
failure_action: rollback
placement:
constraints:
- 'node.role == worker'
restart_policy:
condition: on-failure
delay: 5s
max_attempts: 3
window: 120s
secrets:
- postgres_password
appserver 服務(wù)使用了一個(gè)鏡像,連接到3個(gè)網(wǎng)絡(luò)浊闪,并且掛載了一個(gè)密鑰恼布。此外,appserver服務(wù)還在deploy關(guān)鍵字下引入了一些額外的特性搁宾。
接下來我們進(jìn)一步了解deploy關(guān)鍵字新增的內(nèi)容折汞。
replicas: 2 設(shè)置了期望服務(wù)的副本數(shù)量為2,默認(rèn)為1.如果服務(wù)正在運(yùn)行盖腿,需要調(diào)整副本數(shù)爽待。可以調(diào)整stack文件中的 replicas 的數(shù)值翩腐,然后重新部署stack鸟款。重新部署stack并不會(huì)影響那些沒有改動(dòng)的服務(wù)。
update_config 定義了服務(wù)在滾動(dòng)升級(jí)的時(shí)候應(yīng)該如何操作茂卦。在這里是每次更新兩個(gè)副本何什,升級(jí)失敗之后會(huì)自動(dòng)回滾〉攘回滾會(huì)基于之前的服務(wù)定義啟動(dòng)新的副本处渣。failure_action 的默認(rèn)操作時(shí)pause,會(huì)在服務(wù)升級(jí)失敗后阻止其他副本的升級(jí)而咆。failure_action還支持continue霍比。
restart_policy 定義了Swarm針對(duì)容器異常退出的重啟策略。當(dāng)前服務(wù)的重啟策略是:如果某個(gè)副本以非0返回值退出悠瞬,會(huì)立即重啟當(dāng)前副本。重啟最多嘗試3次,每次都是等待之多120s來檢測(cè)是否成功浅妆。每次重啟的間隔是5s望迎。
(4) visualizer 服務(wù)
visualizer:
image: dockersamples/visualizer:stable
ports:
- "8001:8080"
stop_grace_period: 1m30s
volumes:
- "/var/run/docker.sock:/var/run/docker.sock"
deploy:
update_config:
failure_action: rollback
placement:
constraints:
- 'node.role == manager'
除了指定鏡像、定義端口映射凌外、更新配置以及部署約束之外辩尊,這里還掛載了一個(gè)指定卷,并且定義了容器的優(yōu)雅停止方式康辑。
stop_grace_period 屬性調(diào)整了默認(rèn)為10s的優(yōu)雅停止時(shí)長摄欲。
volumes關(guān)鍵字用于掛載提前創(chuàng)建的卷或者主機(jī)目錄到某個(gè)服務(wù)副本中。在這里掛載Docker主機(jī)的 /var/run/docker.sock 目錄到每個(gè)副本的 /var/run/docker.sock 路徑疮薇。這意味著在服務(wù)副本中任何對(duì) /var/run/docker.sock 的讀寫操作都會(huì)指向 Docker 主機(jī)的對(duì)應(yīng)目錄胸墙。
docker.sock 文件時(shí)Docker提供的套接字,Docker daemon通過該套接字對(duì)其他進(jìn)程暴露其API終端按咒。這意味著如果給某個(gè)容器訪問該文件的權(quán)限迟隅,就是允許該容器接受全部的API終端,即等級(jí)與給予了容器查詢和管理Docker daemon 的能力励七。在大部分場(chǎng)景下這是不允許的智袭,但是這是個(gè)測(cè)試環(huán)境的示例應(yīng)用。
該服務(wù)需要Docker套接字訪問權(quán)限的原因時(shí)需要以圖形化的方式展示當(dāng)前Swarm中的服務(wù)掠抬。為了實(shí)現(xiàn)這個(gè)目標(biāo)吼野,當(dāng)前服務(wù)需要能訪問管理節(jié)點(diǎn) Docker daemon ,當(dāng)前服務(wù)通過部署約束的方式剿另,強(qiáng)制服務(wù)服務(wù)只能部署在管理節(jié)點(diǎn)之上箫锤,同時(shí)將Docker套接字綁定到每個(gè)服務(wù)副本中。
(5) payment_gateway 服務(wù)
payment_gateway:
image: dockersamples/atseasampleshopapp_payment_gateway
secrets:
- source: staging_token
target: payment_token
networks:
- payment
deploy:
update_config:
failure_action: rollback
placement:
constraints:
- 'node.role == worker'
- 'node.labels.pcidss == yes'
在這里雨女,payment_gateway 服務(wù)被要求只能允許在符合PCI DSS(支付卡行業(yè)標(biāo)準(zhǔn))標(biāo)準(zhǔn)的節(jié)點(diǎn)之上谚攒。為了能使其生效,讀者可以將某個(gè)自定義節(jié)點(diǎn)標(biāo)簽應(yīng)用到Swarm集群中符合要求的節(jié)點(diǎn)之上氛堕。本書會(huì)在搭建應(yīng)用部署實(shí)驗(yàn)環(huán)境的時(shí)候完成這個(gè)操作馏臭。
因?yàn)檫@里定義了兩個(gè)部署約束,也就是只有同時(shí)滿足 pcidss=yes 并且時(shí)worker的節(jié)點(diǎn)才會(huì)被部署讼稚。
14.2.3 部署應(yīng)用
在部署應(yīng)用之前括儒,有幾個(gè)前置處理需要完成。分別是:
- Swarm模式:應(yīng)用將采用Docker Stack 部署锐想,而Stack依賴Swarm模式帮寻。
- 標(biāo)簽: 某個(gè)Swarm worker節(jié)點(diǎn)需要自定義標(biāo)簽
- 密鑰: 應(yīng)用所需的密鑰需要在部署前創(chuàng)建完成。
- 搭建應(yīng)用實(shí)驗(yàn)環(huán)境
同Swarm的實(shí)驗(yàn)一樣赠摇,這里我們使用三個(gè)Dokcer主機(jī)來搭建Swarm集群固逗,其中包括1個(gè)管理節(jié)點(diǎn)和2個(gè)工作節(jié)點(diǎn)浅蚪。初始化并添加工作節(jié)點(diǎn)的操作這里不重復(fù)操作了,請(qǐng)看前面的章節(jié)烫罩。
實(shí)驗(yàn)的節(jié)點(diǎn)情況如下:
[pangcm@docker01 ~]$ docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
g6kx0krb978aqlexv6nd2i66x * docker01 Ready Active Leader 19.03.5
px24lw8vvy3kh0ge61oge9cjo docker02 Ready Active 19.03.4
zha2x49djdhuqch35f6gm4efh docker03 Ready Active 19.03.5
(1) 添加節(jié)點(diǎn)標(biāo)簽(pcidss)
在前面我們分析過了payment_gateway 服務(wù)配置了部署約束惜傲,限制了只有運(yùn)行在 pcidss=yes 標(biāo)簽的工作節(jié)點(diǎn)之上。這里我們?cè)?docker02 節(jié)點(diǎn)上增加該標(biāo)簽贝攒。
docker node update --label-add pcidss=yes docker02
可以使用 docker node inspect docker02 命令去確認(rèn)標(biāo)簽
[pangcm@docker01 ~]$ docker node inspect docker02|grep pcidss
"pcidss": "yes"
(2) 創(chuàng)建密鑰
密鑰中有3個(gè)是需要加密的key的盗誊,所以我們要先創(chuàng)建加密的key,然后把加密 key 放到 Docker 密鑰文件當(dāng)中隘弊。
創(chuàng)建鍵值對(duì)
## 不斷enter 即可
openssl req -newkey rsa:4096 -nodes -sha256 -keyout domain.key -x509 -days 365 -out domain.crt
創(chuàng)建 revprox_cert哈踱、revprox_key、postgres_password的密鑰
docker secret create revprox_cert domain.crt
docker secret create revprox_key domain.key
docker secret create postgres_password domain.key
創(chuàng)建stage_token密鑰
echo staging |docker secret create staging_token -
列出所有的密鑰:
[pangcm@docker01 ~]$ docker secret ls
ID NAME DRIVER CREATED UPDATED
zp591zcfknxprzhbn06r3rrwh postgres_password 31 minutes ago 31 minutes ago
tzfh3qgajlnf6yh9s82yw77ws revprox_cert 35 minutes ago 35 minutes ago
f109x6mtz1ueerxwxoy772ujv revprox_key 34 minutes ago 34 minutes ago
3bmwnmddfgyy8ij98csmfldjm staging_token 34 minutes ago 34 minutes ago
這里我們就完成了全部的前置準(zhǔn)備梨熙,下面開始部署嚣鄙。
- 部署示例應(yīng)用
##進(jìn)入到項(xiàng)目目錄下
cd atsea-sample-shop-app
##使用docker stack deploy 命令部署
docker stack deploy -c docker-stack.yml seastack
這里我們指定了stack文件,并把stack命名為 seastack串结。我們可以運(yùn)行 docker network ls 以及docker service ls 命令來擦看應(yīng)用的網(wǎng)絡(luò)和服務(wù)情況。下面是命令輸出需要注意的地方舅列。
網(wǎng)絡(luò)是先于服務(wù)創(chuàng)建的肌割。這是因?yàn)榉?wù)依賴于網(wǎng)絡(luò),所以網(wǎng)絡(luò)需要在服務(wù)啟動(dòng)前創(chuàng)建帐要。Docker將Stack名稱附加到由他創(chuàng)建的任何資源名稱前作為前綴把敞。在本例中,Stack名為seastack榨惠,所以所有資源名稱的格式都如: seastack_<resource>奋早。例如,payment網(wǎng)絡(luò)的名稱是seastack_payment赠橙。而在部署之前創(chuàng)建的資源則不會(huì)被重命名耽装,比如密鑰。
另外一個(gè)需要注意的是查看網(wǎng)絡(luò)狀態(tài)的時(shí)候會(huì)看到多了一個(gè) seastack_default 的網(wǎng)絡(luò)期揪。該網(wǎng)絡(luò)我們沒有定義掉奄,為什么會(huì)創(chuàng)建呢?要知道每個(gè)服務(wù)都要連接到網(wǎng)絡(luò)的凤薛,我們的visualizer服務(wù)沒有指定具體的網(wǎng)絡(luò)姓建。于是Docker就創(chuàng)建了這樣的一個(gè)網(wǎng)絡(luò),并且把visualizer連接到該網(wǎng)絡(luò)缤苫。
我們可以通過 docker stack ls 和docker stack ps 去查看 stack的更多信息速兔。
## docker stack ls
[pangcm@docker01 atsea-sample-shop-app]$ docker stack ls
NAME SERVICES ORCHESTRATOR
seastack 5 Swarm
## docker stack ps
[pangcm@docker01 atsea-sample-shop-app]$ docker stack ps seastack
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR
aioybx1kz4vv seastack_appserver.1 dockersamples/atsea_app:latest docker03 Running Preparing 10 hours ago
i5k69i7gekyc seastack_database.1 dockersamples/atsea_db:latest docker02 Running Running 10 hours ago
8ulzn7q95axq seastack_appserver.1 dockersamples/atsea_app:latest docker02 Shutdown Failed 10 hours ago "task: n
...
可以看到 appserver 在docker02節(jié)點(diǎn)啟動(dòng)失敗過,通過docker stack ps 可以看到Stack中每個(gè)服務(wù)的概況活玲,包括服務(wù)副本所在的節(jié)點(diǎn)涣狗、當(dāng)前狀態(tài)谍婉、期望狀態(tài)和異常細(xì)節(jié)。
如果要查看具體某個(gè)服務(wù)的詳細(xì)信息屑柔,可以使用 docker service logs 命令屡萤。
在服務(wù)都起來之后,我們使用瀏覽器訪問 https://xxxx 即可訪問這個(gè)應(yīng)用的首頁掸宛。
14.2.4 管理應(yīng)用
Stack是一組相關(guān)聯(lián)的服務(wù)和基礎(chǔ)設(shè)施死陆,需要進(jìn)行統(tǒng)一的部署和管理。這意味著Stack是由普通的Docker資源構(gòu)建而來:網(wǎng)絡(luò)唧瘾、卷措译、密鑰、服務(wù)等饰序。我們可以通過普通的Docker命令對(duì)其進(jìn)行查看和重新配置领虹,如:docker netwoerk、docker volume求豫、docker secret塌衰、docker service等。
在這樣的一個(gè)前提下蝠嘉,通過docker service 命令來管理 Stack中的某個(gè)服務(wù)是可行的最疆。一個(gè)簡(jiǎn)單的例子是通過 docker service scale 命令來擴(kuò)充appserver的服務(wù)副本數(shù),但我們不推薦這么操作蚤告。
推薦的方式是通過聲明式方式修改努酸,即將Stack文件作為配置的唯一聲明。這樣杜恰,所有Stack相關(guān)的改動(dòng)都需要體現(xiàn)在Stack文件中获诈,然后重新部署應(yīng)用所需的Stack文件。
舉例心褐,我們把a(bǔ)ppserver的副本數(shù)目從2修改為3舔涎,把visuaizer服務(wù)的優(yōu)雅停止時(shí)間增加到2分鐘,我們修改stack文件逗爹。
appserver:
deploy:
replicas: 3
update_config:
parallelism: 2
failure_action: rollback
visualizer:
ports:
- "8001:8080"
stop_grace_period: 2m
然后重新部署
docker stack deploy -c docker-stack.yml seastack
如果要?jiǎng)h除某個(gè) Stack终抽,使用 docker stack rm 命令。一定要謹(jǐn)慎桶至,刪除Stack不會(huì)進(jìn)行二次確認(rèn)昼伴。該命令會(huì)把網(wǎng)絡(luò)和服務(wù)都刪除,但是密鑰不會(huì)被刪除镣屹,原因是密鑰是我們?cè)诓渴鹎熬蛣?chuàng)建并存在的圃郊。當(dāng)然,卷也是不會(huì)被刪除的女蜈。
14.3 使用Docker Stack 部署應(yīng)用——命令
docker stack deploy 用于根據(jù) Stack 文件部署和更新Stack服務(wù)的命令持舆。
docker stack ls 會(huì)列出 Swarm 集群中全部的Stack色瘩,包括每個(gè)Stack擁有多少服務(wù)。
docker stack ps 列出某個(gè)已經(jīng)部署的Stack相關(guān)詳情逸寓。該命令支持Stack名稱作為其主要參數(shù)居兆,列舉了服務(wù)副本在節(jié)點(diǎn)的分布情況,以及期望狀態(tài)和當(dāng)前狀態(tài)竹伸。
docker stack rm 命令用于從Swarm集群中移除Stack泥栖。移除操作執(zhí)行前并不會(huì)進(jìn)行二次確認(rèn)。
14.4 本章小結(jié)
Stack是Docker原生的部署和管理多服務(wù)應(yīng)用的解決方案勋篓。Stack默認(rèn)集成在Docker引擎中吧享,并且提供了簡(jiǎn)單的聲明式接口對(duì)應(yīng)用進(jìn)行部署和全生命周期管理。
在本章開始提供了應(yīng)用代碼以及一些基礎(chǔ)設(shè)施需求譬嚣,比如網(wǎng)絡(luò)钢颂、端口、卷和密鑰拜银。接下來的內(nèi)容完成了應(yīng)用的容器化殊鞭,并且將全部應(yīng)用服務(wù)和基礎(chǔ)設(shè)施需求集成到一個(gè)聲明式的Stack文件當(dāng)中。在Stack文件中設(shè)置了服務(wù)副本數(shù)尼桶、滾動(dòng)升級(jí)以及重啟策略钱豁。然后通過 docker stack deploy 命令基于Stack文件完成了應(yīng)用的部署。
對(duì)于已部署應(yīng)用的更新操作疯汁,應(yīng)該通過修改Stack文件完成。首先需要從源碼管理系統(tǒng)中檢出Stack文件卵酪,更新該文件幌蚊,然后重新部署應(yīng)用,最后將改動(dòng)后的Stack文件重新提交到源碼控制系統(tǒng)中溃卡。
因?yàn)镾tack文件中定義了像服務(wù)副本數(shù)這樣的內(nèi)容溢豆,所以讀者需要自己維護(hù)多個(gè)Stack文件以用于不同的環(huán)境,比如dev瘸羡、test以及prod漩仙。