寫這篇想要分享的重點:
在實際營運環境中,系統不可能不變,應用程式需要進行版本升級或修復 Bug。本篇將介紹 Kubernetes Deployment 的升級策略(RollingUpdate 與 Recreate),並實作如何透過 Revision 版本歷史與kubectl rollout undo實現復原。這篇想要講什麼:
- Deployment 升級策略對比:
RollingUpdate(滾動更新)與Recreate(重新建立)的運作機制與底層 ReplicaSet 切換原理。- 觸發升級與監控狀態:透過
kubectl apply與kubectl set image更新版本,並使用kubectl rollout status查看滾動進度。- 版本控制與快速回滾:查看
rollout history並實作kubectl rollout undo進行一鍵復原。為何要寫這篇:
部署應用程式只是第一步,維護系統的「生命週期」才是維運的考驗。傳統部署常因更新過程中斷服務,或是版次發布失敗時無法快速復原而造成災難。掌握 K8s 內建的升級與回滾機制,才能確保服務的高可靠度。
在介紹如何rollout & Rollback之前, 需要先理解ReplicaSet和Deployment的概念
ReplicaSet 是 Kubernetes 中的低階副本控制器,主要職責非常簡單:確保在任何時間點,集群中都有指定數量(replicas)的 Pod 在正常運行。
主要功能:ReplicaSet 透過標籤選擇器(Label Selector)來監控並選取 Pod。如果 Pod 意外崩潰或被刪除,ReplicaSet 會自動補上新的 Pod;如果 Pod 數量過多,它會主動刪除多餘的 Pod。
限制:
注意:在實際作業中,極少直接建立或操作 ReplicaSet,通常使用 Deployment 。
Deployment 是 Kubernetes 中的高階宣告式部署管理器,它封裝了 ReplicaSet,為無狀態應用(Stateless Applications)提供完整的生命週期管理功能。
主要功能:
優勢:
kubectl rollout undo,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 Pod Template 中的 Container 映像檔(Image)或設定時,Deployment Controller 會觸發升級機制。K8s 主要提供兩種升級策略:
nginx:1.7.1)。maxUnavailable 與 maxSurge 設定控制節奏)。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] (升級完成!)
Recreate 運作動態流程:
Step 1: [舊 RS: 5 Pods]
Step 2: [舊 RS: 0 Pods] <--- Application Down (服務停機)
Step 3: [新 RS: 5 Pods] (新版全部上線)
我們可以透過以下兩種方式更新 Deployment 的映像檔版本:
修改 YAML 設定檔並套用(推薦作法):
修改 deployment-definition.yml 中的 image: nginx:1.7.1,並執行:
kubectl apply -f deployment-definition.yml
透過 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
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
當發布的新版本存在 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)
kubectl rollout history deployment/myapp-deployment
kubectl rollout undo deployment/myapp-deployment
執行後,K8s 會將新 ReplicaSet 的 Pod 數量清零,並重新擴充舊 ReplicaSet 的 Pod 數量,快速完成版本復原。
kubectl get replicasets
會看到舊的 ReplicaSet 被重新啟用,確保服務恢復正常。
| 操作類別 | 指令範例 |
|---|---|
| 建立 Deployment | kubectl create -f deployment-definition.yml |
| 查詢 Deployment | kubectl get deployments |
| 更新版本 | kubectl apply -f deployment-definition.yml 或 kubectl 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 保密機制!敬請期待!
kubectl rollout undo 能迅速將服務復原至前一個穩定的 ReplicaSet 狀態,降低失敗造成的營運風險。