昨天我們為 todo-api 拆出了 Deployment、Service 與 Ingress。一份 YAML 在單一環境通常就夠用,但在生產環境中,我們通常還要面對 Dev、Staging 和 Prod 等多個環境不同設定,例如 Dev 只需要一個副本、Staging 使用測試網域、Prod 則要三個副本。若直接複製整個目錄三次,下次修改共用設定比如 probe 時,很容易漏掉其中一個環境。而複製貼上帶來的不只是維護麻煩,同一個服務的設定逐漸分岔後,故障表現也可能不同,code review 時也不容易判斷某段差異是環境需求,還是只是忘了同步修改。
這裡先把 Todo 微服務的設定分成三類,我們再來選工具:
管理工具的選擇最常見的就是標題說的 Helm 與 Kustomize。Helm 與 Kustomize 都能減少重複,差別在於管理方式。
以 Todo API 為例,Kustomize 會把部署 YAML 分成共用的 base 與各環境的 overlay:
apps/
todo-api/
base/
deployment.yaml
service.yaml
kustomization.yaml
overlays/
dev/kustomization.yaml
staging/kustomization.yaml
prod/kustomization.yaml
base 的 kustomization.yaml 只列出服務共用的資源,不放入任何環境專屬設定:
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- deployment.yaml
- service.yaml
Prod overlay 只描述相對於 base 的差異,比再複製一份完整 Deployment 更容易 review。
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ../../base
namespace: todo-prod
replicas:
- name: todo-api
count: 3
Kustomize 最後仍會產出完整的 Kubernetes YAML,不過 overlay 變多、patch 彼此覆蓋時,也會讓人難以預測結果。這時不該繼續把邏輯塞進 overlay,而是要重新檢查 base 的邊界,或將功能拆成明確的元件。
Helm 是 Kubernetes 的套件管理工具。由 Chart 作者決定 template 的結構,使用者則透過 values 調整 Chart 開放的設定。這系列我不想為了 todo-api 特別展開建立 Helm Chart,以下的 values 與 template 只用來說明 Chart 如何將設定轉成 Kubernetes manifest,並非可直接執行的專案範例。
replicaCount: 3
image:
repository: ghcr.io/yrw9281/todo-api
tag: "0.1.0"
ingress:
enabled: true
className: nginx
host: todo.example.internal
resources:
requests:
cpu: 250m
memory: 256Mi
template 會讀取 Values,再產生 Deployment。這裡只保留 image 和 replica 的關鍵行。
spec:
replicas: {{ .Values.replicaCount }}
template:
spec:
containers:
- name: todo-api
image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
Helm 適合封裝多個團隊共用的安裝設定,例如 Argo CD 或 observability stack。而如果 template 中堆滿巢狀 if、預設值和例外條件,使用者就很難從 values 看出實際會產生什麼。所以 Chart 應提供清楚的 values schema 與文件,不必把每個 Kubernetes 欄位都做成參數。
這個系列中,Todo 團隊維護的應用程式使用 Kustomize 管理環境 overlay;平台安裝的第三方元件則優先使用官方或受維護的 Helm Chart。理由有兩個:
兩者可以放在同一個交付流程中。無論選哪一種,Git 裡都應保留可審查的設定,並能重現渲染結果。
我們可以用以下指令提交前先渲染 manifest,而不直接套用:
# 檢視 Kustomize 為 Prod 組合出的完整 manifest
kubectl kustomize apps/todo-api/overlays/prod
驗收時不只確認有沒有輸出 YAML,還要檢查 Prod 是否使用 todo-prod Namespace、image 是否為預期版本、副本數是否為三,以及 base 的 readiness probe 和 Service selector 是否仍被保留。若未來採用第三方 Helm Chart,應依 Chart 的文件與實際 values 檔案執行 helm template,再檢查渲染結果。
另外,如果發現調整一個值就得在每個環境複製一大段 Deployment,代表目前的設定分層仍需要調整。
Kustomize 讓應用程式的共用設定與環境差異留在可直接 review 的 YAML 裡;Helm 則讓我們能沿用第三方元件的安裝方式與維護成果。選擇工具並不會消除 Kubernetes 的複雜度,服務團隊仍得理解 Deployment、Service、Ingress 的關係,才能判斷渲染出的設定是否符合預期。
當服務數量持續增加,要求每位開發者都處理這些底層細節,就不再是單靠上述的設定分層就能解決的問題。下一篇會介紹 CRD,先替 Kubernetes 新增一種叫做 Microservice 的資源。開發者只需填入服務要使用的 image 和 port,後續再由平台處理需要的資源。