kubernetes 應用的滾動升級
當叢集中的某個服務需要升級時,我們需要停止目前與該服務相關的所有 Pod,然後重新拉取映象並啟動。如果叢集規模比較大,則這個工作就變成了一個挑戰,而且先全部停止然後逐步升級的方式會導致較長時間的服務不可用。kubernetes 提供了 rolling-update(滾動升級)功能來解決上述問題。
滾動升級通過執行 kubectl rolling-update 命令一鍵完成,該命令建立了一個新的RC,然後自動控制舊的 RC 中的 Pod 副本數量逐漸減少到 0,同時新的 RC 中的 Pod 副本數量從 0 逐步增加到目標值,最終 實現了 Pod 的升級。需要注意的是,系統要求新的 RC 需要與 舊的 RC 在相同的名稱空間(Namespace)內,即不能把別人的資產偷偷轉移到自家的名下。
以 redis-master 為例,假如當前執行的 redis-master Pod 是 1.0 版本,則現在需要升級到 2.0 版本。
建立 redis-master-controller-v2.yaml 的配置檔案如下:
apiVersion: V1
kind: ReplicationController
metadata:
name: redis-master-v2
labels:
name: redis-master
version: v2
spec:
replicas: 1
selector:
name: redis-master
version:v2
template:
metadata:
lables:
name: redis-master
version: v2
spec:
containers:
- name: master
images: kubeguids/redis-master:2.0
ports:
- containerPort: 6379
在配置檔案中有幾處注意:
(1)RC 的名字(name)不能與舊的 RC 的名字相同。
(2)在 selector 中應至少有一個 Label 與舊的 RC 的 Label 不同,以標識其為新的 RC。本例中新增了一個名為 version 的 Label,以與舊的 RC 進行區分。
執行 kubectl rolling-update 命令完成 Pod 的滾動升級:
kubectl rolling-update redis-master -f redis-master-controller-v2.yaml
kubectl 的執行過程如下:
Creating redis-master-v2
.......................................................................................
Update successded. Deleting redis-master
redis-master-v2
等所有新的 Pod 啟動完成後,舊的 Pod 也被全部銷燬,這樣就完成了容器叢集的更新。
另一種方法是不使用配置檔案,直接用 kubectl rolling-update 命令,加上 --image 引數指定新版映象名稱來完成 Pod 的滾動升級。
kubectl rolling-update redis-master --image=redis-master:2.0
與使用配置檔案的方式不同,執行的結果是舊的 RC 被刪除,新的 RC 仍將使用舊的 RC 的名字。
執行結果略.........................
更新完成後,檢視 RC:
$ kubectl get rc
CONTROLLER CONTAINER(S) IMAGES(S) SELECTOR REPLICAS
redis0master master kubeguide/redis-master:2.0 deployment=XXXXX,name=redis-master,version=v1 3
可以看到,kubectl 給 RC 增加了 一個 key 為 “deployment” 的 Label(這個 key 的名字 可通過 --deployment-label-key引數進行修改),Label 的值是 RC 的內容進行 hash 計算後的值,相當於簽名,這樣就能很方便地比較 RC 裡的 Image 名字 及其他資訊是否發生了變化。
如果在更新過程中發現配置有錯誤,則使用者可以中斷更新操作,並通過執行 kubectl-rolling-update-rollback 完成 Pod 版本的回滾。
$ kubectl rolling-update redis-master --image=kubeguide/redis-master:2.0 --rollback