第14章 使用Docker Stack 部署應(yīng)用

大規(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è)模塊色难。

  1. 網(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)建。

  1. 密鑰

密鑰數(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)建密鑰师溅。

  1. 服務(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)建完成。
  1. 搭建應(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)備梨熙,下面開始部署嚣鄙。

  1. 部署示例應(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漩仙。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市犹赖,隨后出現(xiàn)的幾起案子队他,更是在濱河造成了極大的恐慌,老刑警劉巖峻村,帶你破解...
    沈念sama閱讀 217,657評(píng)論 6 505
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件麸折,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡粘昨,警方通過查閱死者的電腦和手機(jī)垢啼,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,889評(píng)論 3 394
  • 文/潘曉璐 我一進(jìn)店門窜锯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人芭析,你說我怎么就攤上這事锚扎。” “怎么了馁启?”我有些...
    開封第一講書人閱讀 164,057評(píng)論 0 354
  • 文/不壞的土叔 我叫張陵驾孔,是天一觀的道長。 經(jīng)常有香客問我进统,道長助币,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,509評(píng)論 1 293
  • 正文 為了忘掉前任螟碎,我火速辦了婚禮眉菱,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘掉分。我一直安慰自己俭缓,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,562評(píng)論 6 392
  • 文/花漫 我一把揭開白布酥郭。 她就那樣靜靜地躺著华坦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪不从。 梳的紋絲不亂的頭發(fā)上惜姐,一...
    開封第一講書人閱讀 51,443評(píng)論 1 302
  • 那天,我揣著相機(jī)與錄音椿息,去河邊找鬼歹袁。 笑死,一個(gè)胖子當(dāng)著我的面吹牛寝优,可吹牛的內(nèi)容都是我干的条舔。 我是一名探鬼主播,決...
    沈念sama閱讀 40,251評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼乏矾,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼孟抗!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起钻心,我...
    開封第一講書人閱讀 39,129評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤凄硼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后捷沸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體帆喇,經(jīng)...
    沈念sama閱讀 45,561評(píng)論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,779評(píng)論 3 335
  • 正文 我和宋清朗相戀三年亿胸,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了坯钦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片预皇。...
    茶點(diǎn)故事閱讀 39,902評(píng)論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖婉刀,靈堂內(nèi)的尸體忽然破棺而出吟温,到底是詐尸還是另有隱情,我是刑警寧澤突颊,帶...
    沈念sama閱讀 35,621評(píng)論 5 345
  • 正文 年R本政府宣布鲁豪,位于F島的核電站,受9級(jí)特大地震影響律秃,放射性物質(zhì)發(fā)生泄漏爬橡。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,220評(píng)論 3 328
  • 文/蒙蒙 一棒动、第九天 我趴在偏房一處隱蔽的房頂上張望糙申。 院中可真熱鬧,春花似錦船惨、人聲如沸柜裸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,838評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽疙挺。三九已至,卻和暖如春怜浅,著一層夾襖步出監(jiān)牢的瞬間铐然,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,971評(píng)論 1 269
  • 我被黑心中介騙來泰國打工恶座, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留搀暑,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,025評(píng)論 2 370
  • 正文 我出身青樓奥裸,卻偏偏與公主長得像,于是被迫代替她去往敵國和親沪袭。 傳聞我的和親對(duì)象是個(gè)殘疾皇子湾宙,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,843評(píng)論 2 354

推薦閱讀更多精彩內(nèi)容