iT邦幫忙

2025 iThome 鐵人賽

DAY 6
0
自我挑戰組

雲端與資料平台實戰:從抽象概念到落地技術系列 第 6

Day6 設計 Helm values.yaml:為什麼減少階層可以更優雅

  • 分享至 

  • xImage
  •  

延續前一日對 Helm values 的介紹,今天我們來探討 如何讓 values 的設計更為優雅

在最初的例子中,我們只設定了 replica、image 與 resource,畫面簡潔清爽。然而,一旦加入 親和度(affinity),整份 values.yaml 就會立刻變得臃腫。


範例:層層縮排的傳統寫法

replicaCount: 2
image:
  repository: nginx
  tag: "1.25"
resources:
  limits:
    cpu: "500m"
    memory: "256Mi"
  nodeAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
      nodeSelectorTerms:
        - matchExpressions:
            - key: "kubernetes.io/arch"
              operator: "In"
              values:
                - "amd64"
                - "arm64"

這樣的寫法在服務單一時還能接受,但如果 多個服務共用一份 values.yaml,光是想像就讓人窒息。
造成這種冗長的根本原因在於:資訊被綁死在過多的階層中


解法:將「縮排」轉化為「拼接」

如果我們願意把縮排轉化為「拼接訊息」,整體結構可以大幅簡化。

nginx-1.25:
  limit:cpu-1.mem-512Mi
  request:cpu-500m.mem-256Mi
  nodeAffinity:
    - kubernetes.io/arch=amd64
    - kubernetes.io/arch=arm64

mysql-9.4.0:
  limit:cpu-1.mem-512Mi
  request:cpu-500m.mem-256Mi
  nodeAffinity:
    - kubernetes.io/arch=amd64
    - kubernetes.io/arch=arm64

這樣寫的好處:

  1. 扁平結構 → 瀏覽更輕鬆,方便比較多個服務。
  2. 拼接式設計 → 將資訊壓縮為字串,由 _help.tpl 邏輯解析還原。
  3. 符合直覺 → 更像清單,而非複雜的 JSON map。

範例:以資源為重心,透過_help.tpl解析

Helm values 是團隊的介面,並沒有唯一的設計風格。
如果專注於 資源配置,我們甚至可以將資訊集中在一個區塊:

resource:
  nginx: lcpu-1-lmem-512Mi.rcpu-500m-rmem-256Mi
  mysql: lcpu-1-lmem-512Mi.rcpu-500m-rmem-256Mi

這種 values 乍看怪異,但可以搭配 tpl 解析回傳統格式。

_help.tpl:解析邏輯

{{- define "parse.resource" -}}
{{- $svc := .svc -}}
{{- $raw := index .Values.resource $svc -}}
{{- $items := splitList "." $raw -}}
limits:
  cpu: {{ index (splitList "-" (index $items 0)) 1 }}
  memory: {{ index (splitList "-" (index $items 0)) 3 }}
requests:
  cpu: {{ index (splitList "-" (index $items 1)) 1 }}
  memory: {{ index (splitList "-" (index $items 1)) 3 }}
{{- end -}}

呼叫方式

resources:
{{ include "parse.resource" (dict "svc" "nginx" "Values" .Values) | nindent 2 }}

渲染結果

resources:
  limits:
    cpu: 1
    memory: 512Mi
  requests:
    cpu: 500m
    memory: 256Mi

tpl就像javascript之於html,可以協助我們進行邏輯的判斷與重組,盡可能的活用tpl可以讓我們設計出符合團隊需求的內容。


範例:同一份value運用 Group 提供給兩個服務使用

我們再分享另一個範例。
真實場景中,常會遇到 資料來源不對稱 的需求,例如服務A需要以DB為主體,服務B需要以dataset為主體,但為了保證服務的穩定,我們需要使用同一份value,此時,我們一樣可以透過使用 _help.tpl 編寫邏輯處理。

舉例來說,我們有一份 values:

DB-1:
  dataset: dataset-A
  table:
    - table-1
    - table-2
DB-2:
  dataset: dataset-A
  table:
    - table-x
    - table-y
DB-3:
  dataset: dataset-B
  table:
    - table-n
    - table-h

現在希望按照 dataset 重新 group,可以寫一個 _groupby.tpl

{{- define "groupby.dataset" -}}
{{- $out := dict -}}
{{- range $dbName, $conf := .Values -}}
  {{- if hasKey $conf "dataset" -}}
    {{- $ds := $conf.dataset -}}
    {{- $tables := $conf.table | default (list) -}}
    {{- $exist := get $out $ds | default (list) -}}
    {{- $_ := set $out $ds (concat $exist $tables) -}}
  {{- end -}}
{{- end -}}
{{- toYaml $out -}}
{{- end -}}

呼叫方式:

datasets:
{{ include "groupby.dataset" . | nindent 2 }}

輸出結果:

datasets:
  dataset-A:
    - table-1
    - table-2
    - table-x
    - table-y
  dataset-B:
    - table-n
    - table-h

這種設計思路就是:

邏輯交給 _help.tpl,介面留給操作者。

values 像一份表單,使用者只需填寫欄位。


範例: Kafka,多資源階層的壓縮

經過上面兩個範例,相信讀者對於tpl的功用已經有所了解,接下來我們稍稍討論關於參數命名的問題。
在部屬 Kafka 資源時,設定中常見多種服務同時在一份value中進行多階層的規劃,這種規劃不但冗長,還充滿重複的 key:

kafka:
  nodepool:
    broker:
      kafkaCluster:
        name:
    controller:
      kafkaCluster:
        name:
    connect:
      kafkaCluster:
        name:

若將重複的資訊提取出來,例如:kafkaCluster.name;並透過拼接組合壓縮階層:

kafka_cluster_name: my-cluster
broker-pool: {...}
controller-pool: {...}
connect-pool: {...}

透過重新的拼接,我們將資訊抽象化並加以壓縮(例如將 nodepool 的設定整合為 broker-poolcontroller-pool...)。同時,將 kafkaCluster.name 提取出來,不僅能 避免重複輸入造成的錯誤,也讓 nodepool 的訊息從結構中 解耦

這正是「減少階層」的核心:

資訊的傳遞,不必依附在縮排,而是透過拼接與解耦來完成。
程式的本質,不在於結構,而在於訊息的流動。


小結

今天的分享圍繞在主題:設計 Helm values,減少階層可以更優雅。
我們透過將 層級壓縮,以 字串拼接 來承載資訊,讓結構更直覺;同時避免重複填寫,減少閱讀時的心智消耗。這樣的設計,讓 values 不只是設定檔,而是一個 供團隊操作的介面。

另一方面,將複雜的解析邏輯封裝進 _help.tpl,把細節交給 go 語言 去處理,使得 values 更專注於「表達」而非「計算」。

相信透過這樣的思路,讀者能夠設計出 更彈性、更易維護 的 Helm values.yaml。

感謝各位閱讀,我們明天見!


上一篇
Day5 從宣告式配置理解helm的運作
下一篇
Day7 Helm template 常用函數與最佳實踐
系列文
雲端與資料平台實戰:從抽象概念到落地技術9
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言