跳至主要内容

7.8 打包所有服務

在過去的幾個小節中,我們都是透過輸入指令的方式來建立 service,這就會遇到和 Docker Compose 相同的問題,當服務越來越多,每次都要輸入相同的指令是強人所難,這時候我們可以接續的 docker-compose.yml 的概念來撰寫 Swarm 的預期狀態檔案,其實有許多的語法都和 Docker Compose 相同,唯一不一樣的就是加入了 deploy 這個參數。

以上一個小節的 Drupal 搭配 PostgreSQL 來做範例,寫成一個 YAML 檔案,並且一鍵啟動服務。

version: '3.9'

services:
drupal:
image: drupal:7.92
secrets:
- source: my_secret
target: /my_secret
networks:
- dev
ports:
- 80:80
deploy:
replicas: 1
restart_policy:
condition: on-failure

pg:
image: postgres:14-alpine
configs:
- source: my_config
target: /my_config
volumes:
- pg:/var/lib/postgresql/data
networks:
- dev
environment:
- POSTGRES_PASSWORD=password
deploy:
replicas: 1
restart_policy:
condition: on-failure
placement:
constraints: [node.id == 您的節點 ID]

secrets:
my_secret:
external: true

configs:
my_config:
external: true

volumes:
pg:
external: true

networks:
dev:
external: true

大部分的參數相信在 Docker Compose 的章節都有介紹過,今天就著重在 deploy 內的參數,deploy 內的參數只有在 Swarm 模式下有用,若是使用 docker compose up 去執行這份檔案,不僅會直接略過這些參數的,而且還會因為 Docker Compose 不支援 secret 以及 config 物件而出錯。

secret 以及 config 都在上一個小節介紹了,轉成 YAML 的寫法其實和 CLI 是一模一樣的,至於 external 在 Docker Compose 的章節就有解釋過了。

replicas 則是副本,這在前面小節也不斷地使用,至於 restart_policy 就是 Docker Compose 寫的 restart,只是在 Swarm 模式下稍微的囉唆一點,且要放在 deploy 內。

大部分都是把 CLI 直接轉成 YAML 的格式,在官方的文件中可以找到全部的寫法,重點還是如何靈活運用是最重要的。

像我一開始使用時,就不知道寫在 YAML 內的 constraints 前面還需要加上 placement 的參數,但其實官方文件就有了,所以認真的閱讀官方文件很重要,一本書很難把所有的情境都涵蓋,了解基礎的使用方式,才能擴大使用的範圍。

如何一鍵啟動?

在 Docker Compose 的章節,我們使用 docker compose up 作為啟動多個容器的方式,而在 Swarm 模式下,docker compose up 這段指令就派不上用場了,要轉而使用 docker stack deploy 這段指令。

root@ubuntu-s-1vcpu-512mb-10gb-sgp1-01:~# docker stack deploy --compose-file docker-compose.yml dev <- 不換行
Creating service dev_drupal
Creating service dev_pg

--compose-file 則為定義預期狀態的 YAML 檔案,不一定要叫做 docker-compose.yml。

而最後的參數則為這個 stack 的命名,可以根據這個 stack 所作的事情來命名。

可以看到 stack 最終的結果還是建立了兩個 service,所以一開始也不需要想得太過複雜,它就是 Swarm 模式下結合多個 service 的方法。

所以到底什麼是 stack 呢?使用上很像 Docker Compose,就是把整個應用程式的預期狀態放入一個 stack 內,並且交由 Docker Swarm 全權處理,如下圖所示:

Stack 示意圖

查看 Stack 內的服務狀態

透過 docker stack ps 『 stack 名稱 』 的方式,就能夠看到整個 stack 內的容器狀態,包含了運行在哪個節點上以及隸屬於哪個 service 的詳細資訊。

root@ubuntu-s-1vcpu-512mb-10gb-sgp1-01:~# docker stack ps dev
ID NAME IMAGE NODE DS CS ERROR PORTS
nlv.. dev_drupal.1 drupal:7.92 03 Run.. Run..
m0t.. dev_pg.1 postgres.. 01 Run.. Run..

一鍵移除所有服務

只需要使用 docker stack rm 的指令就能夠做到,刪除一個 stack 也代表刪除裡面所包含的服務,是不是很像 docker compose down 呢?

root@ubuntu-s-1vcpu-512mb-10gb-sgp1-01:~# docker stack rm dev
Removing service dev_drupal
Removing service dev_pg

綜合上述,個人覺得 Swarm 這個容器調度工具會比 Kubernetes 好上手的原因,是因為語法大部分都承襲自 Docker Compose,只要有打好 Docker 的基礎,學習曲線就不會那麼陡峭,卻可以很快的達到相同的目的 ( 小規模的服務來説 )

而下一個章節開始,我們要開始兌現前面所學的基礎,來部署 Web 應用程式。