隨著小步快跑、快速迭代的開(kāi)發(fā)模式被越來(lái)越多的互聯(lián)網(wǎng)企業(yè)認(rèn)同和采用,應(yīng)用的變更、升級(jí)頻率變得越來(lái)越頻繁。為了應(yīng)對(duì)不同的升級(jí)需求,保證升級(jí)過(guò)程平穩(wěn)順利地進(jìn)行,誕生了一系列的部署發(fā)布模式。
10年積累的網(wǎng)站設(shè)計(jì)、成都網(wǎng)站建設(shè)經(jīng)驗(yàn),可以快速應(yīng)對(duì)客戶對(duì)網(wǎng)站的新想法和需求。提供各種問(wèn)題對(duì)應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認(rèn)識(shí)你,你也不認(rèn)識(shí)我。但先網(wǎng)站制作后付款的網(wǎng)站建設(shè)流程,更有永順免費(fèi)網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。隨著越來(lái)越多的應(yīng)用被容器化,如何方便地讓容器應(yīng)用平穩(wěn)順利升級(jí)受到了廣泛關(guān)注。本文將介紹 k8s 中不同部署形式下應(yīng)用的升級(jí)方法,并重點(diǎn)介紹如何對(duì) deployment 中的應(yīng)用實(shí)施滾動(dòng)發(fā)布(本文所作的調(diào)研基于k8s 1.13
)。
在 k8s 中,pod 是部署和升級(jí)的基本單位。一般來(lái)說(shuō),一個(gè) pod 代表一個(gè)應(yīng)用實(shí)例,而 pod 又會(huì)以deployment、statefulset、daemonset、job等形式部署運(yùn)行,下面依次介紹在這些部署形式下 pod 的升級(jí)方法。
deployment 是 pod 最常見(jiàn)的部署形式,這里將以基于 spring boot 的 java 應(yīng)用為例進(jìn)行介紹。該應(yīng)用是基于真實(shí)應(yīng)用抽象出來(lái)的簡(jiǎn)單版本,非常具有代表性,它有如下特點(diǎn):成都服務(wù)器托管
為了讓具有上述特點(diǎn)的應(yīng)用實(shí)現(xiàn)零宕機(jī)時(shí)間和無(wú)生產(chǎn)中斷的升級(jí),需要精心地配置 deployment 中的相關(guān)參數(shù)。這里和升級(jí)有關(guān)的配置如下(完整配置參見(jiàn)spring-boot-probes-v1.yaml)。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | kind: deployment ... spec: replicas: 8 strategy: type: rollingupdate rollingupdate: maxsurge: 3 maxunavailable: 2 minreadyseconds: 120 ... template: ... spec: containers: - name: spring-boot-probes image: registry.cn-hangzhou.aliyuncs.com/log-service/spring-boot-probes: 1.0 . 0 ports: - containerport: 8080 terminationgraceperiodseconds: 60 readinessprobe: httpget: path: /actuator/health port: 8080 initialdelayseconds: 30 periodseconds: 10 successthreshold: 1 failurethreshold: 1 livenessprobe: httpget: path: /actuator/health port: 8080 initialdelayseconds: 40 periodseconds: 20 successthreshold: 1 failurethreshold: 3 ... |
通過(guò) strategy 可以配置 pod 的替換策略,主要參數(shù)如下。
.spec.strategy.type
- 用于指定替換 pod 的策略類(lèi)型。該參數(shù)可取值 recreate 或 rollingupdate,默認(rèn)為 rollingupdate。
.spec.strategy.rollingupdate.maxsurge
- 指定在滾動(dòng)更新過(guò)程中最多可創(chuàng)建多少個(gè)額外的 pod,可以是數(shù)字或百分比。該值設(shè)置得越大、升級(jí)速度越快,但會(huì)消耗更多的系統(tǒng)資源。.spec.strategy.rollingupdate.maxunavailable
- 指定在滾動(dòng)更新過(guò)程中最多允許多少個(gè) pod 不可用, 可以是數(shù)字或百分比。該值設(shè)置得越大、升級(jí)速度越快,但服務(wù)會(huì)越不穩(wěn)定。通過(guò)調(diào)節(jié) maxsurge 和 maxunavailable,可以滿足不同場(chǎng)景下的升級(jí)需求。
樣例選擇了一個(gè)折中方案,將 maxsurge 設(shè)置為 3,將 maxunavailable 設(shè)置為 2,平衡了穩(wěn)定性、資源消耗和升級(jí)速度。
k8s 提供以下兩類(lèi)探針:成都服務(wù)器托管
探針的配置非常靈活,用戶可以指定探針的探測(cè)頻率、探測(cè)成功閾值、探測(cè)失敗閾值等。各參數(shù)的含義和配置方法可參考文檔configure liveness and readiness probes。
樣例為目標(biāo)容器配置了就緒探針和活性探針:成都服務(wù)器托管
默認(rèn)情況下,一旦新創(chuàng)建的 pod 變成就緒狀態(tài) k8s 就會(huì)認(rèn)為該 pod 是可用的,從而將老的 pod 刪除掉。但有時(shí)問(wèn)題可能會(huì)在新 pod 真正處理用戶請(qǐng)求時(shí)才暴露,因此一個(gè)更穩(wěn)健的做法是當(dāng)某個(gè)新 pod 就緒后對(duì)其觀察一段時(shí)間再刪掉老的 pod。
參數(shù) minreadyseconds 可以控制 pod 處于就緒狀態(tài)的觀察時(shí)間。如果 pod 中的容器在這段時(shí)間內(nèi)都能正常運(yùn)行,k8s 才會(huì)認(rèn)為新 pod 可用,從而將老的 pod 刪除掉。在配置該參數(shù)時(shí),需要仔細(xì)權(quán)衡,如果設(shè)置得過(guò)小,可能造成觀察不充分,如果設(shè)置得過(guò)大,又會(huì)拖慢升級(jí)進(jìn)度。樣例將 minreadyseconds 設(shè)置成了 120 秒,這樣能保證處于就緒狀態(tài)的 pod 能經(jīng)歷一個(gè)完整的活性探測(cè)周期。
當(dāng) k8s 準(zhǔn)備刪除一個(gè) pod 時(shí),會(huì)向該 pod 中的容器發(fā)送 term 信號(hào)并同時(shí)將 pod 從 service 的 endpoint 列表中移除。如果容器無(wú)法在規(guī)定時(shí)間(默認(rèn) 30 秒)內(nèi)終止,k8s 會(huì)向容器發(fā)送 sigkill 信號(hào)強(qiáng)制終止進(jìn)程。pod 終止的詳細(xì)流程可參考文檔termination of pods。
由于應(yīng)用處理請(qǐng)求最長(zhǎng)耗時(shí) 40 秒,為了讓其在關(guān)閉前能夠處理完已到達(dá)服務(wù)端的請(qǐng)求,樣例設(shè)置了 60 秒的優(yōu)雅關(guān)閉時(shí)間。針對(duì)不同的應(yīng)用,您可以根據(jù)實(shí)際情況調(diào)整 terminationgraceperiodseconds 的取值。
上述配置能夠保證目標(biāo)應(yīng)用的平滑升級(jí)。我們可以通過(guò)更改 deployment 中 podtemplatespec 的任意字段觸發(fā) pod 升級(jí),并通過(guò)運(yùn)行命令kubectl get rs -w
觀察升級(jí)行為。這里觀察到的新老版本的 pod 副本數(shù)的變化情況如下:成都服務(wù)器托管
應(yīng)用的升級(jí)并不總會(huì)一帆風(fēng)順,在升級(jí)過(guò)程中或升級(jí)完成后都有可能遇到新版本行為不符合預(yù)期需要回滾到穩(wěn)定版本的情況。k8s 會(huì)將 podtemplatespec 的每一次變更(如果更新模板標(biāo)簽或容器鏡像)都記錄下來(lái)。這樣,如果新版本出現(xiàn)問(wèn)題,就可以根據(jù)版本號(hào)方便地回滾到穩(wěn)定版本?;貪L deployment 的詳細(xì)操作步驟可參考文檔rolling back a deployment。
statefulset 是針對(duì)有狀態(tài) pod 常用的部署形式。針對(duì)這類(lèi) pod,k8s 同樣提供了許多參數(shù)用于靈活地控制它們的升級(jí)行為。好消息是這些參數(shù)大部分都和升級(jí) deployment 中的 pod 相同。這里重點(diǎn)介紹兩者存在差異的地方。
在 k8s 1.7 及之后的版本中,statefulset 支持 ondelete 和 rollingupdate 兩種策略類(lèi)型。
可以通過(guò)參數(shù).spec.updatestrategy.rollingupdate.partition
實(shí)現(xiàn)只升級(jí)部分 pod 的目的。在配置了 partition 后,只有序號(hào)大于或等于 partition 的 pod 才會(huì)進(jìn)行滾動(dòng)升級(jí),其余 pod 將保持不變。
partition 的另一個(gè)應(yīng)用是可以通過(guò)不斷減少 partition 的取值實(shí)現(xiàn)金絲雀升級(jí)。具體操作方法可參考文檔rolling out a canary。
daemonset 保證在全部(或者一些)k8s 工作節(jié)點(diǎn)上運(yùn)行一個(gè) pod 的副本,常用來(lái)運(yùn)行監(jiān)控或日志收集程序。對(duì)于 daemonset 中的 pod,用于控制它們升級(jí)行為的參數(shù)與 deployment 幾乎一致,只是在策略類(lèi)型方面略有差異。daemonset 支持 ondelete 和 rollingupdate 兩種策略類(lèi)型。
滾動(dòng)更新 daemonset 的具體操作步驟可參考文檔perform a rolling update on a daemonset。
deployment、statefulset、daemonset 一般用于部署運(yùn)行常駐進(jìn)程,而 job 中的 pod 在執(zhí)行完特定任務(wù)后就會(huì)退出,因此不存在滾動(dòng)更新的概念。當(dāng)您更改了一個(gè) job 中的 podtemplatespec 后,需要手動(dòng)刪掉老的 job 和 pod,并以新的配置重新運(yùn)行該 job。
k8s 提供的功能可以讓大部分應(yīng)用實(shí)現(xiàn)零宕機(jī)時(shí)間和無(wú)生產(chǎn)中斷的升級(jí),但也存在一些沒(méi)有解決的問(wèn)題,主要包括以下幾點(diǎn):成都服務(wù)器托管
實(shí)例配置:成都服務(wù)器托管
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | livenessprobe: failurethreshold: 3 httpget: path: /user/service/test port: 8080 scheme: http initialdelayseconds: 40 periodseconds: 20 successthreshold: 1 timeoutseconds: 1 name: dataline-dev ports: - containerport: 8080 protocol: tcp readinessprobe: failurethreshold: 1 httpget: path: /user/service/test port: 8080 scheme: http initialdelayseconds: 30 periodseconds: 10 successthreshold: 1 timeoutseconds: 1 |
經(jīng)測(cè)試 , 再對(duì)sprintboot 應(yīng)用進(jìn)行更新時(shí), 訪問(wèn)不再出現(xiàn)502的報(bào)錯(cuò)。
更多關(guān)于阿里云k8s服務(wù)springboot項(xiàng)目應(yīng)用升級(jí)時(shí)出現(xiàn)502錯(cuò)誤技術(shù)文章請(qǐng)查看下面的相關(guān)鏈接
原文鏈接:https://www.cnblogs.com/weifeng1463/p/10431736.html