Kubernetes YAML 遷移到 Helm 的零停機遷移紀錄
我有一個 Linebot 部署在樹梅派上的 k3s,原先是透過簡單的
kubectl apply -f方式來部署這服務的deployment,service,ingress等資源。
最近想將這個服務改為使用Helm Chart來管理,但過程中遇到了一些問題,本文將詳細介紹如何實現零停機遷移。
為什麼要從 YAML 遷移到 Helm?
在開始解決問題前,我們先來看看為什麼要進行這樣的遷移:
- 配置集中管理:將分散的 YAML 檔案整合到一個 Chart 中
- 版本控制:可以輕鬆回滾到之前的版本
- 變數模板化:透過 values.yaml 實現不同環境的配置覆蓋
- 複用性提高:可以在不同的環境或專案中重複使用
- 依賴管理:處理複雜的服務依賴關係
從 kubectl apply 到 Helm 的衝突問題
當我撰寫好 Helm Chart 並嘗試執行以下指令時:
1 | helm install popofinder ./popofinder -n popo --dry-run |
遇到了這樣的錯誤:
1 | Error: INSTALLATION FAILED: Unable to continue with install: |
從錯誤訊息可以看出,對於 popofinder 這個 deployment 來說,在 popo namespace 中已經存在了,並且因為不是透過 Helm 部署的,因此缺少對應的 label 與 annotation 來讓 Helm 接管。
最直接的解決方案及其挑戰
最簡單直接的做法就是將已有的資源全部刪除,然後使用 Helm 重新部署:
1 | kubectl delete deploy,ingress,service -l app=popofinder -n popo |
但我的服務正在線上運行中,這種方法會帶來兩個明顯的問題:
- 不可避免的停機時間: 服務會短暫不可用,影響用戶體驗
- 部署風險增加: 如果
Helm Chart定義有問題,可能需要緊急回滾,造成更長的停機時間
需要尋找更好的解決方案
理想的遷移方案應該能做到:
- 零停機時間: 用戶無感知
- 可回滾性: 出現問題能快速恢復
- 資源保留: 不需要重建所有資源
零停機遷移方案詳解
1. 分析錯誤訊息
從錯誤中我們可以看出,主要是缺少三項關鍵資訊:
- 標籤
app.kubernetes.io/managed-by: Helm- 表明此資源是由 Helm 管理 - 註釋
meta.helm.sh/release-name: popofinder- 指定此資源屬於哪個 Helm 發行版本 - 註釋
meta.helm.sh/release-namespace: popo- 指定此資源所屬的命名空間
2. 逐一添加標籤和註釋
我使用 kubectl label 與 kubectl annotate 命令來新增這些缺少的資訊,讓 Helm “接管”現有資源:
1 | # 為 Deployment 添加標籤和註釋 |
3. 驗證遷移結果
在為所有資源添加標籤和註釋後,再次執行 Helm 安裝命令:
1 | helm install popofinder ./popofinder -n popo |
成功了!現在我可以使用 Helm 來管理和更新這個服務了。

注意事項
本文提供的解決方案僅適用於 Helm 3。Helm 2 使用了不同的資源標記系統,這個方法在 Helm 2 中不適用。
如果你使用的是 Helm 2,請考慮先升級到 Helm 3 或尋找特定於 Helm 2 的解決方案。
Helm 帶來的好處
既然我們已經成功將資源遷移到了 Helm,我們來簡單總結一下 Helm 能為我們帶來的好處:
簡化部署流程:
- 使用單一命令
helm install/upgrade即可完成部署 - 不需要手動管理多個 YAML 檔案
- 使用單一命令
提高可維護性:
- 透過
values.yaml集中管理配置 - 更容易進行變更和追踪
- 透過
版本控制和回滾:
- 每次部署都是一個版本,可以使用
helm history查看 - 出現問題可以立即用
helm rollback回滾
- 每次部署都是一個版本,可以使用
模板化和重用:
- 使用 Go 模板語言讓配置更靈活
- 通過 Chart 依賴關係管理複雜應用
PoPoFinder Linebot 推薦
最後順便在這篇文章推廣一下這個用來方便查詢醫生是否是波波的 Linebot,歡迎掃描 QRcode 加入好友:

功能亮點:
- 支援模糊搜尋功能
- 可以根據地區與科別進行搜尋
GitHub Repo: popofinder