2024-09-25|閱讀時間 ‧ 約 23 分鐘

【資料交換格式 - YAML】善用Anchors與Aliases讓我們的YAML更簡潔

使用docker compose來編排容器化程式非常的方便, 但隨著應用越來越複雜, 我們每個Service會有許多共同掛載的目錄、環境變數, 那這些在傳統的程式語言都能藉由繼承、覆寫的技巧來簡化程式碼, 但在YAML呢? 有沒有這樣的功能呢?


答案是有的, 也就是 anchors & aliases 這兩個技巧, 那就讓我們來好好的了解一番吧!


錨點(Anchors)與別名(Aliases)

它讓我們標記某一段節點並使用別名重新命名, 讓我們在其他地方可以使用這個標記, 藉此減少重複代碼。


各個符號詳細說明如下:

  • &: 錨定某個區塊, 可以讓其他區塊引用。
  • *: 參考錨定的別名區塊。
  • <<: : 合併錨定的別名區塊, 這有利於擴充。
    • ❗ 僅限於map, 不允許Array List。



首先我們看一下這段非常冗長的compose檔

以下這段我們可以看到很多重複的設定, 包括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也有程式的影子所在啊! 可以透過標記的方式來減少複雜的配置檔, 這對於維運來說非常的方便, 我們只要在標記來源進行共用參數的修改即可套用到各個服務, 而不用一個一個去慢慢修改, 非常耗時又容易出錯, 因此在設計的源頭我們就應該把這個地方做好, 讓未來維護可以更加簡單, 也不需要不斷的加班除措。

分享至
成為作者繼續創作的動力吧!
© 2024 vocus All rights reserved.