Pod 升級和回滾
參考鏈接
使用kubernetes 進行升級的時候並不需要停止業務,kubectl 支持滾動升級的方式,每次更新一個pod,而不是同時刪除整個服務。
目前的kubernetes 版本只支持Replication Controllers的方式實現滾動升級。然而,官方推薦的方式是使用Deployments. Deployments是一個更高級別的控制器,它以聲明方式自動執行應用程序的滾動更新,因此推薦使用。
這裏將重點介紹使用Deployment的方式。
- 創建一個nginx應用的deployment:
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 3 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.7.9 ports: - containerPort: 80
可以看到,創建了3個Pod副本:
# kubectl get pods NAME READY STATUS RESTARTS AGE nginx-deployment-75675f5897-jhr26 1/1 Running 0 36m nginx-deployment-75675f5897-n77ds 1/1 Running 0 36m nginx-deployment-75675f5897-ns6pn 1/1 Running 0 36m
更新鏡像為nginx 1.10.3:
# kubectl set image deployment nginx-deployment nginx=nginx:1.10.3 # kubectl get pods NAME READY STATUS RESTARTS AGE nginx-deployment-75675f5897-n77ds 0/1 Terminating 0 47m nginx-deployment-75d56bb955-54686 1/1 Running 0 7s nginx-deployment-75d56bb955-5zxqz 1/1 Running 0 10s nginx-deployment-75d56bb955-bxqd9 1/1 Running 0 8s # kubectl get pods -o wide NAME READY STATUS RESTARTS AGE IP NODE nginx-deployment-75d56bb955-54686 1/1 Running 0 2m 10.2.74.9 10.0.0.3 nginx-deployment-75d56bb955-5zxqz 1/1 Running 0 2m 10.2.74.8 10.0.0.3 nginx-deployment-75d56bb955-bxqd9 1/1 Running 0 2m 10.2.62.16 10.0.0.2 # curl --head 10.2.62.16 HTTP/1.1 200 OK Server: nginx/1.10.3 Date: Wed, 20 Jun 2018 10:52:10 GMT Content-Type: text/html Content-Length: 612 Last-Modified: Tue, 31 Jan 2017 15:01:11 GMT Connection: keep-alive ETag: "5890a6b7-264" Accept-Ranges: bytes
我們也可以直接使用編輯配置文件的方式,直接修改nginx鏡像版本為1.12.2:
# kubectl edit deployment nginx-deployment
# kubectl get pods -o wide
NAME READY STATUS RESTARTS AGE IP NODE
nginx-deployment-7498dc98f8-756tq 1/1 Running 0 11s 10.2.62.17 10.0.0.2
nginx-deployment-7498dc98f8-g265v 1/1 Running 0 13s 10.2.74.10 10.0.0.3
nginx-deployment-7498dc98f8-hh6wv 1/1 Running 0 10s 10.2.74.11 10.0.0.3
curl --head 10.2.62.17
HTTP/1.1 200 OK
Server: nginx/1.12.2
...
在進行滾動升級的過程中,Deployment 進行初始化時,創建了一個新的ReplicaSet,新的ReplicaSet 逐漸創建新的Pod 副本,舊的ReplicaSet 逐漸銷毀舊的副本,並始終保持副本數量恒定,逐步滾動替換。
可以查看ReplicaSet的狀態:
# kubectl get rs -o wide
NAME DESIRED CURRENT READY AGE CONTAINERS IMAGES SELECTOR
nginx-deployment-7498dc98f8 3 3 3 44m nginx nginx:1.12.2 app=nginx,pod-template-hash=3054875494
nginx-deployment-75675f5897 0 0 0 1h nginx nginx:1.7.9 app=nginx,pod-template-hash=3123191453
nginx-deployment-75d56bb955 0 0 0 59m nginx nginx:1.10.3 app=nginx,pod-template-hash=3181266511
查看更新的狀態:
kubectl rollout status deployment/nginx-deployment
在Deployment的定義中,可以通過spec.strategy指定的Pod更新策略,支持兩種策略:
- Recreate(重建):設置
spec.strategy.type=Recreate
, 表示Deployment在更新Pod的時候,會先殺掉所有正在運行的Pod,然後創建新的Pod。 - RollingUpdate(滾動更新): 設置
spec.strategy.type=RollingUpdate
,表示Deployment會以滾動更新的方式來逐個更新Pod。可以指定
RollingUpdate(滾動更新)有兩個主要參數,來控制更新的Pod副本數量:
- .spec.strategy.rollingUpdate.maxUnavailable : 用於指定Deployment在更新過程中不可用狀態的Pod數量上限。該maxUnavailable的數值可以是絕對值正整數,也可以是Pod期望的副本數的百分比(例如10%)。如果設置為百分比,那麽系統會先以向下取整的方式計算出絕對值整數,但是當.spec.strategy.rollingUpdate.maxSurge值為0時,其值不能為0。 默認情況下為25%。
- .spec.strategy.rollingUpdate.maxSurge: 用於指定Deployment更新Pod過程中Pod總數超過Pod期望副本部分的最大值。該maxSurge的數值可以是絕對值(例如5)或Pod期望副本數的百分比(例如10%)。如果設置為百分比,那麽系統會先按照向上取整的方式計算出絕對數值。如果MaxUnavailable的值為0,則這個值不能為0,默認值是25%。
需要註意更新Deployment的標簽選擇器(Label selector)的情況。通常不鼓勵更新Deployment 的標簽選擇器,這樣會導致Deployment選擇的Pod列表發生變化,也可能與其它控制器產生的沖突。
如果要更新Deployment標簽選擇器,有以下註意事項:
- 添加標簽選擇器時,必須同步修改Deployment配置的Pod標簽,為Pod添加新的標簽,否則Deployment的更新會報驗證錯誤而失敗。更改標簽之後,舊的rs將會依舊存在,deployment將無法管理舊的RS。直接執行
kubectl delete rs <rs-name>
即可刪除。 - 更新標簽選擇器,即更新選擇器中標簽的鍵或值,也會產生與添加選擇器標簽類似的效果。
- 刪除標簽選擇器,即從Deployment的標簽選擇器中刪除一個或者多個標簽,該Deployment的ReplicaSet 和Pod不會受到任何影響,但需要註意的是,被刪除的標簽仍然會存在於現有的Pod和ReplicaSet上。
Deployment的回滾
1、查看Deployment部署的歷史記錄:
kubectl rollout history deployment/nginx-deployment
如果查看到的結果為None,則需要在創建和更新deployment時加上 --record參數.
2、查看特定的版本信息:
# kubectl rollout history deployment/nginx-deployment --revision=3
3、撤銷本次發布,回滾到上一個版本:
# kubectl rollout undo deployment/nginx-deployment
4、可以指定版本回滾:
# kubectl rollout undo deployment/nginx-deployment --to-revision=2
5、查看回滾狀態:
# kubectl rollout status deployments nginx-deployment
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for rollout to finish: 2 out of 3 new replicas have been updated...
Waiting for rollout to finish: 1 old replicas are pending termination...
Waiting for rollout to finish: 1 old replicas are pending termination...
deployment "nginx-deployment" successfully rolled out
暫停和恢復Deployment的部署操作
對於一次復雜的Deplyment配置修改,為了避免頻繁觸發Deployment的更新操作,可以先暫停Deployment的更新操作,然後進行配置修改,等所有的修改完成後,再恢復Deployment,一次性觸發完整的更新操作。這樣就可以避免不必要的Deployment的更新操作。
1、 暫停Deployment的操作
# kubectl rollout pause deployment/nginx-deployment
2、修改deployment的鏡像信息:
# kubectl set image deploy/nginx-deployment nginx=nginx:1.12.2
# 查看更新記錄,沒有變化
# kubectl rollout history deploy/nginx-deployment
deployments "nginx-deployment"
REVISION CHANGE-CAUSE
1 <none>
4 <none>
5 <none>
3、再次更新容器資源限制:
# kubectl set resources deployment nginx-deployment -c=nginx --limits=cpu=200m,memory=512Mi
4、恢復Deployment的部署操作
kubectl rollout resume deploy/nginx-deployment
5、歷史記錄以及更新:
# kubectl rollout history deploy/nginx-deployment
deployments "nginx-deployment"
REVISION CHANGE-CAUSE
1 <none>
4 <none>
5 <none>
6 <none>
k8s還提供了針對RC進行滾動升級的方式,使用 kubectl rolling-update 命令來執行。由於RC升級過程無法查看記錄,無法進行版本數量的精細化控制,將逐漸被RS取代,所以建議優先使用Deployment的方式完成Pod的部署升級,這裏不做討論。
其他對象的更新策略
DaemonSet的更新策略
- OnDelete:這是用於向後兼容的默認更新策略。 使用OnDelete更新策略,在更新DaemonSet模板之後,只有在手動刪除舊的DaemonSet窗格時才會創建新的DaemonSet Pod。 這與Kubernetes版本1.5或更早版本中的DaemonSet是一致的。
- RollingUpdate:通過RollingUpdate更新策略,在更新DaemonSet模板後,舊的DaemonSet窗格將被終止,並且將以受控的方式自動創建新的DaemonSet。不過不支持DaemonSet的更新歷史記錄,並且回滾並不能如Deployment直接通過kubectl rollback 命令來實現。
Pod 升級和回滾