1. 程式人生 > 實用技巧 >詳解k8s零停機滾動釋出微服務 - kubernetes

詳解k8s零停機滾動釋出微服務 - kubernetes

1、前言

在當下微服務架構盛行的時代,使用者希望應用程式時時刻刻都是可用,為了滿足不斷變化的新業務,需要不斷升級更新應用程式,有時可能需要頻繁的釋出版本。實現"零停機"、“零感知”的持續整合(Continuous Integration)和持續交付/部署(Continuous Delivery)應用程式,一直都是軟體升級換代不得不面對的一個難題和痛點,也是一種追求的理想方式,也是DevOps誕生的目的。

2、滾動釋出

把一次完整的釋出過程,合理地分成多個批次,每次釋出一個批次,成功後,再發佈下一個批次,最終完成所有批次的釋出。在整個滾動過程期間,保證始終有可用的副本在執行,從而平滑的釋出新版本,實現零停機(without an outage)

、使用者零感知,是一種非常主流的釋出方式。由於其自動化程度比較高,通常需要複雜的釋出工具支撐,而k8s可以完美的勝任這個任務。

3、k8s滾動更新機制

k8s建立副本應用程式的最佳方法就是部署(Deployment),部署自動建立副本集(ReplicaSet),副本集可以精確地控制每次替換的Pod數量,從而可以很好的實現滾動更新。具體來說,k8s每次使用一個新的副本控制器(replication controller)來替換已存在的副本控制器,從而始終使用一個新的Pod模板來替換舊的pod模板。

大致步驟如下:

  1. 建立一個新的replication controller。
  2. 增加或減少pod副本數量,直到滿足當前批次期望的數量。
  3. 刪除舊的replication controller。

4、演示

使用kubectl更新一個已部署的應用程式,並模擬回滾。為了方便分析,將應用程式的pod副本數量設定為10。

kubectl -n k8s-ecoysystem-apps scale deployment helloworldapi  --replicas=10

4.1. 釋出微服務

檢視部署列表
$ 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

4.2. 驗證釋出

檢查rollout狀態
kubectl -n k8s-ecoysystem-apps rollout status deployments/helloworldapi 
檢查pod詳情
kubectl describe pods -n k8s-ecoysystem-apps


從上圖可以看到,映象已經升級到v2.3版本

4.3. 回滾釋出

kubectl -n k8s-ecoysystem-apps rollout undo deployments/helloworldapi 


到目前為止,整個滾動釋出工作就圓滿完成了!!!
那麼如果我們想回滾到指定版本呢?答案是k8s完美支援,並且還可以通過資原始檔進行配置保留的歷史版次量。由於篇幅有限,感興趣的朋友,可以自己下去實戰,回滾命令如下:

# 1. 檢視版次
kubectl -n k8s-ecoysystem-apps rollout history deployment/helloworldapi
# 2. 回滾到指定版次
kubectl -n k8s-ecoysystem-apps rollout undo deployment/helloworldapi  --to-revision=<版次>

5、原理

k8s精確地控制著整個釋出過程,分批次有序地進行著滾動更新,直到把所有舊的副本全部更新到新版本。實際上,k8s是通過兩個引數來精確地控制著每次滾動的pod數量:

  • maxSurge滾動更新過程中執行操作期望副本數的最大pod數,可以為絕對數值(eg:5),但不能為0;也可以為百分數(eg:10%)。預設為25%。
  • maxUnavailable滾動更新過程中不可用的最大pod數,可以為絕對數值(eg:5),但不能為0;也可以為百分數(eg:10%)。預設為25%。

如果未指定這兩個可選引數,則k8s會使用預設配置:

kubectl -n k8s-ecoysystem-apps get deployment helloworldapi -o yaml

5.1. 剖析部署概況

  • DESIRED最終期望處於READY狀態的副本數
  • CURRENT當前的副本總數
  • UP-TO-DATE當前完成更新的副本數
  • AVAILABLE當前可用的副本數

當前的副本總數 = 10 + 10 * 25% = 13,所以CURRENT為13。
當前可用的副本數 = 10 - 10 * 25% = 8,所以AVAILABLE為8。

5.2. 剖析部署詳情

kubectl -n k8s-ecoysystem-apps describe deployment helloworldapi  

整個滾動過程是通過控制兩個副本集來完成的,新的副本集:helloworldapi-6564f59f66;舊的副本集:helloworldapi-6f4959c8c7 。
理想狀態下的滾動過程:

  1. 建立了一個新的副本集,併為其分配3個新版本的pod,使副本總數達到13,一切正常。
  2. 通知舊副本集,銷燬2箇舊版本的pod,使可用副本總數保持到8,一起正常。
  3. 當兩個副本銷燬成功後,通知新副本集,再新增2個新版本的pod,使副本總數達到13,一切正常。
    只要銷燬成功,新副本集就會創造新的pod,一直迴圈,直到舊的副本集pod數量為0。

滾動升級一個服務,實際就是建立一個新的RS,然後逐漸將新RS中副本數增加到理想狀態,將舊RS中的副本數減小到0的複合操作;

無論理想還是不理想,k8s最終都會使應用程式全部更新到期望狀態,都會始終保持最大的副本總數和可用副本總數的不變性!!!

6、總結

本篇詳解了k8s滾動更新機制,並通過實戰演示了微服務的滾動更新,當然還可以加入健康檢查歷史版次回滾,大家可以下去自己實踐,在實戰中學習和進步,基礎打牢後,我們將結合實際情況,實戰更多的例子,下一篇將實戰金絲雀釋出微服務,請繼續關注。

本篇已貢獻給kubeasz,使用指南,特性實驗,Rollingupdate

如果你覺得本篇文章對您有幫助的話,感謝您的【推薦】
如果你對 kubernets 感興趣的話可以關注我,我會定期的在部落格分享我的學習心得

7、延伸閱讀

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

做一個有底蘊的軟體工作者