iT邦幫忙

2026 iThome 鐵人賽

DAY 22
0

昨天整理了 K8s 常見的錯誤狀況和排查方式,今天要學 K8s 的套件管理工具——Helm。


為什麼需要 Helm

到目前為止,Todo App 已經累積了不少 YAML 檔案:

todo-api-deployment.yaml
todo-api-service.yaml
todo-api-configmap.yaml
todo-api-hpa.yaml
todo-frontend-deployment.yaml
todo-frontend-service.yaml
mysql-statefulset.yaml
mysql-service.yaml
mysql-headless-service.yaml
todo-ingress.yaml
...

這些 YAML 有幾個問題:

問題一:部署順序要自己管理

mysql 要先跑起來,todo-api 才能連到資料庫。但 kubectl apply -f 一次套用所有 YAML,不保證順序。

問題二:多環境設定要複製貼上

dev 和 staging 環境的 YAML 結構一樣,只有 image tag、replica 數量、資料庫密碼不同。現在的做法是維護兩份幾乎一樣的 YAML,改一個地方要改兩次。

問題三:沒有版本管理

kubectl apply 之後,不知道現在跑的是哪個版本,rollback 要手動處理。

Helm 用「Chart」把所有相關的 YAML 包成一個可版本化、可設定的套件,一個指令部署整個應用程式。


Helm 的核心概念

Chart:一組 YAML 模板的集合,描述一個完整的應用程式。可以自己寫,也可以用別人發布的 Chart。

Release:Chart 安裝到 K8s 之後的執行實例。同一個 Chart 可以安裝多次,每次都是一個獨立的 Release(例如 dev-todo-app 和 staging-todo-app)。

Values:Chart 的可設定參數,每個 Release 可以有不同的 Values,讓同一個 Chart 部署到不同環境。

Repository:存放 Chart 的倉庫,類似 Docker Hub 之於 Docker Image。

Helm Chart(模板)+ Values(設定)= Release(部署實例)

實際操作

今天目標:用 podinfo 這個 Chart,實際體驗 Chart / Values / Release 三個核心概念,並操作 upgrade 和 rollback。

為什麼選 podinfo?
它是專門用來示範 K8s 的小型 Web 應用,只有一個 Deployment 和一個 Service,幾秒> 就能啟動。最重要的是,它的 Values 可以直接改變網頁上顯示的訊息和背景顏色,每次修改 Values 都能在瀏覽器上看到結果,很適合用來理解 Helm 在做什麼。

Step1: 安裝 Helm

macOS:

brew install helm

Linux:

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

Windows:

winget install Helm.Helm

確認安裝成功:

helm version

Step2: 新增 Chart Repository

helm repo add podinfo https://stefanprodan.github.io/podinfo
helm repo update

可以先搜尋看看這個 repo 裡有哪些 Chart:

helm search repo podinfo

Step3: 準備 dev 環境的 Values 檔,安裝第一個 Release

  1. 在 helm 資料夾中建立 dev-values.yaml:
replicaCount: 1

ui:
  message: "Hello from DEV"
  color: "#2e7d32"
  1. 用這份 Values 安裝 Chart:
helm install dev-podinfo podinfo/podinfo \
  -n podinfo-dev \
  --create-namespace \
  -f dev-values.yaml

前面幾天的 Todo App 已經部署在 dev namespace,這裡用 podinfo-dev 和 podinfo-staging 隔開,避免練習時影響到 Todo App,最後清除時也能放心將整個 namespace 刪掉。

  1. 確認安裝狀態:
helm list -n podinfo-dev

https://ithelp.ithome.com.tw/upload/images/20260923/20183863gSlaHaP3Bf.png

dev-podinfo 是 Release 名稱,podinfo 是 Chart 名稱,REVISION: 1 是版本號,上面提到的三個核心概念都能對應到。

  1. 確認 Pod 已經跑起來,STATUS 為 Running、READY 為 1/1:
kubectl get pods -n podinfo-dev

https://ithelp.ithome.com.tw/upload/images/20260923/20183863xWD6eQh8YM.png

Step4: 打開網頁看看

kubectl port-forward svc/dev-podinfo 9898:9898 -n podinfo-dev

看到 Forwarding from 127.0.0.1:9898 -> 9898 後保持這個終端機開著,瀏覽器打開 http://localhost:9898,會看到綠色背景和「Hello from DEV」。這兩個就是我們在 dev-values.yaml 裡設定的值。

https://ithelp.ithome.com.tw/upload/images/20260923/20183863kCNkCmKRup.png

Step5: 同一個 Chart,用不同 Values 部署 staging 環境

在 helm 資料夾中建立 staging-values.yaml:

replicaCount: 2

ui:
  message: "Hello from STAGING"
  color: "#c62828"

用同一個 Chart、不同的 Values,再安裝一個 Release:

helm install staging-podinfo podinfo/podinfo \
  -n podinfo-staging \
  --create-namespace \
  -f staging-values.yaml
helm list -A

https://ithelp.ithome.com.tw/upload/images/20260923/20183863PSVaM7EYuP.png

開另一個終端機,用不同的本機 port 轉發 staging:

kubectl port-forward svc/staging-podinfo 9899:9898 -n podinfo-staging

打開 http://localhost:9899,會看到紅色背景和「Hello from STAGING」。把兩個分頁並排,就是 Helm 解決多環境問題的方式:Chart 只有一份,環境之間的差異全部寫在 Values 檔裡。

https://ithelp.ithome.com.tw/upload/images/20260923/20183863AAoCTxcj7G.png

再確認一下 Pod 數量,staging 設定了 replicaCount: 2:

kubectl get pods -n podinfo-dev
kubectl get pods -n podinfo-staging

https://ithelp.ithome.com.tw/upload/images/20260923/20183863JhHJ7p82QM.png
dev 有 1 個 Pod,staging 有 2 個。

Step6: 看 Release 用了哪些 Values、建立了哪些資源

查看這個 Release 使用的 Values:

helm get values dev-podinfo -n podinfo-dev

輸出就是我們在 dev-values.yaml 寫的內容。沒有寫到的參數,Helm 會使用 Chart 內建的預設值。

查看 Release 實際建立的 K8s 資源:

kubectl get all -n podinfo-dev

會看到 Deployment、ReplicaSet、Pod、Service。這些原本要我們自己寫 YAML 的資源,Helm 用 Chart 模板加上 Values 幫我們產生好了。如果想看 Helm 最後產生的完整 YAML:

helm get manifest dev-podinfo -n podinfo-dev

Step7: 升級 Release

假設 dev 環境要改版,修改 dev-values.yaml:

replicaCount: 3

ui:
  message: "Hello from DEV v2"
  color: "#2e7d32"

套用新的 Values:

helm upgrade dev-podinfo podinfo/podinfo \
  -n podinfo-dev \
  -f dev-values.yaml

⚠️ upgrade 會讓 Pod 重建,原本的 port-forward 會斷線。回到 Step4 的終端機按 Ctrl + C,重新執行一次 port-forward。

重新整理 http://localhost:9898,訊息變成「Hello from DEV v2」。再看 Pod 數量:

kubectl get pods -n podinfo-dev

變成 3 個了。

https://ithelp.ithome.com.tw/upload/images/20260923/20183863JAsYWI6Vju.png

⚠️ 注意:helm upgrade 是以 Chart 預設值 為基礎,再套上這次指定的 Values。如果這次沒有帶 -f dev-values.yaml,只用 --set replicaCount=3 升級,ui.message 和 ui.color 會被重設回預設值。這也是為什麼實務上會把設定寫在 Values 檔裡,每次升級都帶同一份檔案。

看 Release 的歷史版本:

helm history dev-podinfo -n podinfo-dev

https://ithelp.ithome.com.tw/upload/images/20260923/20183863eqPokT1agL.png

Step8: 回滾 Release

假設新版有問題,回滾到 REVISION 1:

helm rollback dev-podinfo 1 -n podinfo-dev

一樣重新執行 port-forward 後重新整理頁面,訊息變回「Hello from DEV」,Pod 也回到 1 個。

kubectl get pods -n podinfo-dev
helm history dev-podinfo -n podinfo-dev

https://ithelp.ithome.com.tw/upload/images/20260923/20183863WSmzWLJC88.png

注意 rollback 並不是刪掉 REVISION 2,而是用 REVISION 1 的設定建立一個新的 REVISION 3。所有變更都留有紀錄,隨時知道現在跑的是哪個版本、從哪裡來,這就解決了一開始提到的「問題三:沒有版本管理」。

Step9: 移除 Release

  1. 練習結束,先按 Ctrl + C 停掉兩個 port-forward,再把兩個 Release 移除:
helm uninstall dev-podinfo -n podinfo-dev
helm uninstall staging-podinfo -n podinfo-staging
kubectl delete namespace podinfo-dev podinfo-staging

helm uninstall 會把 Release 建立的所有資源一次清掉,不用一個一個 kubectl delete。

  1. 剛剛建立的 dev-values.yaml和 staging-values.yaml刪除 :
# mac/linux
rm dev-values.yaml staging-values.yaml

# window
Remove-Item dev-values.yaml, staging-values.yaml

小結

今天學了 Helm 的基本概念和操作:

  • Chart:YAML 模板的集合,描述一個完整應用程式
  • Release:Chart 的部署實例,同一個 Chart 可以部署多個 Release
  • Values:讓同一個 Chart 部署到不同環境有不同設定,實務上會寫成 Values 檔
  • helm install / upgrade / rollback / uninstall:完整的生命週期管理

用 podinfo 實際看到了同一個 Chart 配上不同 Values 產生不同的 Release,也體驗了 upgrade 和 rollback 如何留下完整的版本紀錄。明天會動手把 Todo App 包成 Helm Chart,從使用者變成 Chart 的作者,到時候就會知道 Values 檔裡的設定是怎麼被套進模板裡的。


上一篇
Day 21|K8s 除錯
下一篇
Day 23|Helm (2)
系列文
從零學 K8s|30 天核心概念 × 實作,新手也能真正掌握 Kubernetes 共 25 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言