一 deploymentPod升級和回滾 1.1 deployment升級 若Pod是通過Deployment創建的,可以在運行時修改Deployment的Pod定義(spec.template)或鏡像名稱,並應用到Deployment對象上,系統即可完成Deployment的自動更新操作。 如果在 ...
一 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註意:使用此方式升級的時候需要註意以下兩點:
- RC的名字(name) 不能與舊RC的名字相同。
- 在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的部署和升級操作。