我有一個 Linebot 部署在樹梅派上的 k3s,原先是透過簡單的
kubectl apply -f方式來部署這服務的deployment,service,ingress等資源。 最近想將這個服務改為使用Helm Chart來管理,但過程中遇到了一些問題,本文將詳細介紹如何實現零停機遷移。
為什麼要從 YAML 遷移到 Helm?
在開始解決問題前,我們先來看看為什麼要進行這樣的遷移:
- 配置集中管理:將分散的 YAML 檔案整合到一個 Chart 中
- 版本控制:可以輕鬆回滾到之前的版本
- 變數模板化:透過 values.yaml 實現不同環境的配置覆蓋
- 複用性提高:可以在不同的環境或專案中重複使用
- 依賴管理:處理複雜的服務依賴關係
從 kubectl apply 到 Helm 的衝突問題
當我撰寫好 Helm Chart 並嘗試執行以下指令時:
helm install popofinder ./popofinder -n popo --dry-run
遇到了這樣的錯誤:
Error: INSTALLATION FAILED: Unable to continue with install:
Deployment "popofinder" in namespace "popo" exists and cannot be imported into the current release: invalid ownership metadata;
label validation error: missing key "app.kubernetes.io/managed-by": must be set to "Helm";
annotation validation error: missing key "meta.helm.sh/release-name": must be set to "popofinder";
annotation validation error: missing key "meta.helm.sh/release-namespace": must be set to "popo"
從錯誤訊息可以看出,對於 popofinder 這個 deployment 來說,在 popo namespace 中已經存在了,並且因為不是透過 Helm 部署的,因此缺少對應的 label 與 annotation 來讓 Helm 接管。
最直接的解決方案及其挑戰
最簡單直接的做法就是將已有的資源全部刪除,然後使用 Helm 重新部署:
kubectl delete deploy,ingress,service -l app=popofinder -n popo
helm install popofinder ./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 "接管"現有資源:
# 為 Deployment 添加標籤和註釋
kubectl label deploy popofinder -n popo app.kubernetes.io/managed-by=Helm
kubectl annotate deploy popofinder -n popo meta.helm.sh/release-name=popofinder meta.helm.sh/release-namespace=popo
# 為 Service 添加標籤和註釋
kubectl label svc popofinder -n popo app.kubernetes.io/managed-by=Helm
kubectl annotate svc popofinder -n popo meta.helm.sh/release-name=popofinder meta.helm.sh/release-namespace=popo
# 為 Ingress 添加標籤和註釋
kubectl label ingress popofinder -n popo app.kubernetes.io/managed-by=Helm
kubectl annotate ingress popofinder -n popo meta.helm.sh/release-name=popofinder meta.helm.sh/release-namespace=popo
# 如果有其他資源,也需要類似處理
3. 驗證遷移結果
在為所有資源添加標籤和註釋後,再次執行 Helm 安裝命令:
helm install popofinder ./popofinder -n popo
成功了!現在我可以使用 Helm 來管理和更新這個服務了。
以下依文章上下文整理成功結果的示意輸出,並非原始截圖的逐字轉錄:
$ helm install popofinder ./popofinder -n popo
NAME: popofinder
NAMESPACE: popo
STATUS: deployed
Helm 帶來的好處
既然我們已經成功將資源遷移到了 Helm,我們來簡單總結一下 Helm 能為我們帶來的好處:
-
簡化部署流程:
- 使用單一命令
helm install/upgrade即可完成部署 - 不需要手動管理多個 YAML 檔案
- 使用單一命令
-
提高可維護性:
- 透過
values.yaml集中管理配置 - 更容易進行變更和追踪
- 透過
-
版本控制和回滾:
- 每次部署都是一個版本,可以使用
helm history查看 - 出現問題可以立即用
helm rollback回滾
- 每次部署都是一個版本,可以使用
-
模板化和重用:
- 使用 Go 模板語言讓配置更靈活
- 通過 Chart 依賴關係管理複雜應用
PoPoFinder Linebot 推薦
最後順便在這篇文章推廣一下這個用來方便查詢醫生是否是波波的 Linebot,歡迎掃描 QRcode 加入好友:
無法掃描 QR code?點擊這裡加入 PoPoFinder LINE Bot
功能亮點:
- 支援模糊搜尋功能
- 可以根據地區與科別進行搜尋
GitHub Repo: popofinder
