iT邦幫忙

2026 iThome 鐵人賽

DAY 10
0
Kubernetes

Kubernetes學習心得分享系列 第 10

Day 10:【系統】 應用程式升級策略與無縫回滾 (Deployment Rolling Update & Rollback)

  • 分享至 

  • xImage
  •  

前言

寫這篇想要分享的重點:
在實際營運環境中,系統不可能不變,應用程式需要進行版本升級或修復 Bug。本篇將介紹 Kubernetes Deployment 的升級策略(RollingUpdate 與 Recreate),並實作如何透過 Revision 版本歷史與 kubectl rollout undo 實現復原。

這篇想要講什麼:

  1. Deployment 升級策略對比:RollingUpdate(滾動更新)與 Recreate(重新建立)的運作機制與底層 ReplicaSet 切換原理。
  2. 觸發升級與監控狀態:透過 kubectl applykubectl set image 更新版本,並使用 kubectl rollout status 查看滾動進度。
  3. 版本控制與快速回滾:查看 rollout history 並實作 kubectl rollout undo 進行一鍵復原。

為何要寫這篇:
部署應用程式只是第一步,維護系統的「生命週期」才是維運的考驗。傳統部署常因更新過程中斷服務,或是版次發布失敗時無法快速復原而造成災難。掌握 K8s 內建的升級與回滾機制,才能確保服務的高可靠度。

名詞對應

  • RollingUpdate: 滾動更新
  • Recreate: 重新建立
  • Rollout: 發布 / 升級
  • Rollback: 回滾 / 復原
  • Revision: 修訂

Deployment & ReplicaSet

在介紹如何rollout & Rollback之前, 需要先理解ReplicaSet和Deployment的概念

什麼是 ReplicaSet (RS)?

ReplicaSet 是 Kubernetes 中的低階副本控制器,主要職責非常簡單:確保在任何時間點,集群中都有指定數量(replicas)的 Pod 在正常運行

  • 主要功能:ReplicaSet 透過標籤選擇器(Label Selector)來監控並選取 Pod。如果 Pod 意外崩潰或被刪除,ReplicaSet 會自動補上新的 Pod;如果 Pod 數量過多,它會主動刪除多餘的 Pod。

  • 限制

    • 不支援滾動更新:若直接修改 ReplicaSet 的 Pod Template(例如更新 Image 版本),既有的 Pod 不會自動重啟更新,必須手動刪除舊 Pod 才能以更新版本建立Pod。
    • 缺乏版本紀錄:無法保留歷史發布狀態,因此無法實現一鍵回滾(Rollback)。
  • 注意:在實際作業中,極少直接建立或操作 ReplicaSet,通常使用 Deployment 。

什麼又是 Deployment?

Deployment 是 Kubernetes 中的高階宣告式部署管理器,它封裝了 ReplicaSet,為無狀態應用(Stateless Applications)提供完整的生命週期管理功能。

  • 主要功能

    • 當建立一個 Deployment 時,它會自動建立並管理一個 ReplicaSet,再由該 ReplicaSet 去管理實際的 Pod。
    • 當更新應用時,Deployment 不會直接改動舊的 ReplicaSet,而是建立一個新版本的 ReplicaSet,並透過逐步增加新 RS 副本數、減少舊 RS 副本數的方式達成升級。
  • 優勢

    • Rolling Update:可在不停機的情況下逐步替換舊版 Pod。
    • 版本控管與歷史紀錄:自動保留過往的 ReplicaSet 歷史版本。
    • Rollback:若新版本上線後發生 Bug,只需執行 kubectl rollout undo,Deployment 就能迅速將流量切回舊版 ReplicaSet。
    • 暫停與恢復(Pause & Resume):支援在多次修改配置期間暫停部署,待全部調整完成後再統一發布。

Deployment & ReplicaSet 關係圖

+-------------------------------------------------------------+
|                     Deployment (高階管理)                    |
|  - 職責:滾動更新 (Rolling Update)、版本回滾 (Rollback)         |
+------------------------------+------------------------------+
                               |
                               | (控制與版控)
                               v
+-------------------------------------------------------------+
|                    ReplicaSet (低階控制)                     |
|  - 職責:維持指定數量的 Pod 持續運行                         |
+---------------+--------------+--------------+---------------+
                |              |              |
                v              v              v
         +------------+  +------------+  +------------+
         |   Pod 1    |  |   Pod 2    |  |   Pod 3    |
         +------------+  +------------+  +------------+


兩者對照

比較 ReplicaSet Deployment
角色 低階Pod控制器 高階管理器
控制對象 直接管理 Pod 管理 ReplicaSet(間接管理 Pod)
Update 不支援Rolling Update 支援 Rolling Update 與 Recreate 策略
Rollback 無歷史紀錄,無法 Rollback 保留歷史 ReplicaSet,支援一鍵回滾 (Rollback)
實做 不直接使用 標準部署方式

Deployment 升級策略 (Deployment Strategies)

當我們修改了 Deployment Pod Template 中的 Container 映像檔(Image)或設定時,Deployment Controller 會觸發升級機制。K8s 主要提供兩種升級策略:

1. RollingUpdate(滾動更新,預設行為)

  • 運作機制:逐步建立新版本(New ReplicaSet)的 Pod,同時逐步銷毀舊版本(Old ReplicaSet)的 Pod。
  • 優點零停機時間(Zero Downtime),服務在升級過程中不會中斷。
  • 運作流程範例
    1. 建立新的 ReplicaSet(例如對應映像檔 nginx:1.7.1)。
    2. 新 ReplicaSet 啟動 1 個新 Pod,舊 ReplicaSet 減少 1 個舊 Pod(預設以 maxUnavailablemaxSurge 設定控制節奏)。
    3. 逐步交替,直到新 ReplicaSet 的 Pod 數量達到期望值,且舊 ReplicaSet 的 Pod 數量降至 0。
RollingUpdate 運作動態流程:

Step 1: [舊 RS: 5 Pods] (100% 舊版運作中)
Step 2: [舊 RS: 4 Pods] <---> [新 RS: 1 Pod ] (開始替換)
Step 3: [舊 RS: 2 Pods] <---> [新 RS: 3 Pods]
Step 4: [舊 RS: 0 Pods] <---> [新 RS: 5 Pods] (升級完成!)

2. Recreate(重新建立)

  • 運作機制:先一次性殺掉所有正在運行的舊版本 Pod,待全部停止後,再一次性建立所有新版本的 Pod。
  • 缺點會有停機時間(Application Down)
  • 適用場景:當新舊版本的應用程式無法同時存在(例如新舊版的資料庫 Schema 不相容,無法雙版本並存)時使用。
Recreate 運作動態流程:

Step 1: [舊 RS: 5 Pods]
Step 2: [舊 RS: 0 Pods]  <--- Application Down (服務停機)
Step 3: [新 RS: 5 Pods] (新版全部上線)

觸發版本升級與監控狀態

我們可以透過以下兩種方式更新 Deployment 的映像檔版本:

  1. 修改 YAML 設定檔並套用(推薦作法)
    修改 deployment-definition.yml 中的 image: nginx:1.7.1,並執行:

    kubectl apply -f deployment-definition.yml
    
    
  2. 透過 CLI 動態設定

kubectl set image deployment/myapp-deployment nginx-container=nginx:1.9.1

注意:直接用 set image 會導致本地 YAML 設定檔與 Cluster 實際狀態不一致,營運時建議以 YAML 檔版控為主。

監控升級進度

更新命令下達後,可使用 rollout status 指令觀察 Pod 的替換過程:

kubectl rollout status deployment/myapp-deployment

  • 輸出畫面會顯示目前新版 Pod 的建立進度:
Waiting for rollout to finish: 1 of 10 updated replicas are available...
Waiting for rollout to finish: 2 of 10 updated replicas are available...
...
deployment "myapp-deployment" successfully rolled out


版本控制與一鍵回滾 (Rollback)

當發布的新版本存在 Bug(例如 Container 啟動失敗或陷入 CrashLoopBackOff)時,我們可以迅速復原到前一個穩定版本。

基本運作原理

每次更新 Deployment 時,K8s 都會保留舊的 ReplicaSet(將其 Pod 數量調整為 0,但保留物件與歷史紀錄)。每一個歷史狀態稱為一個 Revision

回滾 (Rollback) 機制:

[ Deployment ]
     │
     ├── ReplicaSet-v1 (Revision 1) ──> [Pod] [Pod] [Pod] (數量由 0 調回 3)
     │
     └── ReplicaSet-v2 (Revision 2) ──> (數量由 3 清零 0)

常用管理與回滾指令

  • 查看發布歷史紀錄 (Revision)
kubectl rollout history deployment/myapp-deployment

  • 復原至前一個版本
kubectl rollout undo deployment/myapp-deployment

執行後,K8s 會將新 ReplicaSet 的 Pod 數量清零,並重新擴充舊 ReplicaSet 的 Pod 數量,快速完成版本復原。

  • 查看目前的 ReplicaSet 狀態
kubectl get replicasets

會看到舊的 ReplicaSet 被重新啟用,確保服務恢復正常。


常用指令速查總結 (Commands Summary)

操作類別 指令範例
建立 Deployment kubectl create -f deployment-definition.yml
查詢 Deployment kubectl get deployments
更新版本 kubectl apply -f deployment-definition.ymlkubectl set image deployment/myapp-deployment nginx=nginx:1.9.1
確認升級進度 kubectl rollout status deployment/myapp-deployment
確認歷史版本 kubectl rollout history deployment/myapp-deployment
一鍵復原/回滾 kubectl rollout undo deployment/myapp-deployment

總結

  • 本篇總結:
    Kubernetes 透過 Deployment 封裝了 ReplicaSet,實現聲明式的版本管理;透過預設的 RollingUpdate 策略可以達到無停機升級,並利用 Revision 歷史紀錄與 kubectl rollout undo** 在幾秒鐘內完成快速回滾,避免中止服務。

  • 下一篇預告:
    掌控了應用程式的部署與升級生命週期後,明天 Day 11 我們將進入應用程式配置管理領域, 探討 環境變數抽離:ConfigMaps 與 Secrets 應用,了解如何將設定檔與機密資訊從程式碼中解耦,並學習 etcd 的 Encryption at Rest 保密機制!敬請期待!

Takeaway

  • 預設 RollingUpdate 滾動更新:採用逐一替換 Pod 的方式進行版本升級,維持服務持續運作,實現無停機更新。
  • Recreate 策略適用場景:先一次性刪除所有舊 Pod 再建立新 Pod,雖然會造成暫時的服務中斷,但適合新舊版架構無法共存的特殊情境。
  • ReplicaSet 版本歷史(Revision):升級時,舊的 ReplicaSet 不會被刪除而是將數量調為 0,作為版本歷史保存下來供回滾使用。
  • 一鍵快速回滾:透過 kubectl rollout undo 能迅速將服務復原至前一個穩定的 ReplicaSet 狀態,降低失敗造成的營運風險。

上一篇
Day 09:【系統】 常駐服務與靜態 Pod 部署 (DaemonSet & Static Pods)
下一篇
Day 11:【配置】 環境變數抽離:ConfigMaps 與 Secrets 應用
系列文
Kubernetes學習心得分享12
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言