前言
在容器化技術的演進過程中,我們經歷了從 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
差異對比:
| 項目 | 純 YAML | Helm |
|---|---|---|
| 檔案數量 | 環境數 × 資源數 | 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 install 或 helm 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 這麼快?
- 不需要重新下載 Chart:所有資料都存在 Secret 裡
- 不需要重新渲染模板:Manifest 已經預先產生好
- 只更新有差異的資源:透過三方合併,只處理真正需要改變的部分
注意事項
⚠️ Secret 有大小限制:Kubernetes Secret 預設最大 1MB,如果 Chart 很大可能會有問題
⚠️ 歷史版本會累積:預設保留 10 個版本,可透過 --history-max 調整:
helm upgrade my-app ./my-chart --history-max 5
⚠️ Rollback 不會還原資料:只會還原 Kubernetes 資源設定,資料庫等持久化資料不會回滾
與 Kubernetes 原生 Rollback 的差異
| 項目 | Helm Rollback | kubectl rollout undo |
|---|---|---|
| 範圍 | 整個 Release(多個資源) | 單一 Deployment |
| 歷史儲存 | Kubernetes Secret | ReplicaSet |
| 設定還原 | 完整還原(含 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 │
│ │
└─────────────────────────────────────────────────────────────────┘
它們追蹤的東西不同:
| 項目 | Git | Helm Revision |
|---|---|---|
| 追蹤對象 | 原始碼變更 | 部署狀態變更 |
| 儲存位置 | Git Repository | Kubernetes Secret |
| 版本格式 | SHA hash(如 abc123) |
遞增數字(1, 2, 3...) |
| 回滾影響 | 程式碼回到過去 | K8s 資源回到過去 |
為什麼會獨立?
-
部署不一定對應程式碼變更
- 你可能只改了
replicas: 3→replicas: 5(沒有程式碼變更) - 這時 Helm 會有新 Revision,但 Git 沒有新 commit
- 你可能只改了
-
一次 commit 可能多次部署
- 同一個版本的程式碼,可能部署到 dev、staging、prod
- 每次部署都是新的 Helm Revision
-
部署可能失敗重試
- 同一個 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(品質很高)
- 網址:https://charts.bitnami.com/bitnami
- VMware 維護,品質穩定
- 包含 MySQL、Redis、Kafka 等常用服務
3. 官方 Charts
- Elastic:https://helm.elastic.co
- Grafana:https://grafana.github.io/helm-charts
- Prometheus:https://prometheus-community.github.io/helm-charts
如何選擇好的 Chart?
- 看維護狀況:最近 6 個月有更新
- 看下載量:下載量高的通常比較穩定
- 看文件:有完整的使用說明
- 看社群: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,會發現新世界!
參考資源
- Artifact Hub - Helm Chart 搜尋平台
- Bitnami Charts - 高品質 Chart 集合
- Elastic Helm Charts - Elastic 官方 Charts





















留言