在 Kubernetes 生態系統中,Helm 已經成為應用佈署的事實標準工具。透過範本化機制,Helm 大幅簡化了 Kubernetes 資源的管理複雜度。經過長期的容器化技術實踐,我發現 Helm 的真正價值在於其強大的範本化能力與高度可重用性。本文將深入探討如何建構結構良好的 Helm Chart,並運用範本化技術提升佈署效率與維護性。

Helm Chart 的核心架構設計

Chart.yaml 檔案的關鍵定義

Chart.yaml 是 Helm Chart 的核心元件,定義了 Chart 的基本資訊與中繼資料。在開發流程中,這個檔案通常是最先需要建立的配置檔。

apiVersion: v2
name: pacman
type: application
version: 0.1.0
appVersion: "1.0.0"

這個配置檔包含了幾個關鍵元素。apiVersion 指定使用的 Helm API 版本,目前主流版本為 v2,提供了更完善的功能與向後相容性。name 定義了 Chart 的名稱,這個名稱會反映在佈署資源的命名中,影響整個資源識別體系。version 代表 Chart 本身的版本號,當 Chart 定義發生變更時應該更新此值,這與應用程式版本是分開管理的。appVersion 則是應用程式的版本號,獨立於 Chart 版本進行追蹤。type 欄位指定這是一個 application 類型的 Chart,而非 library 類型。

在微服務架構的實踐中,清晰定義這些元素對於版本管理與依賴追蹤至關重要。特別是在複雜的服務網格環境中,準確的版本資訊能夠有效避免佈署衝突與相依性問題。

@startuml
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

package "Helm Chart 架構" {
  component "Chart.yaml" as chart
  component "values.yaml" as values
  component "templates/" as templates
  component "_helpers.tpl" as helpers
}

chart --> templates : 定義中繼資料
values --> templates : 提供預設值
helpers --> templates : 提供範本函式

note right of chart
  定義 Chart 基本資訊
  - apiVersion
  - name
  - version
  - appVersion
end note

note right of values
  定義可覆寫的預設值
  - image
  - replicaCount
  - securityContext
end note

note right of templates
  包含所有 Kubernetes
  資源範本檔案
end note

@enduml

建立彈性化的佈署範本

Helm 的核心價值體現在範本化能力上。透過範本語法,我們可以建立高度彈性的資源定義。以下展示一個完整的 deployment.yaml 範本實作。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Chart.Name }}
  labels:
    app.kubernetes.io/name: {{ .Chart.Name }}
    {{- if .Chart.AppVersion }}
    app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
    {{- end }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app.kubernetes.io/name: {{ .Chart.Name }}
  template:
    metadata:
      labels:
        app.kubernetes.io/name: {{ .Chart.Name }}
    spec:
      containers:
      - image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
        imagePullPolicy: {{ .Values.image.pullPolicy }}
        securityContext:
          {{- toYaml .Values.securityContext | nindent 14 }}
        name: {{ .Chart.Name }}
        ports:
        - containerPort: {{ .Values.image.containerPort }}
          name: http
          protocol: TCP

這個佈署範本展示了 Helm 範本化的多項強大功能。透過 Chart.Name 從 Chart.yaml 注入名稱,確保命名一致性。條件式語法 if .Chart.AppVersion 只在版本存在時加入標籤,避免空值問題。使用 quote 管道函式對值進行引號處理,確保 YAML 格式正確性。從 values.yaml 提取 replicaCount 設定副本數量,提供環境客製化能力。toYaml 函式將 YAML 物件插入範本,支援複雜結構的嵌入。nindent 函式確保正確的縮排,維持 YAML 格式的嚴謹性。

這種範本化方式使佈署配置變得極為靈活。在不同環境間切換時,只需調整 values.yaml 或使用不同的值檔案,就能快速適應開發、測試、生產等多種場景的需求。

@startuml
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

start

:讀取 Chart.yaml;
:讀取 values.yaml;
:讀取 templates/;

partition "範本渲染流程" {
  :解析範本變數;
  :套用 helper 函式;
  :執行條件邏輯;
  :應用管道函式;
}

:生成最終 YAML;

if (驗證語法?) then (通過)
  :輸出 Kubernetes 資源;
  stop
else (失敗)
  :顯示錯誤訊息;
  stop
endif

@enduml

服務範本的設計原則

服務範本負責將應用程式暴露給叢集內外的使用者。service.yaml 的設計需要確保與 Deployment 的標籤選擇器完美對應。

apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: {{ .Chart.Name }}
  name: {{ .Chart.Name }}
spec:
  ports:
  - name: http
    port: {{ .Values.image.containerPort }}
    targetPort: {{ .Values.image.containerPort }}
  selector:
    app.kubernetes.io/name: {{ .Chart.Name }}

服務範本相對簡潔但至關重要。使用一致的命名方式與 Deployment 資源保持同步,確保資源識別的統一性。從 values.yaml 取得容器連接埠配置,避免硬編碼帶來的維護問題。確保 selector 與 Deployment 中的標籤精確匹配,實現正確的服務發現機制。

在大型微服務架構的實踐中,維持這種標籤與選擇器的一致性對於問題排查與系統維護極為關鍵。當服務網格中包含數十個甚至上百個服務時,標準化的命名與標籤策略能夠大幅降低運維複雜度。

values.yaml 的配置管理策略

values.yaml 檔案提供 Chart 的預設值,這些值在佈署時可以被覆寫,實現不同環境的客製化配置。

image:
  repository: quay.io/gitops-cookbook/pacman-kikd
  tag: "1.0.0"
  pullPolicy: Always
  containerPort: 8080
replicaCount: 1
securityContext: {}

這個配置檔案定義了容器映像的完整資訊。repository 指定映像倉庫位置,tag 定義映像版本,pullPolicy 決定映像拉取策略。containerPort 設定容器監聽的連接埠。replicaCount 定義預設的副本數量,在生產環境中通常會提高此值以確保高可用性。securityContext 預設為空物件,允許在需要時提供完整的安全配置。

當需要增強安全性時,可以擴展 securityContext 配置。

securityContext:
  capabilities:
    drop:
    - ALL
  readOnlyRootFilesystem: true
  runAsNonRoot: true
  runAsUser: 1000

這個安全配置遵循最小權限原則。移除所有容器能力確保容器無法執行特權操作。設定唯讀根檔案系統防止執行時期的檔案修改。強制以非 root 使用者執行,降低潛在的安全風險。指定特定的使用者 ID 確保可預測的權限行為。

Helm 範本的進階技術應用

本地渲染與驗證機制

在實際佈署前預覽渲染後的 YAML 是 Helm 的強大功能之一。透過本地渲染,可以在不影響叢集的情況下驗證範本邏輯與值的結合是否符合預期。

helm template .

這個命令會輸出完整的 YAML 配置,包含所有 Service 與 Deployment 資源。透過檢查輸出內容,可以確認範本變數是否被正確替換,條件邏輯是否按預期執行,以及最終生成的資源定義是否符合需求。

在開發流程中,我通常會將渲染輸出重定向到檔案進行詳細檢查。

helm template . > rendered.yaml

這樣可以使用 diff 工具比較不同版本間的差異,或者使用 kubectl dry-run 進一步驗證資源的有效性。

動態值覆寫機制

Helm 允許在渲染或佈署時動態覆寫預設值,這對於多環境部署極為實用。

helm template --set replicaCount=3 .

這個命令將副本數量從預設的 1 增加到 3。set 參數支援點記法來設定巢狀值,例如 image.tag 或 securityContext.runAsUser。對於複雜的配置,也可以使用多個 set 參數。

helm template --set replicaCount=3 --set image.tag=2.0.0 .

這種靈活性使得同一個 Chart 可以適應從開發到生產的各種環境需求,真正實現基礎設施即程式碼的理念。

佈署生命週期管理

當渲染結果通過驗證後,就可以將 Chart 佈署到 Kubernetes 叢集。

helm install pacman .

佈署成功後,可以透過多種方式檢視相關資源的狀態。

kubectl get pods
kubectl get deployment
kubectl get services

Helm 提供了完整的佈署歷史追蹤能力。

helm history pacman

這個命令顯示所有佈署版本的詳細記錄,包括修訂版本號、更新時間、狀態、Chart 版本與應用版本。這對於追蹤變更歷史與問題排查非常有價值。當需要回復到先前版本時,這些歷史記錄提供了清晰的參考依據。

解除安裝 Chart 同樣簡單明瞭。

helm uninstall pacman

這個命令會移除所有相關的 Kubernetes 資源,包括 Deployment、Service、ConfigMap 等,確保環境的乾淨狀態。

@startuml
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

[*] --> 初始化
初始化 --> 渲染範本 : helm template
渲染範本 --> 驗證輸出 : 檢查 YAML
驗證輸出 --> 佈署應用 : helm install
佈署應用 --> 執行中
執行中 --> 升級版本 : helm upgrade
升級版本 --> 執行中
執行中 --> 回復版本 : helm rollback
回復版本 --> 執行中
執行中 --> 解除安裝 : helm uninstall
解除安裝 --> [*]

note right of 渲染範本
  可使用 --set 覆寫值
  支援多個值檔案
end note

note right of 執行中
  可查看佈署歷史
  helm history <release>
end note

@enduml

範本重用性的最佳實踐

_helpers.tpl 的架構設計

在開發 Helm Chart 時,經常會遇到需要在多個範本檔案中重複使用相同配置片段的情況。這正是 _helpers.tpl 檔案發揮作用的場景。透過集中管理可重用的範本片段,可以大幅提升維護效率與一致性。

在前述範例中,標籤選擇器在多處重複出現。

app.kubernetes.io/name: {{ .Chart.Name }}

這種重複不僅增加了維護負擔,也提高了出錯風險。當需要調整選擇器邏輯時,必須在每個使用位置進行修改,容易遺漏或產生不一致。

建立 _helpers.tpl 檔案來定義可重用的範本片段能夠有效解決這個問題。

{{- define "pacman.selectorLabels" -}}
app.kubernetes.io/name: {{ .Chart.Name }}
{{- end }}

這個範本定義了名為 pacman.selectorLabels 的片段,生成應用程式的選擇器標籤。使用命名空間作為前綴是重要的實踐原則,可以避免在引入依賴時發生名稱衝突。當 Chart 被其他 Chart 作為依賴引入時,這種命名策略能夠確保範本函式的唯一性。

在範本檔案中使用這個 helper 非常簡潔。

spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      {{- include "pacman.selectorLabels" . | nindent 6 }}
  template:
    metadata:
      labels:
        {{- include "pacman.selectorLabels" . | nindent 8 }}

這裡使用 include 函式引入定義的 helper。第一個參數是 helper 名稱,第二個參數是當前上下文,通常使用點符號代表根上下文。透過管道符號連接 nindent 函式進行適當的縮排處理。nindent 6 表示縮排 6 個空格,確保 YAML 格式的正確性。

這種方法帶來多重優勢。首先是減少重複程式碼,提升程式碼品質。其次是集中管理共用邏輯,當需要修改時只需更新一處。再者是簡化維護工作,降低錯誤發生機率。最後是提高一致性,確保所有使用位置的行為統一。

在實務應用中,helpers 的用途遠不止於標籤定義。可以用於複雜的條件邏輯、通用註解生成、環境變數配置、資源名稱標準化等多種場景。這極大提升了 Chart 的可維護性與可讀性。

命名範本的組織策略

對於更複雜的場景,可以在 _helpers.tpl 中定義多個相關的 helpers,形成完整的範本函式庫。

{{- define "pacman.labels" -}}
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
app.kubernetes.io/managed-by: {{ .Release.Service }}
{{- end }}

{{- define "pacman.selectorLabels" -}}
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/instance: {{ .Release.Name }}
{{- end }}

這個範例定義了兩個相關但用途不同的標籤集。pacman.labels 提供完整的標籤集合,包含名稱、實例、版本與管理者資訊,適用於資源的 metadata.labels。pacman.selectorLabels 則只包含選擇器所需的最小標籤集,用於 selector.matchLabels 與 template.metadata.labels,確保服務發現的準確性。

這種分層設計讓標籤使用更加靈活且符合 Kubernetes 最佳實踐。完整標籤提供豐富的中繼資料便於管理與監控,而選擇器標籤保持簡潔確保匹配的穩定性。

Sprig 函式庫的應用

Helm 整合了 Sprig 函式庫,提供了豐富的範本函式來處理字串、列表、字典等資料結構。這些函式大幅增強了範本的表達能力。

{{- define "pacman.fullname" -}}
{{- if .Values.fullnameOverride }}
{{- .Values.fullnameOverride | trunc 63 | trimSuffix "-" }}
{{- else }}
{{- printf "%s-%s" .Release.Name .Chart.Name | trunc 63 | trimSuffix "-" }}
{{- end }}
{{- end }}

這個範例展示了條件邏輯與字串處理函式的結合應用。首先檢查是否提供了 fullnameOverride 值,若存在則使用該值。使用 trunc 函式將字串截斷為 63 個字元,符合 Kubernetes 資源名稱的長度限制。trimSuffix 函式移除可能出現的尾隨連字號,確保名稱格式的正確性。若未提供覆寫值,則使用 printf 函式組合 Release 名稱與 Chart 名稱,同樣進行截斷與格式化處理。

這種設計確保生成的資源名稱既符合使用者的客製化需求,又遵守 Kubernetes 的命名規範,避免因名稱問題導致的佈署失敗。

with 語句簡化深層存取

對於巢狀結構的值存取,with 語句能夠簡化範本程式碼,提升可讀性。

{{- with .Values.resources }}
resources:
  {{- toYaml . | nindent 10 }}
{{- end }}

這個範例使用 with 語句建立了一個新的作用域。在 with 區塊內,點符號代表 .Values.resources 而非根上下文。這比重複寫完整路徑更加簡潔,特別是當需要多次參照同一個深層路徑時。toYaml 函式將值轉換為 YAML 格式,nindent 確保正確的縮排。

這種寫法不僅提升了程式碼的可讀性,也減少了打字錯誤的可能性。在處理複雜的巢狀配置時,with 語句是非常實用的工具。

@startuml
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

package "Helper 範本架構" {
  component "_helpers.tpl" as helpers {
    [selectorLabels]
    [labels]
    [fullname]
  }
  
  component "deployment.yaml" as deploy
  component "service.yaml" as service
  component "其他範本" as other
}

helpers --> deploy : include
helpers --> service : include
helpers --> other : include

note right of helpers
  集中管理可重用範本
  - 標籤定義
  - 命名規則
  - 通用邏輯
end note

note bottom of deploy
  使用 include 函式
  引入 helper 範本
end note

@enduml

標籤選擇器的管理策略

選擇器標籤的設計原則

在 Kubernetes 架構中,標籤選擇器是連接 Service 與 Deployment 的關鍵機制。透過 Helm 範本化這些選擇器,可以實現更靈活且一致的配置管理。

基本的 Service 定義展示了選擇器的核心作用。

apiVersion: v1
kind: Service
metadata:
  labels:
    app.kubernetes.io/name: pacman
  name: pacman
spec:
  ports:
  - name: http
    port: 8080
    targetPort: 8080
  selector:
    app.kubernetes.io/name: pacman

對應的 Deployment 定義確保 Pod 具有匹配的標籤。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: pacman
  labels:
    app.kubernetes.io/name: pacman
    app.kubernetes.io/version: "1.0.0"
spec:
  replicas: 1
  selector:
    matchLabels:
      app.kubernetes.io/name: pacman
  template:
    metadata:
      labels:
        app.kubernetes.io/name: pacman
    spec:
      containers:
      - image: "quay.io/gitops-cookbook/pacman-kikd:1.0.0"
        imagePullPolicy: Always
        securityContext: {}
        name: pacman
        ports:
        - containerPort: 8080
          name: http
          protocol: TCP

這些定義遵循 Kubernetes 推薦的標籤命名規範,使用 app.kubernetes.io 前綴。Service 透過 selector 將流量路由到具有匹配標籤的 Pod。Deployment 確保建立的 Pod 具有正確的標籤,實現服務發現機制。

使用 Helm 範本增強標籤管理

透過修改 _helpers.tpl 檔案,可以集中管理選擇器標籤的定義。

{{- define "pacman.selectorLabels" -}}
app.kubernetes.io/name: {{ .Chart.Name }}
app.kubernetes.io/version: {{ .Chart.AppVersion }}
{{- end }}

這個範本片段生成包含應用名稱與版本的標籤。Chart.Name 與 Chart.AppVersion 從 Chart.yaml 自動讀取,確保一致性。當需要更新標籤策略時,只需修改這個 helper 定義,所有使用位置會自動同步更新。

使用 helm template 命令渲染範本可以驗證輸出結果。

helm template .

渲染後的 Service 與 Deployment 會包含更新後的選擇器標籤,確保兩者的標籤匹配,維持服務發現的正確性。

在實務中,雖然 _helpers.tpl 是常見的檔案名,但 Helm 實際上會讀取任何以底線開頭的檔案中的範本定義。這提供了更大的組織靈活性,當 Chart 變得複雜時,可以將 helpers 分散到多個檔案中,按功能分類管理。

@startuml
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

participant Service
participant "選擇器標籤" as Selector
participant Deployment
participant Pod

Service -> Selector : 定義 selector
Selector -> Pod : 匹配標籤
Deployment -> Pod : 建立 Pod
Pod -> Pod : 設定標籤

note over Service
  spec.selector:
    app.kubernetes.io/name
    app.kubernetes.io/version
end note

note over Deployment
  spec.template.metadata.labels:
    app.kubernetes.io/name
    app.kubernetes.io/version
end note

Service --> Pod : 路由流量

@enduml

容器映像版本的管理機制

佈署與升級流程

在微服務架構中,頻繁更新容器映像是常態需求。Helm 提供了簡潔而強大的版本管理機制。

首先佈署應用的初始版本。

helm install pacman .

佈署完成後,檢查當前的版本狀態。

helm history pacman

輸出顯示版本歷史記錄,包含修訂版本號、更新時間、狀態、Chart 版本與應用版本。這些資訊對於追蹤變更與問題排查非常重要。

要更新容器映像,需要修改 values.yaml 檔案中的 image.tag 欄位。

image:
  repository: quay.io/gitops-cookbook/pacman-kikd
  tag: "1.1.0"
  pullPolicy: Always
  containerPort: 8080
replicaCount: 1
securityContext: {}

同時更新 Chart.yaml 中的 appVersion 欄位,反映應用程式的新版本。

apiVersion: v2
name: pacman
description: A Helm chart for Pacman
type: application
version: 0.1.0
appVersion: "1.1.0"

這裡展現了 Helm 的雙層版本控制概念。version 代表 Chart 本身的版本,當範本或結構變化時才需要更新。appVersion 代表應用程式的版本,反映容器映像的版本號。這種分離使得版本管理更加清晰與靈活。

執行升級命令套用新的配置。

helm upgrade pacman .

系統會顯示升級成功的訊息,包含新的修訂版本號與狀態資訊。使用 helm history 命令可以檢視完整的版本歷史,包括被取代的舊版本。

版本回復機制

Helm 不僅支援升級,還提供了便捷的回復功能。當發現新版本存在問題時,可以快速回復到先前的穩定版本。

helm rollback pacman 1

這個命令將應用回復到修訂版本 1 的狀態。回復操作本身會建立一個新的修訂版本,完整保留操作歷史。透過 helm history 可以看到回復記錄,包括回復到哪個版本。

這種版本管理機制在生產環境中極為重要。當新版本導致問題時,可以迅速回復,最小化服務中斷時間。同時完整的歷史記錄提供了清晰的審計軌跡。

外部值檔案的應用

除了直接修改 values.yaml 或使用 set 參數,Helm 還支援使用外部值檔案覆寫配置。這在管理多環境佈署時特別實用。

建立一個名為 newvalues.yaml 的檔案,只包含需要覆寫的值。

image:
  tag: "1.2.0"

使用此檔案渲染範本。

helm template pacman -f newvalues.yaml .

渲染輸出會使用新指定的映像標籤,而其他未覆寫的值保持預設設定。這種方式讓環境配置管理更加靈活,可以為不同環境維護獨立的值檔案,同時共用相同的 Chart 定義。

在實務中,通常會為開發、測試、預發布、生產等環境各準備一個值檔案。佈署時只需指定對應的檔案,就能確保環境特定的配置被正確套用,實現一致且可重複的佈署流程。

@startuml
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

state "版本 1.0.0" as v1
state "版本 1.1.0" as v2
state "版本 1.2.0" as v3

[*] --> v1 : helm install
v1 --> v2 : helm upgrade
v2 --> v3 : helm upgrade
v3 --> v2 : helm rollback

note right of v1
  初始佈署
  Revision 1
end note

note right of v2
  升級版本
  Revision 2
end note

note right of v3
  再次升級
  Revision 3
end note

note bottom of v2
  回復至穩定版本
  建立 Revision 4
end note

@enduml

Chart 的封裝與分發機制

Chart 封裝流程

隨著 Chart 數量增加,組織與分享變得至關重要。Helm 提供了完整的封裝與分發機制,簡化 Chart 的管理與散佈。

封裝 Chart 的操作非常簡單。

helm package .

這個命令會在當前目錄生成一個壓縮檔案,檔名格式為 chart-name-version.tgz。例如 pacman-0.1.0.tgz,包含了 Chart 的所有檔案與資源定義。

Chart 倉庫的建立

Helm Chart 倉庫是一個 HTTP 伺服器,提供封裝好的 Chart 檔案與中繼資料索引。倉庫的基本結構包含壓縮的 Chart 檔案與一個 index.yaml 索引檔。

repo
├── index.yaml
├── pacman-0.1.0.tgz

index.yaml 檔案是倉庫的核心,包含所有可用 Chart 的詳細資訊。

apiVersion: v1
entries:
  pacman:
    - apiVersion: v2
      appVersion: 1.0.0
      created: "2022-01-24T16:42:54.080959+01:00"
      description: A Helm chart for Pacman
      digest: aa3cce809ffcca86172fc793d7804d1c61f157b9b247680a67d5b16b18a0798d
      name: pacman
      type: application
      urls:
        - pacman-0.1.0.tgz
      version: 0.1.0
generated: "2022-01-24T16:42:54.080485+01:00"

索引檔案包含每個 Chart 的完整中繼資料。apiVersion 定義索引格式版本,appVersion 記錄應用程式版本,created 標記建立時間。description 提供 Chart 說明,digest 是 SHA256 校驗和用於驗證完整性。urls 列出 Chart 檔案的位置,可以是相對或絕對路徑。version 標示 Chart 版本號。

使用 helm repo index 命令可以自動生成索引檔案。

helm repo index .

這個命令會掃描目錄中的所有 Chart 檔案,生成或更新 index.yaml。這大幅簡化了倉庫維護工作,特別是當倉庫包含多個 Chart 時。

Chart 簽署與安全驗證

在企業環境中,確保 Chart 的完整性與真實性至關重要。Helm 支援使用 GPG 金鑰對 Chart 進行數位簽署。

假設已有 GPG 金鑰對,可以在封裝時加入簽署。

helm package --sign --key 'me@example.com' --keyring /home/me/.gnupg/secring.gpg .

這個命令會生成兩個檔案,Chart 壓縮檔與對應的簽名檔。

.
├── Chart.yaml
├── pacman-0.1.0.tgz
├── pacman-0.1.0.tgz.prov
├── templates
│   ├── deployment.yaml
│   └── service.yaml
└── values.yaml

.prov 檔案包含加密簽名與摘要資訊。使用者下載 Chart 時,可以使用 verify 命令驗證簽名的有效性。

helm verify pacman-0.1.0.tgz

成功的驗證會顯示簽署者資訊、金鑰指紋與 Chart 雜湊值。這確保 Chart 未被篡改且來源可信。在分散式團隊或開源專案中,這種驗證機制能夠有效防止惡意修改,保障佈署的安全性。

在實務中,我建議為生產環境的 Chart 都進行簽署。雖然增加了一些作業流程,但對於保障系統安全性來說是值得的投資。特別是在處理敏感應用或金融系統時,簽署驗證應該是強制性的安全要求。

@startuml
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

actor 開發者
participant "本地 Chart" as local
participant "封裝工具" as package
participant "Chart 倉庫" as repo
participant "使用者" as user

開發者 -> local : 開發 Chart
開發者 -> package : helm package --sign
package -> package : 生成 .tgz 檔案
package -> package : 生成 .prov 簽名檔
package -> repo : 上傳至倉庫
repo -> repo : 更新 index.yaml
user -> repo : helm repo add
user -> repo : helm search
user -> repo : helm install
repo -> user : 下載 Chart
user -> user : helm verify
user -> user : 驗證簽名

note right of package
  使用 GPG 金鑰簽署
  確保 Chart 完整性
end note

note right of user
  驗證數位簽名
  確認來源可信
end note

@enduml

從倉庫安裝與管理 Chart

倉庫的註冊與管理

在實際工作中,從倉庫安裝 Chart 是最常見的使用方式,相較於本地開發更加便利與安全。

首先需要將倉庫註冊到 Helm 配置中。

helm repo add bitnami https://charts.bitnami.com/bitnami

註冊成功後,可以檢視所有已配置的倉庫。

helm repo list

輸出顯示倉庫名稱與對應的 URL 位址。這些倉庫可以是公開的社群倉庫,也可以是企業內部的私有倉庫。

Chart 搜尋與探索

要尋找特定的應用 Chart,使用 search 命令可以快速定位。

helm search repo postgresql

系統會回傳所有符合條件的 Chart,包含版本資訊與簡短描述。輸出結果通常包括 Chart 名稱、Chart 版本、應用版本與功能說明。這幫助使用者快速評估不同 Chart 的適用性。

從倉庫安裝應用

確定要安裝的 Chart 後,使用 install 命令進行佈署。

helm install my-db \
  --set postgresql.postgresqlUsername=my-default,postgresql.postgresqlPassword=postgres,postgresql.postgresqlDatabase=mydb,postgresql.persistence.enabled=false \
  bitnami/postgresql

這個命令執行了完整的佈署流程。將佈署命名為 my-db 便於後續管理。透過 set 參數覆寫預設配置,設定資料庫使用者名稱、密碼與資料庫名稱。關閉持久化儲存適合測試環境,生產環境則應啟用以確保資料持久性。指定使用 Bitnami 倉庫的 PostgreSQL Chart。

在生產環境的實踐中,建議使用外部值檔案而非命令列參數。這樣可以更好地管理配置,進行版本控制,並且避免敏感資訊出現在命令歷史中。

佈署後的資源檢查

佈署完成後,檢查相關的 Kubernetes 資源確保一切正常。

kubectl get pods
kubectl get services
kubectl get statefulset
kubectl get secrets

這些命令顯示佈署建立的所有資源。Pods 展示執行中的容器實例,Services 提供網路端點,StatefulSet 管理有狀態的應用實例,Secrets 儲存敏感配置如密碼。

檢視 Chart 的配置選項

使用第三方 Chart 時,瞭解所有可配置的參數對於客製化至關重要。

helm show values bitnami/postgresql

這個命令顯示 Chart 的完整配置文件,包含所有可設定的參數與預設值。輸出通常包含詳細的註解說明每個參數的用途與可能的值。這對於理解 Chart 功能與進行深度客製化非常有幫助。

在實務中,我通常會將這個輸出儲存為檔案,作為客製化配置的起點。根據實際需求修改必要的參數,然後使用該檔案進行佈署,確保配置的可追溯性與可重複性。

@startuml
!define PLANTUML_FORMAT svg
!theme _none_

skinparam dpi auto
skinparam shadowing false
skinparam linetype ortho
skinparam roundcorner 5
skinparam defaultFontName "Microsoft JhengHei UI"
skinparam defaultFontSize 16
skinparam minClassWidth 100

start

:helm repo add;
note right
  註冊 Chart 倉庫
end note

:helm repo update;
note right
  更新倉庫索引
end note

:helm search repo;
note right
  搜尋所需 Chart
end note

:helm show values;
note right
  檢視配置選項
end note

:helm install;
note right
  安裝 Chart
  可使用 --set 或 -f
end note

:kubectl get resources;
note right
  驗證佈署結果
end note

stop

@enduml

總結與最佳實踐

Helm Chart 開發是結合 Kubernetes 資源管理與範本程式設計的實務技術。透過掌握 Chart 結構設計、範本化技巧與 helpers 重用機制,能夠建立既靈活又易於維護的應用佈署方案。

在長期的實踐中,良好的範本設計能夠顯著降低維護成本,提升團隊協作效率。從簡單的佈署開始,逐步引入範本化與重用技術,最終構建出適應各種環境與需求的 Helm Chart。無論是單體應用還是複雜的微服務架構,這些技術都能幫助實現更高效的 Kubernetes 資源管理,真正落實基礎設施即程式碼的理念。

建議在開發 Chart 時遵循以下原則。使用語意化版本管理區分 Chart 版本與應用版本。善用 _helpers.tpl 集中管理可重用範本邏輯。遵循 Kubernetes 推薦的標籤命名規範。為不同環境準備獨立的值檔案。在生產環境啟用 Chart 簽署驗證。維護完整的版本歷史便於追蹤與回復。使用外部倉庫管理與分享 Chart。定期更新依賴的第三方 Chart。

透過這些實踐,可以建立穩健且可擴展的 Helm Chart 架構,支撐現代化的 Kubernetes 應用佈署需求。