詳解k8s零停機(jī)滾動發(fā)布微服務(wù) - kubernetes

1、前言

在當(dāng)下微服務(wù)架構(gòu)盛行的時代,用戶希望應(yīng)用程序時時刻刻都是可用,為了滿足不斷變化的新業(yè)務(wù),需要不斷升級更新應(yīng)用程序,有時可能需要頻繁的發(fā)布版本。實(shí)現(xiàn)"零停機(jī)"、“零感知”的持續(xù)集成(Continuous Integration)和持續(xù)交付/部署(Continuous Delivery)應(yīng)用程序,一直都是軟件升級換代不得不面對的一個難題和痛點(diǎn),也是一種追求的理想方式,也是DevOps誕生的目的。

2、滾動發(fā)布

把一次完整的發(fā)布過程,合理地分成多個批次,每次發(fā)布一個批次,成功后,再發(fā)布下一個批次,最終完成所有批次的發(fā)布。在整個滾動過程期間,保證始終有可用的副本在運(yùn)行,從而平滑的發(fā)布新版本,實(shí)現(xiàn)零停機(jī)(without an outage)、用戶零感知,是一種非常主流的發(fā)布方式。由于其自動化程度比較高,通常需要復(fù)雜的發(fā)布工具支撐,而k8s可以完美的勝任這個任務(wù)。

3、k8s滾動更新機(jī)制

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

大致步驟如下:

1. 創(chuàng)建一個新的replication controller。
2. 增加或減少pod副本數(shù)量,直到滿足當(dāng)前批次期望的數(shù)量。
3. 刪除舊的replication controller。

4、演示

使用kubectl更新一個已部署的應(yīng)用程序,并模擬回滾。為了方便分析,將應(yīng)用程序的pod副本數(shù)量設(shè)置為10。

kubectl -n k8s-ecoysystem-apps scale deployment helloworldapi  --replicas=10
4.1. 發(fā)布微服務(wù)
# 查看部署列表
$ kubectl get deployments -n k8s-ecoysystem-apps
# 查看正在運(yùn)行的pod
$ kubectl get pods -n k8s-ecoysystem-apps
# 通過pod描述,查看應(yīng)用程序的當(dāng)前映像版本
$ 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. 驗(yàn)證發(fā)布
# 檢查rollout狀態(tài)
$ kubectl -n k8s-ecoysystem-apps rollout status deployments/helloworldapi 
# 檢查pod詳情
$ kubectl describe pods -n k8s-ecoysystem-apps

從上圖可以看到,鏡像已經(jīng)升級到v2.3版本

4.3. 回滾發(fā)布
$ kubectl -n k8s-ecoysystem-apps rollout undo deployments/helloworldapi 

到目前為止,整個滾動發(fā)布工作就圓滿完成了!??!
那么如果我們想回滾到指定版本呢?答案是k8s完美支持,并且還可以通過資源文件進(jìn)行配置保留的歷史版次量。由于篇幅有限,感興趣的朋友,可以自己下去實(shí)戰(zhàn),回滾命令如下:

$ kubectl -n k8s-ecoysystem-apps rollout undo deployment/helloworldapi  --to-revision=<版次>

5、原理

k8s精確地控制著整個發(fā)布過程,分批次有序地進(jìn)行著滾動更新,直到把所有舊的副本全部更新到新版本。實(shí)際上,k8s是通過兩個參數(shù)來精確地控制著每次滾動的pod數(shù)量:

`maxSurge` 滾動更新過程中運(yùn)行操作期望副本數(shù)的最大pod數(shù),可以為絕對數(shù)值(eg:5),但不能為0;也可以為百分?jǐn)?shù)(eg:10%)。默認(rèn)為25%。
`maxUnavailable` 滾動更新過程中不可用的最大pod數(shù),可以為絕對數(shù)值(eg:5),但不能為0;也可以為百分?jǐn)?shù)(eg:10%)。默認(rèn)為25%。

如果未指定這兩個可選參數(shù),則k8s會使用默認(rèn)配置:

$ kubectl -n k8s-ecoysystem-apps get deployment helloworldapi -o yaml
5.1. 剖析部署概況
`DESIRED`    最終期望處于READY狀態(tài)的副本數(shù)
`CURRENT`    當(dāng)前的副本總數(shù)
`UP-TO-DATE` 當(dāng)前完成更新的副本數(shù)
`AVAILABLE`  當(dāng)前可用的副本數(shù)

當(dāng)前的副本總數(shù) = 10 + 10 * 25% = 13,所以CURRENT為13。
當(dāng)前可用的副本數(shù) = 10 - 10 * 25% = 8,所以AVAILABLE為8。

5.2. 剖析部署詳情
kubectl -n k8s-ecoysystem-apps describe deployment helloworldapi

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

 1.  創(chuàng)建了一個新的副本集,并為其分配3個新版本的pod,使副本總數(shù)達(dá)到13,一切正常。
 2.  通知舊副本集,銷毀2個舊版本的pod,使可用副本總數(shù)保持到8,一起正常。
 3.  當(dāng)兩個副本銷毀成功后,通知新副本集,再新增2個新版本的pod,使副本總數(shù)達(dá)到13,一切正常。
     只要銷毀成功,新副本集就會創(chuàng)造新的pod,一直循環(huán),直到舊的副本集pod數(shù)量為0。

滾動升級一個服務(wù),實(shí)際就是創(chuàng)建一個新的RS,然后逐漸將新RS中副本數(shù)增加到理想狀態(tài),將舊RS中的副本數(shù)減小到0的復(fù)合操作;

無論理想還是不理想,k8s最終都會使應(yīng)用程序全部更新到期望狀態(tài),都會始終保持最大的副本總數(shù)和可用副本總數(shù)的不變性?。?!

6、總結(jié)

本篇詳解了k8s滾動更新機(jī)制,并通過實(shí)戰(zhàn)演示了微服務(wù)的滾動更新,當(dāng)然還可以加入健康檢查歷史版次回滾,大家可以下去自己實(shí)踐,在實(shí)戰(zhàn)中學(xué)習(xí)和進(jìn)步,基礎(chǔ)打牢后,我們將結(jié)合實(shí)際情況,實(shí)戰(zhàn)更多的例子,下一篇將實(shí)戰(zhàn)金絲雀發(fā)布微服務(wù),請繼續(xù)關(guān)注。

本篇已貢獻(xiàn)給kubeasz,使用指南,特性實(shí)驗(yàn),Rollingupdate

如果你覺得本篇文章對您有幫助的話,感謝您的【推薦】。
如果你對 kubernets 感興趣的話可以關(guān)注我,我會定期的在博客分享我的學(xué)習(xí)心得。

原文鏈接

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

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容