在當下微服務架構盛行的時代,用戶但願應用程序時時刻刻都是可用,爲了知足不斷變化的新業務,須要不斷升級更新應用程序,有時可能須要頻繁的發佈版本。實現"零停機"、「零感知」的持續集成(Continuous Integration)和持續交付/部署(Continuous Delivery)應用程序,一直都是軟件升級換代不得不面對的一個難題和痛點,也是一種追求的理想方式,也是DevOps誕生的目的。javascript
把一次完整的發佈過程,合理地分紅多個批次,每次發佈一個批次,成功後,再發佈下一個批次,最終完成全部批次的發佈。在整個滾動過程期間,保證始終有可用的副本在運行,從而平滑的發佈新版本,實現零停機(without an outage)、用戶零感知,是一種很是主流的發佈方式。因爲其自動化程度比較高,一般須要複雜的發佈工具支撐,而k8s能夠完美的勝任這個任務。java
k8s建立副本應用程序的最佳方法就是部署(Deployment),部署自動建立副本集(ReplicaSet),副本集能夠精確地控制每次替換的Pod數量,從而能夠很好的實現滾動更新。具體來講,k8s每次使用一個新的副本控制器(replication controller)來替換已存在的副本控制器,從而始終使用一個新的Pod模板來替換舊的pod模板。git
大體步驟以下:github
- 建立一個新的replication controller。
- 增長或減小pod副本數量,直到知足當前批次指望的數量。
- 刪除舊的replication controller。
使用kubectl更新一個已部署的應用程序,並模擬回滾。爲了方便分析,將應用程序的pod副本數量設置爲10。api
kubectl -n k8s-ecoysystem-apps scale deployment helloworldapi --replicas=10
查看部署列表 $ kubectl get deployments -n k8s-ecoysystem-apps 查看正在運行的pod $ kubectl get pods -n k8s-ecoysystem-apps 經過pod描述,查看應用程序的當前映像版本 $ kubectl describe pods -n k8s-ecoysystem-apps
升級鏡像版本到v2.3 $ kubectl -n k8s-ecoysystem-apps set image deployments/helloworldapi helloworldapi=registry.wuling.com/justmine/helloworldapi:v2.3
檢查rollout狀態 kubectl -n k8s-ecoysystem-apps rollout status deployments/helloworldapi 檢查pod詳情 kubectl describe pods -n k8s-ecoysystem-apps
從上圖能夠看到,鏡像已經升級到v2.3版本架構
kubectl -n k8s-ecoysystem-apps rollout undo deployments/helloworldapi
到目前爲止,整個滾動發佈工做就圓滿完成了!!!
那麼若是咱們想回滾到指定版本呢?答案是k8s完美支持,而且還能夠經過資源文件進行配置保留的歷史版次量。因爲篇幅有限,感興趣的朋友,能夠本身下去實戰,回滾命令以下:app
# 1. 查看版次 kubectl -n k8s-ecoysystem-apps rollout history deployment/helloworldapi # 2. 回滾到指定版次 kubectl -n k8s-ecoysystem-apps rollout undo deployment/helloworldapi --to-revision=<版次>
k8s精確地控制着整個發佈過程,分批次有序地進行着滾動更新,直到把全部舊的副本所有更新到新版本。實際上,k8s是經過兩個參數來精確地控制着每次滾動的pod數量:ide
maxSurge
滾動更新過程當中運行操做指望副本數的最大pod數,能夠爲絕對數值(eg:5),但不能爲0;也能夠爲百分數(eg:10%)。默認爲25%。maxUnavailable
滾動更新過程當中不可用的最大pod數,能夠爲絕對數值(eg:5),但不能爲0;也能夠爲百分數(eg:10%)。默認爲25%。
若是未指定這兩個可選參數,則k8s會使用默認配置:svg
kubectl -n k8s-ecoysystem-apps get deployment helloworldapi -o yaml
DESIRED
最終指望處於READY狀態的副本數
CURRENT
當前的副本總數
UP-TO-DATE
當前完成更新的副本數
AVAILABLE
當前可用的副本數
當前的副本總數 = 10 + 10 * 25% = 13,因此CURRENT爲13。
當前可用的副本數 = 10 - 10 * 25% = 8,因此AVAILABLE爲8。微服務
kubectl -n k8s-ecoysystem-apps describe deployment helloworldapi
整個滾動過程是經過控制兩個副本集來完成的,新的副本集:helloworldapi-6564f59f66;舊的副本集:helloworldapi-6f4959c8c7 。
理想狀態下的滾動過程:
- 建立了一個新的副本集,併爲其分配3個新版本的pod,使副本總數達到13,一切正常。
- 通知舊副本集,銷燬2箇舊版本的pod,使可用副本總數保持到8,一塊兒正常。
- 當兩個副本銷燬成功後,通知新副本集,再新增2個新版本的pod,使副本總數達到13,一切正常。
只要銷燬成功,新副本集就會創造新的pod,一直循環,直到舊的副本集pod數量爲0。
滾動升級一個服務,實際就是建立一個新的RS,而後逐漸將新RS中副本數增長到理想狀態,將舊RS中的副本數減少到0的複合操做;
不管理想仍是不理想,k8s最終都會使應用程序所有更新到指望狀態,都會始終保持最大的副本總數和可用副本總數的不變性!!!
本篇詳解了k8s滾動更新機制,並經過實戰演示了微服務的滾動更新,固然還能夠加入健康檢查和歷史版次回滾,你們能夠下去本身實踐,在實戰中學習和進步,基礎打牢後,咱們將結合實際狀況,實戰更多的例子,下一篇將實戰金絲雀發佈微服務,請繼續關注。
本篇已貢獻給kubeasz,使用指南,特性實驗,Rollingupdate
若是你以爲本篇文章對您有幫助的話,感謝您的【推薦】。
若是你對 kubernets 感興趣的話能夠關注我,我會按期的在博客分享個人學習心得。
https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#rolling-update
https://kubernetes.io/docs/tutorials/kubernetes-basics/update-intro/
https://kubernetes.io/docs/reference/generated/kubectl/kubectl-commands#rolling-update
https://github.com/kubernetes/community/blob/master/contributors/design-proposals/cli/simple-rolling-update.md
https://kubernetes.io/docs/tasks/run-application/rolling-update-replication-controller
https://kubernetes.io/docs/tutorials/kubernetes-basics/update-interactive
https://kubernetes.io/images/docs/kubectl_rollingupdate.svg