rollout undo 快速回退(Rollback)至上一版本。在傳統部署架構中,更新應用往往需要把伺服器停機、換上新版程式碼、再重新開機,這會導致幾分鐘甚至幾小時的服務中斷(Downtime),也就是大家常見的「伺服器維護中」。
Kubernetes Deployment 預設採用的更新策略是 Rolling Update(滾動更新):
Deployment 本身是透過管理 ReplicaSet 的副本數來完成滾動更新的:
沿用 Day 08 建立的 nginx-deployment(目前執行的是 Nginx 1.25):
kubectl get deployment nginx-deployment
更新 Deployment 有兩種方式(修改 YAML 後 kubectl apply,或直接使用 kubectl set image 指令)。這裡我們使用指令式操作進行升級:
kubectl set image deployment/nginx-deployment nginx=nginx:1.26
執行以下指令,觀察滾動更新的即時狀態:
kubectl rollout status deployment/nginx-deployment
你也可以同時在另一個終端機觀察 Pod 的替換歷程:
kubectl get pods -l app=nginx-app -w
你會清楚看到新的 Pod 陸續進入 Running,而舊的 Pod 依序變成 Terminating。
Kubernetes 會記錄每一次 Deployment 的變更歷史:
kubectl rollout history deployment/nginx-deployment
輸出預期:
deployment.apps/nginx-deployment
REVISION CHANGE-CAUSE
1 <none>
2 <none>
此時系統中已經存在 Revision 1(舊版 1.25)與 Revision 2(新版 1.26)。
假設我們不小心把映像檔版本打錯成一個不存在的 Tag(例如 nginx:999.0):
kubectl set image deployment/nginx-deployment nginx=nginx:999.0
觀察 Pod 狀態:
kubectl get pods -l app=nginx-app
你會發現新的 Pod 出現了 ErrImagePull 或 ImagePullBackOff 錯誤。但神奇的是,舊的 Pod 仍然健在並持續服務,K8s 不會因為新版本失敗就把整個系統搞垮!
發現新版本有問題時,只需要一行指令就能瞬間恢復到上一個正常的版本:
kubectl rollout undo deployment/nginx-deployment
執行後再次檢查:
kubectl rollout status deployment/nginx-deployment
kubectl get pods -l app=nginx-app
失敗的 Pod 會被清理乾淨,系統瞬間退回穩定的 Nginx 1.26 版本!
今天我們體驗了 Kubernetes 核心強項之一:零停機的滾動更新與容錯率極高的版本回退機制。
現在我們的後端 Pod 已經能穩定運行、自我修復、還能無縫升級了。但目前這些 Pod 都只能在內部溝通,外部使用者到底該如何存取它們?
明天 Day 10,我們將進入網路篇的核心:「Pod 之間的溝通橋樑:Service(ClusterIP)概念與內部網路」!