Mark Ku's Blog
首頁 關於我
用 Helm 佈署應用:為什麼選 Helm 佈署Kubernetes 容器應用、怎麼裝、和純 YAML 的差異
DevOps
用 Helm 佈署應用:為什麼選 Helm 佈署Kubernetes 容器應用、怎麼裝、和純 YAML 的差異
Mark Ku
Mark Ku
September 24, 2025
2 min

前言

在容器化技術的演進過程中,我們經歷了從 Docker 到 Kubernetes 的轉變:

Docker 時代

  • 學習曲線相對平緩,一個 docker run 就能啟動應用
  • 單一容器,配置簡單,容易理解
  • 適合小型專案和個人開發

Kubernetes 時代

  • 功能強大,但學習曲線陡峭
  • 需要管理多種資源(Pod、Service、Deployment、Ingress 等)
  • 檔案數量爆炸式增長,維護成本高
  • 但提供了企業級的擴展性、高可用性和自動化能力

Helm 的出現

  • 讓 Kubernetes 的複雜性變得可管理
  • 就像 Docker 讓容器變得簡單一樣,Helm 讓 K8s 部署變得簡單
  • 一個 Chart 就能管理整個應用的生命週期
  • 抽換方便,版本管理清晰,回滾容易

但 Helm 也帶來了新的挑戰

  • 配置數量變得更多:除了原本的 YAML,還要學習 Chart 結構、values.yaml、模板語法
  • 學習曲線又更高了:需要理解 Go template、Helm 指令、Chart 生態圈
  • 初學者可能覺得 Helm 比純 YAML 更複雜
  • 但一旦掌握,維護及遷移成本會是比較低的。

什麼是 Helm?為什麼需要它?

想像你要在 Kubernetes 上部署一個完整的 Web 應用,你需要:

  • Deployment(Pod 管理)
  • Service(網路服務)
  • Ingress(外部存取)
  • ConfigMap(設定檔)
  • Secret(密碼)

如果每個環境(開發、測試、正式)都要手動寫這些 YAML,你會發現:

問題一:檔案爆炸

  • 開發環境:5 個 YAML 檔案
  • 測試環境:5 個 YAML 檔案
  • 正式環境:5 個 YAML 檔案
  • 總共 15 個檔案要維護!

問題二:參數混亂

  • 開發用 nginx:1.20,正式用 nginx:1.21
  • 開發 1 個副本,正式 3 個副本
  • 每次改版都要手動修改一堆檔案

問題三:版本管理困難

  • 出問題時不知道要回滾到哪個版本
  • 沒有清楚的部署歷史記錄

Helm 如何解決這些問題?

Helm 就像 Kubernetes 的「套件管理器」,把多個 YAML 檔案打包成一個「Chart」:

一個 Chart 搞定所有環境

  • values.yaml 控制不同環境的參數
  • 開發環境:helm install my-app ./my-chart -f dev-values.yaml
  • 正式環境:helm install my-app ./my-chart -f prod-values.yaml

版本管理與回滾

  • 每次部署都有版本號(REVISION 1, 2, 3…)
  • 出問題時:helm rollback my-app 2 立即回滾

豐富的生態圈

  • 不用自己寫 Chart,直接使用現成的(MySQL、Redis、Nginx 等)
  • 就像手機的 App Store,有數千個現成的應用

簡單說: Helm 讓你在 K8s 上部署應用就像安裝手機 App 一樣簡單!

Helm 是怎麼運作的?

1. Chart 就像一個「應用包」

my-web-app/
├── Chart.yaml          # 應用資訊(名稱、版本)
├── values.yaml         # 預設設定
├── templates/          # YAML 模板
│   ├── deployment.yaml
│   ├── service.yaml
│   └── ingress.yaml
└── charts/             # 其他依賴的應用

2. 模板 + 設定 = 最終的 YAML

模板檔案(templates/deployment.yaml):

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ .Values.app.name }}    # 這裡會被替換
spec:
  replicas: {{ .Values.replicas }} # 這裡會被替換
  template:
    spec:
      containers:
      - name: {{ .Values.app.name }}
        image: {{ .Values.image }}:{{ .Values.tag }}

設定檔案(values.yaml):

app:
  name: "my-web-app"
replicas: 3
image: "nginx"
tag: "1.21"

最終產生的 YAML:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-web-app
spec:
  replicas: 3
  template:
    spec:
      containers:
      - name: my-web-app
        image: nginx:1.21

3. 不同環境用不同設定檔

開發環境(dev-values.yaml):

replicas: 1
image: "nginx"
tag: "1.20"

正式環境(prod-values.yaml):

replicas: 3
image: "nginx"
tag: "1.21"

實際操作:5 分鐘部署 Elasticsearch

步驟 1:安裝 Helm

# macOS
brew install helm

# Linux
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash

# Windows
choco install kubernetes-helm

步驟 2:加入 Elastic 的應用商店

helm repo add elastic https://helm.elastic.co
helm repo update

步驟 3:一鍵安裝 Elasticsearch

helm install elasticsearch elastic/elasticsearch

就這樣!Elasticsearch 開始部署了。

步驟 4:查看部署狀態

# 查看所有已安裝的應用
helm list

# 查看 Elasticsearch 的詳細狀態
helm status elasticsearch

# 查看部署歷史
helm history elasticsearch

步驟 5:升級或回滾

# 升級到新版本
helm upgrade elasticsearch elastic/elasticsearch --set imageTag=8.5.0

# 如果出問題,回滾到上一個版本
helm rollback elasticsearch

Helm vs 純 YAML:實際比較

用純 YAML 部署 Nginx

deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-dev
spec:
  replicas: 1
  template:
    spec:
      containers:
      - name: nginx
        image: nginx:1.20

service.yaml:

apiVersion: v1
kind: Service
metadata:
  name: nginx-dev-service
spec:
  selector:
    app: nginx-dev
  ports:
  - port: 80

正式環境還要再寫一套類似的檔案…

用 Helm 部署 Nginx

一個命令搞定:

# 開發環境
helm install nginx bitnami/nginx --set replicaCount=1,imageTag=1.20

# 正式環境  
helm install nginx bitnami/nginx --set replicaCount=3,imageTag=1.21

差異對比:

項目純 YAMLHelm
檔案數量環境數 × 資源數1 個 Chart
參數管理手動修改每個檔案統一 values.yaml
版本控制手動記錄自動版本管理
回滾手動重建helm rollback
生態圈自己寫數千個現成 Chart

常用的 Helm 指令

# 基本操作
helm list                    # 查看已安裝的應用
helm status <app-name>       # 查看應用狀態
helm history <app-name>      # 查看部署歷史

# 安裝與升級
helm install <name> <chart>   # 安裝應用
helm upgrade <name> <chart>  # 升級應用
helm uninstall <name>        # 刪除應用

# 回滾
helm rollback <name> <revision>  # 回滾到指定版本
helm rollback <name>             # 回滾到上一個版本

# 查看與下載
helm search repo <keyword>   # 搜尋可用的 Chart
helm pull <chart>            # 下載 Chart 到本地
helm template <chart>        # 預覽會產生的 YAML

Helm Rollback 是怎麼實作的?

很多人好奇 helm rollback 是如何快速回滾的,其實背後的原理並不複雜:

Release 與 Revision 機制

每次執行 helm installhelm upgrade,Helm 都會建立一個 Release,並記錄版本號(Revision):

# 查看部署歷史
helm history my-app

# 輸出範例:
REVISION    STATUS      CHART           DESCRIPTION
1           superseded  my-app-1.0.0    Install complete
2           superseded  my-app-1.0.1    Upgrade complete
3           deployed    my-app-1.0.2    Upgrade complete

歷史資料儲存在哪裡?

Helm 會把每個 Revision 的完整資訊儲存在 Kubernetes 的 Secret 中:

# 查看 Helm 建立的 Secret
kubectl get secrets -l owner=helm

# 輸出範例:
NAME                          TYPE                 DATA
sh.helm.release.v1.my-app.v1  helm.sh/release.v1   1
sh.helm.release.v1.my-app.v2  helm.sh/release.v1   1
sh.helm.release.v1.my-app.v3  helm.sh/release.v1   1

每個 Secret 包含:

  • Chart 模板:當時使用的所有 YAML 模板
  • Values:當時使用的設定值
  • Manifest:最終產生的 Kubernetes 資源 YAML
  • Metadata:版本號、狀態、時間戳記等

Rollback 的運作流程

當你執行 helm rollback my-app 2 時,Helm 會:

┌─────────────────────────────────────────────────────────┐
│  1. 讀取目標版本                                          │
│     從 Secret sh.helm.release.v1.my-app.v2 取出資料      │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│  2. 解壓縮並解碼                                          │
│     Secret 內容是 base64 + gzip 壓縮的                   │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│  3. 取得舊版 Manifest                                     │
│     獲得當時產生的完整 Kubernetes YAML                    │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│  4. 執行三方合併(Three-way Merge)                       │
│     比對:舊版 Manifest vs 現有狀態 vs 目標版本           │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│  5. 套用變更                                              │
│     透過 kubectl apply 將資源更新到目標狀態               │
└─────────────────────────────────────────────────────────┘
                          ↓
┌─────────────────────────────────────────────────────────┐
│  6. 建立新的 Revision                                     │
│     Rollback 本身也會建立一個新版本(如 v4)              │
└─────────────────────────────────────────────────────────┘

實際範例:查看 Secret 內容

# 取得特定版本的 Release 資料
kubectl get secret sh.helm.release.v1.my-app.v2 -o jsonpath='{.data.release}' | base64 -d | gunzip

# 會輸出 JSON 格式的完整 Release 資訊,包含:
# - chart: Chart 的完整內容
# - config: 當時的 values
# - manifest: 產生的 YAML
# - version: 版本號

為什麼 Rollback 這麼快?

  1. 不需要重新下載 Chart:所有資料都存在 Secret 裡
  2. 不需要重新渲染模板:Manifest 已經預先產生好
  3. 只更新有差異的資源:透過三方合併,只處理真正需要改變的部分

注意事項

⚠️ Secret 有大小限制:Kubernetes Secret 預設最大 1MB,如果 Chart 很大可能會有問題

⚠️ 歷史版本會累積:預設保留 10 個版本,可透過 --history-max 調整:

helm upgrade my-app ./my-chart --history-max 5

⚠️ Rollback 不會還原資料:只會還原 Kubernetes 資源設定,資料庫等持久化資料不會回滾

與 Kubernetes 原生 Rollback 的差異

項目Helm Rollbackkubectl rollout undo
範圍整個 Release(多個資源)單一 Deployment
歷史儲存Kubernetes SecretReplicaSet
設定還原完整還原(含 values)只還原 Pod 模板
ConfigMap/Secret✅ 會還原❌ 不會還原

Helm 版本號與 Git 的關係

很多人會問:「Helm 的 Revision 和 Git commit 有什麼關係?」

答案是:兩者是完全獨立的系統,沒有直接關聯。

┌─────────────────────────────────────────────────────────────────┐
│                        兩套獨立的版本系統                         │
├─────────────────────────────────────────────────────────────────┤
│                                                                 │
│   Git(原始碼版本控制)          Helm(部署版本控制)              │
│   ├── commit abc123             ├── Revision 1                 │
│   ├── commit def456             ├── Revision 2                 │
│   ├── commit ghi789             ├── Revision 3                 │
│   └── 儲存在 Git Repository      └── 儲存在 K8s Secret          │
│                                                                 │
└─────────────────────────────────────────────────────────────────┘

它們追蹤的東西不同:

項目GitHelm Revision
追蹤對象原始碼變更部署狀態變更
儲存位置Git RepositoryKubernetes Secret
版本格式SHA hash(如 abc123遞增數字(1, 2, 3…)
回滾影響程式碼回到過去K8s 資源回到過去

為什麼會獨立?

  1. 部署不一定對應程式碼變更

    • 你可能只改了 replicas: 3replicas: 5(沒有程式碼變更)
    • 這時 Helm 會有新 Revision,但 Git 沒有新 commit
  2. 一次 commit 可能多次部署

    • 同一個版本的程式碼,可能部署到 dev、staging、prod
    • 每次部署都是新的 Helm Revision
  3. 部署可能失敗重試

    • 同一個 commit 可能因為設定調整而部署多次

實務上如何關聯?

雖然兩者獨立,但在 CI/CD 流程中,我們通常會透過 標籤(Label)或註解(Annotation) 來關聯:

# 在 values.yaml 或部署時加入 Git 資訊
metadata:
  annotations:
    git.commit: "abc123def"
    git.branch: "main"
    git.repo: "github.com/myorg/myapp"

部署時帶入 Git 資訊:

# 在 CI/CD 中自動帶入 Git commit
helm upgrade my-app ./chart \
  --set gitCommit=$(git rev-parse --short HEAD) \
  --set gitBranch=$(git branch --show-current)

這樣做的好處:

  • 出問題時可以快速對應到是哪個 commit 造成的
  • 方便追蹤「這個部署對應哪個版本的程式碼」
  • 但 Rollback 還是只能用 Helm Revision,不能用 Git commit

總結: Helm 透過把每個版本的完整資訊存在 Secret 中,實現了快速且完整的回滾機制。這也是為什麼 Helm 比手動管理 YAML 更可靠的原因之一。

哪裡可以找到現成的 Chart?

1. Artifact Hub(最推薦)

  • 網址:https://artifacthub.io/
  • 就像 Helm 的「App Store」
  • 有數千個現成的應用可以直接使用

2. Bitnami Charts(品質很高)

3. 官方 Charts

如何選擇好的 Chart?

  1. 看維護狀況:最近 6 個月有更新
  2. 看下載量:下載量高的通常比較穩定
  3. 看文件:有完整的使用說明
  4. 看社群:GitHub 上有活躍的討論

實務建議

1. 從簡單開始

  • 先試用現成的 Chart(如 Nginx、Redis)
  • 熟悉後再考慮自建 Chart

2. 環境分離

  • 開發、測試、正式環境用不同的 values.yaml
  • 不要直接修改 Chart 的原始檔案

3. 版本控制

  • 把 values.yaml 放到 Git 管理
  • 每次部署都記錄版本號

4. 備份重要資料

  • 資料庫等重要服務要定期備份
  • Helm 只管理應用部署,不負責資料備份

常見問題

Q: Helm 會影響現有的 Kubernetes 資源嗎? A: 不會。Helm 只是管理工具,不會影響已經存在的資源。

Q: 可以同時使用 Helm 和 kubectl 嗎? A: 可以。Helm 最終還是透過 kubectl 與 Kubernetes 互動。

Q: 如果 Chart 出問題怎麼辦? A: 用 helm rollback 回滾,或 helm uninstall 刪除後重新安裝。

Q: 自建 Chart 很複雜嗎? A: 一開始可能有點複雜,但熟悉後會比手寫 YAML 簡單很多。

總結

Helm 讓 Kubernetes 應用部署變得:

  • 更簡單:一個命令部署複雜應用
  • 更安全:版本管理與快速回滾
  • 更高效:重用現成的 Chart,不用重複造輪子

如果你還在手寫一堆 YAML 檔案,建議試試 Helm,會發現新世界!

參考資源


Tags

Mark Ku

Mark Ku

Software Developer

10年以上豐富網站開發經驗,開發過各種網站,電子商務、平台網站、直播系統、POS系統、SEO 優化、金流串接、AI 串接,Infra 出身,帶過幾次團隊,也加入過大團隊一起開發。

Expertise

前端(React)
後端(C#)
網路管理
DevOps
溝通
領導

Social Media

facebook github website

Related Posts

半年回顧:中大型系統 API Gateway (Kong) 架構評估及驗證
半年回顧:中大型系統 API Gateway (Kong) 架構評估及驗證
December 14, 2025
3 min

Quick Links

關於我

Social Media