1. 程式人生 > >022.掌握Pod-Pod升級和回滾

022.掌握Pod-Pod升級和回滾

一 deploymentPod升級和回滾

1.1 deployment升級

若Pod是通過Deployment建立的,可以在執行時修改Deployment的Pod定義(spec.template)或映象名稱,並應用到Deployment物件上,系統即可完成Deployment的自動更新操作。 如果在更新過程中發生了錯誤, 則還可以通過回滾操作恢復Pod的版本。 示例:
  1 [root@uk8s-m-01 study]# vi nginx-deployment.yaml
  2 apiVersion: apps/v1beta1
  3 kind: Deployment
  4 metadata:
  5   name: nginx-deployment
  6 spec:
  7   replicas: 3
  8   template:
  9     metadata:
 10       labels:
 11         app: nginx
 12     spec:
 13       containers:
 14       - name: nginx
 15         image: nginx:1.7.9
 16         ports:
 17         - containerPort: 80
 18 
 19 [root@uk8s-m-01 study]# kubectl create -f nginx-deployment.yaml
 20 [root@uk8s-m-01 study]# kubectl get pods
  1 [root@uk8s-m-01 study]# kubectl get deployment			#檢視deployment
  2 [root@uk8s-m-01 study]# kubectl set image deployment/nginx-deployment nginx=nginx:1.8.1	#命令更新
  3 [root@uk8s-m-01 study]# kubectl get pods			        #檢視升級後的pod
  1 [root@uk8s-m-01 study]# kubectl edit deployment/nginx-deployment			#直接編輯deployment
  1 [root@uk8s-m-01 study]# kubectl rollout status deployment/nginx-deployment		#檢視升級情況
  1 [root@uk8s-m-01 study]# kubectl get pods
  2 [root@uk8s-m-01 study]# kubectl describe pod nginx-deployment-7448597cd5-8sng2 | grep Image

1.2 deployment升級原理

  1 [root@uk8s-m-01 study]# kubectl describe deployments/nginx-deployment		#觀察Deployment的更新過程
初始建立Deployment時,系統建立了一個ReplicaSet(nginx-deployment-5754944d6c),並按使用者的需求建立了3個Pod副本。 當更新Deployment時,系統建立了一個新的ReplicaSet(nginx-deployment-b5f766d54),並將其副本數量擴充套件到1,然後將舊ReplicaSet縮減為2。 之後,系統繼續按照相同的更新策略對新舊兩個ReplicaSet進行逐個調整。 最後,新的ReplicaSet運行了3個新版本Pod副本,舊的ReplicaSet副本數量則縮減為0。
  1 [root@uk8s-m-01 study]# kubectl get rs			#檢視多次升級的結果
注意:在整個升級的過程中,系統會保證至少有兩個Pod可用,並且最多同時執行4個Pod,這是Deployment通過複雜的演算法完成的。Deployment需要確保在整個更新過程中只有一定數量的Pod可能處於不可用狀態。在預設情況下,Deployment確保可用的Pod總數至少為所需的副本數量(DESIRED)減1,也就是最多1個不可用(maxUnavailable=1)。

1.3 deployment升級策略

在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)來控制滾動更新的過程。
    • spec.strategy.rollingUpdate.maxUnavailable:用於指定Deployment在更新過程中不可用狀態的Pod數量的上限。 該maxUnavailable的數值可以是絕對值(例如5)或Pod期望的副本數的百分比(例如10%),如果被設定為百分比,那麼系統會先以向下取整的方式計算出絕對值(整數)。而當另一個引數maxSurge被設定為0時,maxUnavailable則必須被設定為絕對數值大於0。舉例來說,當maxUnavailable被設定為30%時,舊的ReplicaSet可以在滾動更新開始時立即將副本數縮小到所需副本總數的70%。一旦新的Pod建立並準備好,舊的ReplicaSet會進一步縮容,新的ReplicaSet又繼續擴容。整個過程中系統在任意時刻都可以確保可用狀態的Pod總數至少佔Pod期望副本總數的70%。
    • spec.strategy.rollingUpdate.maxSurge:用於指定在Deployment更新Pod的過程中Pod總數超過Pod期望副本數部分的最大值。該maxSurge的數值可以是絕對值(例如5)或Pod期望副本數的百分比(例
  • 如10%)。如果設定為百分比,那麼系統會先按照向上取整的方式計算出絕對數值(整數)。舉例來說,當maxSurge的值被設定為30%時,新的ReplicaSet可以在滾動更新開始時立即進行副本數擴容,只需要保證新舊ReplicaSet的Pod副本數之和不超過期望副本數的130%即可。一旦舊的Pod被殺掉,新的ReplicaSet就會進一步擴容。在整個過程中系統在任意時刻都能確保新舊ReplicaSet的Pod副本總數之和不超過所需副本數的130%。

1.4 deployment回滾

預設情況下,所有Deployment的釋出歷史記錄都被保留在系統中,以便於我們隨時進行回滾(可以配置歷史記錄數量)。
  1 [root@uk8s-m-01 study]# kubectl rollout history deployment/nginx-deployment	#檢視部署歷史
  2 [root@uk8s-m-01 study]# kubectl rollout history deployment/nginx-deployment  --revision=3	#檢視對應的部署歷史版本
  3 [root@uk8s-m-01 study]# kubectl rollout history deployment/nginx-deployment  --revision=2	#檢視對應的部署歷史版本
提示:Deployment的更新操作是在Deployment進行部署(Rollout)時被觸發的,即當且僅當Deployment的Pod模板(即spec.template)被更改時才會建立新的修訂版本,例如更新模板標籤或容器映象。其他更新操作(如擴充套件副本數)將不會觸發Deployment的更新操作,因此將Deployment回滾到之前的版本時,只有Deployment的Pod模板部分會被修改。
  1 [root@uk8s-m-01 study]# kubectl rollout undo deployment/nginx-deployment --to-revision=2	#回滾版本
  2 [root@uk8s-m-01 study]# kubectl describe deployment/nginx-deployment

1.5 暫停和恢復deployment

對於一次複雜的Deployment配置修改,為了避免頻繁觸發Deployment的更新操作,可以先暫停Deployment的更新操作,然後進行 配置修改,再恢復Deployment,一次性觸發完整的更新操作,從而避免不必要的Deployment更新操作了。
  1 [root@uk8s-m-01 study]# kubectl get deployments				#檢視deployment
  2 [root@uk8s-m-01 study]# kubectl get rs					#檢視rs
  3 [root@uk8s-m-01 study]# kubectl rollout pause deployment/nginx-deployment	#暫停deployment
  4 [root@uk8s-m-01 study]# kubectl set image deployment/nginx-deployment nginx=nginx:1.10.3	#升級操作,但由於暫停deployment,因此不會觸發更新
  5 [root@uk8s-m-01 study]# kubectl rollout history deployment/nginx-deployment	#檢視歷史版本
  6 [root@uk8s-m-01 study]# kubectl set resources deployment/nginx-deployment -c=nginx --limits=cpu=200m,memory=512Mi
  7 [root@uk8s-m-01 study]# kubectl rollout resume deployment/nginx-deployment	#恢復deployment
  8 [root@uk8s-m-01 study]# kubectl get rs
  9 NAME                          DESIRED   CURRENT   READY   AGE
 10 nginx-deployment-7448597cd5   0         0         0       52m
 11 nginx-deployment-84bc94dcb7   1         1         0       6s
 12 nginx-deployment-b5f766d54    3         3         3       55m
  1 [root@uk8s-m-01 study]# kubectl describe deployment/nginx-deployment
  2 [root@uk8s-m-01 study]# kubectl describe pods nginx-deployment-84bc94dcb7-hqxkk | grep Image
  3     Image:          nginx:1.10.3

二 RC升級和回滾

2.1 RC滾動升級

, Kubernetes提供了kubectl rolling-update命令進行對於RC的滾動升級。該命令建立了一個新的RC,然後自動控制舊的RC中的Pod副本數量逐漸減少到0,同時新的RC中的Pod副本數量從0逐步增加到目標值,來完成Pod的升級。 注意:該方式要求新的RC與舊的RC都在相同的名稱空間內。 示例:
  1 [root@uk8s-m-01 study]# vi redis-master-controller-v1.yaml
  2 apiVersion: v1
  3 kind: ReplicationController
  4 metadata:
  5   name: redis-master-v1
  6   labels:
  7     name: redis-master
  8 spec:
  9   replicas: 1
 10   selector:
 11     name: redis-master
 12   template:
 13     metadata:
 14       labels:
 15         name: redis-master
 16     spec:
 17       containers:
 18       - name: master
 19         image: kubeguide/redis-master:1.0
 20         ports:
 21         - containerPort: 6379
 22 
 23 [root@uk8s-m-01 study]# kubectl create -f redis-master-controller-v1.yaml
  1 [root@uk8s-m-01 study]# vi redis-master-controller-v2.yaml		#RC升級配置檔案
  2 apiVersion: v1
  3 kind: ReplicationController
  4 metadata:
  5   name: redis-master-v2
  6   labels:
  7     name: redis-master
  8     version: v2
  9 spec:
 10   replicas: 1
 11   selector:
 12     name: redis-master
 13     version: v2
 14   template:
 15     metadata:
 16       labels:
 17         name: redis-master
 18         version: v2
 19     spec:
 20       containers:
 21       - name: master
 22         image: kubeguide/redis-master:2.0
 23         ports:
 24         - containerPort: 6379
注意:使用此方式升級的時候需要注意以下兩點:
  1. RC的名字(name) 不能與舊RC的名字相同。
  2. 在selector中應至少有一個Label與舊RC的Label不同, 以標識其為新RC。如上所示新增了一個名為version的Label,以與舊RC進行區分。
  1 [root@uk8s-m-01 study]# kubectl rolling-update redis-master-v1 -f redis-master-controller-v2.yaml
  2 [root@uk8s-m-01 study]# kubectl rolling-update redis-master-v1 --image=kubeguide/redis-master:2.0	#也可直接命令中升級
kubectl通過新建一個新版本Pod, 停掉一箇舊版本Pod,如此逐步迭代來完成整個RC的更新。

2.2 RC回滾

  1 [root@uk8s-m-01 study]# kubectl rolling-update redis-master-v1 --rollback
提示:RC的滾動升級不具有Deployment在應用版本升級過程中的歷史記錄、新舊版本數量的精細控制等功能,RC將逐漸被RS和Deployment所取代,建議使用者優先考慮使用Deployment完成Pod的部署和升級操作。