使用docker compose來編排容器化程式非常的方便, 但隨著應用越來越複雜, 我們每個Service會有許多共同掛載的目錄、環境變數, 那這些在傳統的程式語言都能藉由繼承、覆寫的技巧來簡化程式碼, 但在YAML呢? 有沒有這樣的功能呢?
答案是有的, 也就是 anchors & aliases 這兩個技巧, 那就讓我們來好好的了解一番吧!
它讓我們標記某一段節點並使用別名重新命名, 讓我們在其他地方可以使用這個標記, 藉此減少重複代碼。
各個符號詳細說明如下:
以下這段我們可以看到很多重複的設定, 包括logging、environment, 這些都是重複的, 理論上應該可以使用嵌入的方式套用。
services:
web1:
image: nginx:latest
ports:
- "8081:80"
environment:
- ENV=production
- DEBUG=false
volumes:
- ./web1:/usr/share/nginx/html
logging:
driver: "json-file"
options:
max-size: "200k"
max-file: "10"
web2:
image: nginx:latest
ports:
- "8082:80"
environment:
- ENV=production
- DEBUG=false
volumes:
- ./web2:/usr/share/nginx/html
logging:
driver: "json-file"
options:
max-size: "200k"
max-file: "10"
worker1:
image: myapp/worker:latest
environment:
- ENV=production
- DEBUG=false
volumes:
- ./worker1:/app
logging:
driver: "json-file"
options:
max-size: "200k"
max-file: "10"
worker2:
image: myapp/worker:latest
environment:
- ENV=production
- DEBUG=false
volumes:
- ./worker2:/app
logging:
driver: "json-file"
options:
max-size: "200k"
max-file: "10"
# 定義通用的錨點配置
x-common-logging: &default-logging
driver: "json-file"
options:
max-size: "200k"
max-file: "10"
x-common-environment: &default-env
- ENV=production
- DEBUG=false
x-common-service: &default-service
environment: *default-env
logging: *default-logging
services:
web1:
<<: *default-service # 引用通用的服務配置
image: nginx:latest
ports:
- "8081:80"
volumes:
- ./web1:/usr/share/nginx/html
web2:
<<: *default-service # 引用通用的服務配置
image: nginx:latest
ports:
- "8082:80"
volumes:
- ./web2:/usr/share/nginx/html
worker1:
<<: *default-service # 引用通用的服務配置
image: myapp/worker:latest
volumes:
- ./worker1:/app
worker2:
<<: *default-service # 引用通用的服務配置
image: myapp/worker:latest
volumes:
- ./worker2:/app
透過 docker compose config 來檢查一下唄! 我們可以看到「web1」的部份成功的套入logging及environment了。
name: yaml-example
services:
web1:
environment:
DEBUG: "false"
ENV: production
image: nginx:latest
logging:
driver: json-file
options:
max-file: "10"
max-size: 200k
networks:
default: null
ports:
- mode: ingress
target: 80
published: "8081"
protocol: tcp
原來YAML也有程式的影子所在啊! 可以透過標記的方式來減少複雜的配置檔, 這對於維運來說非常的方便, 我們只要在標記來源進行共用參數的修改即可套用到各個服務, 而不用一個一個去慢慢修改, 非常耗時又容易出錯, 因此在設計的源頭我們就應該把這個地方做好, 讓未來維護可以更加簡單, 也不需要不斷的加班除措。