iT邦幫忙

2025 iThome 鐵人賽

DAY 8
0
自我挑戰組

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

Day 8 瀏覽 Bitnami Library ,學習建構Helm Chart

  • 分享至 

  • xImage
  •  

Bitnami Library 是一個非常實用的 Helm Library,裡面收錄了大多數知名服務,並且持續維護。對 DevOps 人員來說,它就像一個百寶箱,在專案初期就能快速進行 POC。

今天,我們就從 Kafka 開始,帶大家一起認識並使用它。


TL;DR

helm install my-release oci://registry-1.docker.io/bitnamicharts/kafka

你可能在每個 Helm repository 都看到過這樣的指令。是的,使用 Helm 部屬一個服務就是這麼簡單,就像安裝一個 package 一樣。

但我們也可以注意一些細節:

  • helm install 是 Helm 的基本安裝指令。
  • my-release 是部屬服務的名稱,也就是所謂的 release,Helm 會對它進行版本管理。
  • oci://registry-1.docker.io/bitnamicharts/kafka 中的 OCI 協議,是 container 與 Helm 共用的儲存方式。透過 OCI registry,你可以像使用 Git 一樣進行推送、儲存和版本管控。

建議大家先打開 README.md 來看,這是使用封裝好服務的好習慣。README 裡會列出這個 Chart 的主要參數,幫助我們了解如何調整服務設定。

簡單介紹一下 Kafka:它是一個訊息串流平台,不同於一般的串流服務,Kafka 更重視資料的 儲存與重用能力。這也是為什麼它能夠支撐大量事件流,並提供可靠的訊息保留功能。

經過這些介紹,相信你已經對 Helm Library 有了初步認識。接下來,我們就跟著 Kafka 的專案結構,一步步了解它是怎麼建構的。


接下來,我們來看看 Kafka Chart templates 目錄結構

templates/
├── broker                        - 建構 broker 所需的服務
├── controller-eligible           - 建構 controller 所需的服務(負責狀態管理)
├── metrics                       - 監控指標
├── provisioning                  - 協助建構 topic 等
├── rbac                          - 集群 serviceAccount & Role 設定
├── NOTES.txt
├── _helpers.tpl                  - 定義共用模板與邏輯
├── _init_containers.tpl          - 初始化容器的模板
├── ca-cert.yaml
├── cert.yaml
├── extra-list.yaml
├── log4j2-configmap.yaml
├── secrets.yaml
├── svc.yaml
└── tls-secret.yaml

這個主目錄設計符合 Helm 官方最佳實踐

  • 一個服務一個檔案,命名使用小寫加 - 連結。
  • 每個模板檔案各司其職,讓 Chart 結構清晰易維護。

再來看一個 _helpers.tpl 的範例節錄:

{{/*
Return the proper Kafka controller-eligible fullname
*/}}
{{- define "`kafka.controller`.fullname" -}}
{{- printf "%s-controller" (include "common.names.fullname" .) | trunc 63 | trimSuffix "-" -}}
{{- end -}}
  • 這段模板會回傳 Kafka controller 的完整名稱。
  • 在 Helm 渲染過程中,所有模板都會同時被讀取,就像組成一個超長文本一樣。
  • 因此,tpl 的命名需要與服務命名空間對應,以避免混淆。
  • 範例中包括了 kafkacontroller 兩個服務命名空間。

接下來,我們來瀏覽Kafka的服務主體,也就是 templates/broker/statefulset.yaml

{{- $replicaCount := int .Values.broker.replicaCount }}
{{- if or (gt $replicaCount 0) .Values.broker.autoscaling.hpa.enabled }}
apiVersion: {{ include "common.capabilities.statefulset.apiVersion" . }}
kind: StatefulSet
metadata:
  name: {{ template "kafka.broker.fullname" . }}
  namespace: {{ include "common.names.namespace" . | quote }}
  labels: {{- include "common.labels.standard" ( dict "customLabels" .Values.commonLabels "context" $ ) | nindent 4 }}
    app.kubernetes.io/component: broker
    app.kubernetes.io/part-of: kafka
  • 如同上一章提到的原則,盡可能減少模板內的邏輯,並搭配 _helpers.tpl 使用。
  • 與前面不同的是,Bitnami 幾乎把所有變數處理都寫在 _helpers.tpl,這樣可以更嚴謹地控制命名與數值。

annotations 的設計

annotations:
  {{- if include "kafka.broker.createConfigmap" . }}
  checksum/configuration: {{ include (print $.Template.BasePath "/broker/configmap.yaml") . | sha256sum }}
  {{- end }}
  {{- if or (include "kafka.createSaslSecret" .) (not .Values.existingKraftSecret) }}
  checksum/secret: {{ include (print $.Template.BasePath "/secrets.yaml") . | sha256sum }}
  {{- end }}
  {{- if include "kafka.createTlsSecret" . }}
  checksum/tls-secret: {{ include (print $.Template.BasePath "/tls-secret.yaml") . | sha256sum }}
  {{- end }}
  {{- if include "kafka.metrics.jmx.createConfigmap" . }}
  checksum/jmx-configuration: {{ include (print $.Template.BasePath "/metrics/jmx-configmap.yaml") . | sha256sum }}
  {{- end }}
  {{- if .Values.broker.podAnnotations }}
  {{- include "common.tplvalues.render" (dict "value" .Values.broker.podAnnotations "context" $) | nindent 8 }}
  {{- end }}
  • 你會發現,Bitnami 頻繁使用 if 判斷,這是為了考慮更多使用者場景,確保值存在才使用,避免出現 Exception。
  • 同時,它也利用 sha256sum 對 ConfigMap 和 Secret 做 checksum,這樣可以確保 Pod 在內容變更時自動滾動更新。

Bitnami common 模組

Bitnami Library 的一個特色是引入了 common 模組,統一管理整個 Library 的共用模板,並在每個專案中透過 dependency 引用。

{{- define "kafka.controller.fullname" -}}
{{- printf "%s-controller" (include "`common.names.fullname`" .) | trunc 63 | trimSuffix "-" -}}
{{- end -}}
  • common 中包含許多通用模板,例如:
templates/
├── _affinities.tpl
├── _capabilities.tpl
├── _compatibility.tpl
├── _errors.tpl
├── _images.tpl
├── _ingress.tpl
├── _labels.tpl
├── _names.tpl
├── _resources.tpl
├── _secrets.tpl
├── _storage.tpl
├── _tplvalues.tpl
├── _utils.tpl
├── _warnings.tpl
└── validations
  • 這種設計讓每個 Chart 可以專注在自身邏輯,共用邏輯與函數集中管理,提高可維護性

接下來,我們來瀏覽 Kafka Chart 的 values.yaml

你會發現,整個文件 包含註解多達 2487 行,去掉註解後仍有 731 行。如果後續真的要使用,可以進一步 移除掉沒有使用的行數,保持精簡。

值得注意的是,雖然行數很多,但 最深的階層也只有四層,並不複雜。


範例TLS設定

tls:
  type: JKS
  pemChainIncluded: false
  autoGenerated:
    enabled: true
    engine: helm
    customAltNames: []
    certManager:
      existingIssuer: ""
      existingIssuerKind: ""
      keySize: 2048
      keyAlgorithm: RSA
      duration: 2160h
  • 經過整理,第一層的參數僅有 49 項,代表主要服務項目大致上就是這些。
  • 在實作時,先規劃好第一層項目是一種很實用的方法,能幫助我們快速理解整個 Chart 的結構。

範例:Broker 預設設定

broker:
  replicaCount: 0
  minId: 100
  config: {}
  overrideConfiguration: {}
  existingConfigmap: ""
  secretConfig: ""
  existingSecretConfig: ""
  heapOpts: -XX:InitialRAMPercentage=75 -XX:MaxRAMPercentage=75
  command: []
  args: []
  extraEnvVars: []
  extraEnvVarsCM: ""
  extraEnvVarsSecret: ""
  extraContainerPorts: []
  • 注意 預設值會影響服務行為,例如 replicaCount: 0 代表初始不啟動 broker。
  • 留意空值是 {} 還是 [],不同形式會影響 Helm 渲染與 Kubernetes 資源產生的結果。

小結

今天我們透過瀏覽 Bitnami Library 的 Kafka Chart,學到了不少實務與設計技巧:

  1. Helm 部署快速入門

    • 使用 helm install 就像安裝 package 一樣簡單。
    • Release 名稱與 OCI registry 讓 Helm 可以進行版本管理與儲存控制。
  2. Chart 結構與模板設計

    • Templates 目錄清楚分工,每個檔案各司其職。
    • _helpers.tpl 負責共用邏輯,減少模板內部複雜度。
    • StatefulSet 與 annotations 的設計透過 if 判斷與 checksum,確保通用性與安全性。
  3. Common 模組的價值

    • Bitnami 將常用模板統一放在 common 中,提升整個 Library 的可維護性。
    • 各個專案透過 dependency 引用,專注自身邏輯。
  4. Values.yaml 管理技巧

    • 雖然行數多,但層級淺、結構清晰。
    • 第一層參數即為主要服務項,先掌握這些就能快速調整服務。
    • 預設值與空值的選擇會直接影響服務行為,務必要注意。

  • 透過 Bitnami Library,我們可以很快理解一個 Chart 的架構,並掌握 Helm 的設計哲學。
  • 減少模板內邏輯、善用 _helpers.tpl、保留通用性,是實務中非常重要的設計思路。
  • 這些技巧不只是 Kafka 專屬,而是可以套用到任何 Helm Chart 的通用方法。

希望今天的分享,能幫助你在實作 Helm Chart 時更有方向感。明天,我們將探索 Helm 的部屬與管理

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


上一篇
Day7 Helm template 常用函數與最佳實踐
下一篇
Day9 Helm Chart 部署與版本管理
系列文
雲端與資料平台實戰:從抽象概念到落地技術9
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言