如果pod是通過Deployment創建的,則用戶可以在運行時修改Deployment的pod定義(sepc.template)或鏡像名稱,並應用到Deployment對象上,系統即可完成Deployment的自動更新操作。如果在更新過程中發生了錯誤,則還可以通過回滾操作恢復Pod的版本。
Deployment的升級
以Deployment nginx爲例:
kubectl create -f nginx-deployment.yaml --record=true
apiVersion: apps/v1beta1
kind: Deployment
metadata:
name: nginx-deployment
spec:
replicas: 3
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.7.9
ports:- containerPort: 80
現在pod鏡像需要被更新爲 nginx:1.9.1,我們可以通過kubectl set image 命令爲Deployment設置新的鏡像名稱:
kubectl set image deployment/nginx-deployment nginx=nginx:1.9.1
另外一種方法是使用kubectl edit命令直接修改Deployment的配置,將image從nginx:1.7.9更改爲nginx:1.9.1。
kubectl edit deployment/nginx-deployment
一旦鏡像名發生了修改,則將觸發系統完成Deployment所有運行pod的滾動升級操作,可以使用kubectl rollout status 命令查看Deployment的更新過程:
kubectl rollout status deployment/nginx-deployment
運行kubectl get rs 命令,可以看到兩個ReplicaSet的最終狀態:
更新策略:
在deployment的定義中,可以通過spec.strategy指定pod更新的策略,目前支持兩種策略:Recreate(重建)和RollingUpdate(滾動更新)策略,默認值爲RollingUpdate。
Recreate:設置spec.strategy.type=Recreate,表示Deployment在更新pod時,會先殺掉所有正在運行的pod,然後創建新的pod。
RollingUpdate:設置spec.strategy.type=RollingUpdate,表示Deployment會以滾動更新的方式來逐個更新pod。同時,可以通過設置spec.strategy.rollingUpdate下的兩個參數(maxUnavailable和maxSurge)來控制滾動更新的過程。
Deployment是如何完成Pod更新的呢?通過kubectl describe deployment nginx-deployment 可以看到詳細的事件信息:
spec.strategy.rollingUpdate.maxUnavailable:用於指定Deployment在更新過程中不可用狀態的pod數量的上限。該參數的數值可以是絕對值(例如5)或pod期望的副本數的百分比(例如10%),如果被設置爲百分比,那麼系統會先以向下取整的方式計算出絕對值。而當另一個參數maxSurge被設置爲0時,maxUnavailable則必須被設置爲絕對值大於0。默認值爲25%。
spec.strategy.rollingUpdate.maxSurge:用於指定Deployment在更新過程中pod總數超過pod期望副本數部分的最大值,該maxSurge的數值可以是絕對值(例如5)或pod期望副本數的百分比(例如10%),如果設置爲百分比,那麼系統會先按照向上取整的方式計算出絕對值。默認值爲25%
多重更新(Rollover)的情況
如果deployment的上一次更新正在進行,此時用戶再次發起deployment的更新操作,那麼deployment會爲每一次更新都創建一個ReplicaSet,而每次在新的ReplicaSet創建成功後,會逐個增加pod副本數,同時將之前正在擴容的ReplicaSet停止擴容更新,並將其加入舊版本ResplicaSet列表中,然後開始縮容至0的操作。
假設我們創建了一個deployment,這個deployment開始創建了5個nginx:1.7.9的pod副本,在這個創建pod動作尚未完成時,我們又將deployment進行更新,在副本數量不變的情況下將pod模板中的鏡像修改爲nginx:1.9.1,又假設此時deployment已經創建了3個nginx:1.7.9的pod副本,則deployment會立即殺掉已創建的3個nginx:1.7.9 pod,並開始創建nginx:1.9.1 pod。deployment不會在等待nginx:1.7.9的pod創建到5個之後再進行更新操作。
Deployment的回滾
kubectl create -f nginx-deployment.yaml --record=true
在創建deployment時使用--record=true參數,就可以在歷史命令中看到每個版本所執行的命令了
假如我們在更新deployment鏡像時,將容器鏡像名稱設置錯誤爲nginx:1.7(一個不存在的鏡像),則部署過程會卡在拉取鏡像過程中。
這時,我們需要回滾到之前穩定版本的deployment。
首先,使用kubectl rollout history命令查看deployment部署的歷史記錄:
kubectl rollout history deployment nginx-deployment
如果需要查看某一條命令的詳細信息,則可以加上--reversion=<N>參數
kubectl rollout history deployment nginx-deployment --reversion=3
我們可以看到image的版本是nginx1.7,並不存在此鏡像!!!
現在我們決定撤銷本次發佈並回滾到上一個部署版本:
kubectl rollout undo deployment nginx-deployment
也可以使用--to-revision參數指定回滾到的部署版本號:
kubectl rollout undo deployment nginx-deployment --to-revision=2
這樣就可以回滾到之前的穩定版本了。