騰訊會(huì)議,一款提供靈活協(xié)作的線上會(huì)議解決方案。其中大量的模塊是有狀態(tài)服務(wù),在使用Kubernetes為其進(jìn)行容器化部署時(shí),Pod升級(jí)需保持共享內(nèi)存、長(zhǎng)連接服務(wù)。升級(jí)時(shí)只容忍ms級(jí)抖動(dòng),需提供大規(guī)模分批灰度發(fā)布、業(yè)務(wù)配額控制等能力,并同時(shí)解決集群節(jié)點(diǎn)負(fù)載不均衡、上萬(wàn)Pods的Workload的HPA性能差等問(wèn)題。這里將向大家介紹TKEx容器平臺(tái)及其在灰度發(fā)布、資源管理、彈性伸縮等方面的能力。
海量規(guī)模下Kubernetes面臨的挑戰(zhàn)
在騰訊自研業(yè)務(wù)中,已經(jīng)有幾百萬(wàn)核跑在Kubernetes上,要在如此體量的容器場(chǎng)景提供可靠穩(wěn)定的容器服務(wù),無(wú)論在底層、集群能力、運(yùn)營(yíng)或運(yùn)維等各個(gè)方面都面臨巨大挑戰(zhàn)。
1.我們?cè)趺催M(jìn)行容器可靠高性能的灰度發(fā)布?尤其是在自研業(yè)務(wù)里面,大量的服務(wù)是有狀態(tài)的服務(wù),原生的Kubernetes StatefulSet已經(jīng)無(wú)法滿足我們?nèi)绱舜笠?guī)模的容器發(fā)布需求。
2.調(diào)度層面需要做哪些優(yōu)化,從而保證在Pod漂移和重調(diào)度的過(guò)程中保證業(yè)務(wù)的穩(wěn)定性。
3.在優(yōu)化資源編排性能方面,如何在整個(gè)平臺(tái)層面和業(yè)務(wù)層面做好后臺(tái)管理。
4.在大規(guī)模的彈性伸縮方面如何提供高性能和全面的彈性伸縮能力。
TKEx容器平臺(tái)簡(jiǎn)介
TKEx容器平臺(tái)的底層基于騰訊公有云的TKE和EKS兩個(gè)產(chǎn)品,它是使用Kubernetes原生的技術(shù)手段服務(wù)于騰訊內(nèi)部的業(yè)務(wù),包括騰訊會(huì)議、騰訊課堂、QQ及騰訊看點(diǎn)等。TKEx在灰度發(fā)布、服務(wù)路由、彈性伸縮、容器調(diào)度、資源管理、多集群管理、業(yè)務(wù)容災(zāi)、在離線混部等方面做了大量工作,比如:
1.通過(guò)Kubernetes API/Contoller/Operator的原生方式適配騰訊內(nèi)部各種系統(tǒng),比如服務(wù)路由系統(tǒng)、CMDB、CI、安全平臺(tái)等。
2.通過(guò)聲明式的方式,對(duì)所有的托管業(yè)務(wù)進(jìn)行生命周期管理。
3.支持在線業(yè)務(wù)、大數(shù)據(jù)、AI等類型作業(yè)。
4.實(shí)現(xiàn)在線業(yè)務(wù)和離線業(yè)務(wù)的混合部署,同時(shí)提升整個(gè)資源的利用率。
5.通過(guò)優(yōu)化linux的內(nèi)核,增強(qiáng)資源底層隔離能力。
6.集成Tencent Cloud Mesh(TCM)服務(wù)為自研業(yè)務(wù)提供ServiceMesh服務(wù)。
7.在大規(guī)模的集群里面,對(duì)彈性伸縮的各種組件進(jìn)行改造和優(yōu)化,以保證它的性能和可用性。
8.基于業(yè)務(wù)產(chǎn)品維度,提供多租戶和配額管理能力。
下面是TKEx平臺(tái)縮略版的架構(gòu)圖,僅包括本次討論的相關(guān)能力。
1.底層基于TKE和EKS兩個(gè)產(chǎn)品,在上層服務(wù)于在線業(yè)務(wù)、AI訓(xùn)練以及大數(shù)據(jù)作業(yè)。
2.中間這四個(gè)框主要包括在應(yīng)用和路由管理、資源編排調(diào)度、彈性伸縮、混部。下面會(huì)重點(diǎn)介紹其中前三個(gè)部分。
高效穩(wěn)定的發(fā)布能力
業(yè)務(wù)沒(méi)有大規(guī)模使用StatefulSet的滾動(dòng)更新能力,對(duì)于有狀態(tài)服務(wù)來(lái)說(shuō),原生的滾動(dòng)更新機(jī)制的發(fā)布可控性太差,對(duì)于multi-zone容災(zāi)部署的業(yè)務(wù)更是很難做精細(xì)化的發(fā)布策略。我們提供了分批灰度發(fā)布策略供有狀態(tài)服務(wù)使用,約80%的Workload都選擇了這種策略。
以一個(gè)業(yè)務(wù)分兩批進(jìn)行發(fā)布為例,第一批升級(jí)兩個(gè)Pod,用戶可以指定是哪兩個(gè)Pod,也可以按照一定比例指定第一批是10%,由平臺(tái)自動(dòng)選擇10%的Pod進(jìn)行灰度,剩余Pods在第二批進(jìn)行灰度。
·自動(dòng)分批機(jī)制:如果Pod的探針完善且能真實(shí)反映業(yè)務(wù)是否可用,用戶可以使用自動(dòng)分批機(jī)制,上一批次完成后可通過(guò)自定義的批次時(shí)間間隔和健康檢查機(jī)制自動(dòng)進(jìn)行下一批的灰度發(fā)布或者自動(dòng)回滾。
·手動(dòng)分批機(jī)制:用戶也可以通過(guò)手動(dòng)分批機(jī)制,在上一批次灰度完成后,可人為在業(yè)務(wù)層面確認(rèn)上一批的灰度是否成功,來(lái)決定是否觸發(fā)下一批灰度還是回滾。
分批灰度發(fā)布更安全、更可靠、更可控的特性,整個(gè)發(fā)布過(guò)程更靈活。由于單個(gè)批次內(nèi)所有選中Pods的更新都是并發(fā)的,因此可以應(yīng)付緊急快速發(fā)布的需求。
StatefulSetPlus是我們用來(lái)實(shí)現(xiàn)分批灰度發(fā)布的CRD,它繼承了Kubernetes原生的StatefulSet的所有能力,并在此之上新增和優(yōu)化了大量特性。StatefulSetPlus主要提供的核心特性包括自動(dòng)的以及手動(dòng)的分批灰度發(fā)布,在發(fā)布異常時(shí)可以進(jìn)行全量一次回滾或者分批次的回滾。Pod更新的策略支持兩種形式,一種是Pod重建的方式,另一種是Pod的原地升級(jí)方式。同時(shí)我們還提供了一些高級(jí)特性,比如:
1.支持Pod升級(jí)過(guò)程中保持Pod使用的共享內(nèi)存數(shù)據(jù)不丟失,這個(gè)特性非常適合于像騰訊會(huì)議這樣的音視頻業(yè)務(wù)。
2.如果升級(jí)過(guò)程中觸發(fā)了Workload的擴(kuò)容,那么擴(kuò)容的時(shí)候會(huì)使用上一個(gè)好的版本進(jìn)行擴(kuò)容,而不是像原生的StatefulSet和Deployment一樣,使用最新的鏡像進(jìn)行擴(kuò)容。因?yàn)樽钚碌溺R像版本有可能是不可用的,擴(kuò)容出來(lái)的Pod可服務(wù)型存在風(fēng)險(xiǎn)。
3.在存儲(chǔ)編排方面,我們繼承了StatefulSet的Per Pod Per PV的特性,同時(shí)也支持Per Workload Per PV的特性,即單個(gè)StatefulSetPlus下面所有的Pod共享一個(gè)PV,也就是類似Deployment共享PV的模式。
4.在StatefulSet里面,當(dāng)節(jié)點(diǎn)出現(xiàn)異常,比如出現(xiàn)了NodeLost的情況下,出于有狀態(tài)服務(wù)的可用性考慮,不會(huì)進(jìn)行Pod重建。在StatefulSetPlus中,監(jiān)聽(tīng)到NodeLost后,對(duì)應(yīng)的Pod會(huì)自動(dòng)漂移。這還不夠,我們會(huì)通過(guò)NPD檢測(cè),上報(bào)事件或Patch Condition快速發(fā)現(xiàn)節(jié)點(diǎn)異常,對(duì)StatefulSetPlus Pod進(jìn)行原地重建或者漂移等決策。
5.StatefulSetPlus還有一個(gè)非常重要的特性,就是它支持ConfigMap的版本管理以及ConfigMap的分批灰度發(fā)布,這是決定ConfigMap能否大規(guī)模在生產(chǎn)中使用的關(guān)鍵能力。
這里特別介紹一下,如何支持Pod升級(jí)過(guò)程中保持共享內(nèi)存數(shù)據(jù)不丟失,并且在升級(jí)過(guò)程中,單個(gè)Pod只有毫秒級(jí)的服務(wù)抖動(dòng)。主要的實(shí)現(xiàn)原理就是在Pod里面,通過(guò)一個(gè)占位容器和業(yè)務(wù)容器進(jìn)行文件鎖的搶占動(dòng)作,來(lái)實(shí)現(xiàn)升級(jí)過(guò)程中兩個(gè)容器的角色進(jìn)行快速切換。
動(dòng)態(tài)的資源調(diào)度和管理
kubernetes的調(diào)度原生是使用靜態(tài)調(diào)度的方式,在生產(chǎn)環(huán)境會(huì)出現(xiàn)集群里面各個(gè)節(jié)點(diǎn)的負(fù)載不均衡的情況,并且造成很大的資源浪費(fèi)。
動(dòng)態(tài)調(diào)度器是我們自研的一個(gè)調(diào)度器擴(kuò)展器,主要任務(wù)是平衡集群中各個(gè)節(jié)點(diǎn)真實(shí)的負(fù)載,在調(diào)度的時(shí)候,將各個(gè)節(jié)點(diǎn)的真實(shí)負(fù)載納入考量的范疇。
動(dòng)態(tài)調(diào)度器必須要解決的一個(gè)技術(shù)點(diǎn)是調(diào)度熱點(diǎn)的問(wèn)題。當(dāng)集群中有一批節(jié)點(diǎn)負(fù)載比較低,這時(shí)用戶創(chuàng)建大量的Pod,這些Pod會(huì)集中調(diào)度到這些低負(fù)載的節(jié)點(diǎn)上面,這將導(dǎo)致這些低負(fù)載節(jié)點(diǎn)在幾分鐘之后又會(huì)成為高負(fù)載節(jié)點(diǎn),從而影響這批節(jié)點(diǎn)上Pod的服務(wù)質(zhì)量,這種現(xiàn)象尤其在集群擴(kuò)容后很容易出現(xiàn)。我們自研的調(diào)度熱點(diǎn)規(guī)避算法,極大的避免了某個(gè)節(jié)點(diǎn)因?yàn)榈拓?fù)載被動(dòng)態(tài)調(diào)度器調(diào)度后成為延遲性的高負(fù)載熱點(diǎn),極少數(shù)高負(fù)載節(jié)點(diǎn)在de-scheduler中會(huì)基于Node CPU的歷史監(jiān)控進(jìn)行節(jié)點(diǎn)降熱操作。
我們希望能夠快速地感知集群的異常情況,包括kubelet異常、docker異常、內(nèi)核死鎖以及節(jié)點(diǎn)是否出現(xiàn)文件描述符即將耗盡的情況,從而能在第一時(shí)間去做決策,避免問(wèn)題的惡化。其中快速發(fā)現(xiàn)這個(gè)動(dòng)作是由Node Problem Detector(NPD)組件負(fù)責(zé)的,NPD組件是基于社區(qū)的NPD進(jìn)行了大量的策略擴(kuò)展。
NPD檢測(cè)到異常后,除了NPD組件本身對(duì)節(jié)點(diǎn)自愈的動(dòng)作之外,de-scheduler還會(huì)基于異常事件和當(dāng)前集群/Workload現(xiàn)狀協(xié)助進(jìn)行動(dòng)作決策,比如Pod驅(qū)逐、Container原地重啟。這里要重點(diǎn)提一下,我們基于Self算法的分布式的Ping檢測(cè),能夠快速發(fā)現(xiàn)節(jié)點(diǎn)的網(wǎng)絡(luò)異常情況,由de-scheduler對(duì)網(wǎng)絡(luò)異常節(jié)點(diǎn)上的Pods進(jìn)行漂移。
在騰訊內(nèi)部,產(chǎn)品的管理是分多個(gè)層級(jí)的,因此在配額管理方面,我們沒(méi)有使用Kubernetes原生的ResourceQuota機(jī)制,而是研發(fā)了DynamicQuota CRD來(lái)實(shí)現(xiàn)多層級(jí)的、動(dòng)態(tài)的面向業(yè)務(wù)的Quota管理。
比如從業(yè)務(wù)維度,騰訊會(huì)議是一個(gè)產(chǎn)品,騰訊課堂是一個(gè)產(chǎn)品,每個(gè)產(chǎn)品下面都會(huì)有多級(jí)業(yè)務(wù)模塊,在做資源規(guī)劃和配額管理的時(shí)候,是基于產(chǎn)品維度的。在實(shí)際部署的時(shí)候,實(shí)際上Workload綁定到對(duì)應(yīng)的CMDB的最后一級(jí)模塊。所以,這里需要自動(dòng)的將產(chǎn)品配額下發(fā)到CMDB多級(jí)模塊的機(jī)制,通過(guò)DynamicQuota不只是做資源使用上限的控制,更重要的是保證這個(gè)業(yè)務(wù)有這么多配額可以用,防止被其他業(yè)務(wù)搶占了。
當(dāng)然這里還有一些關(guān)鍵問(wèn)題,比如為了避免資源浪費(fèi),我們需要把一些產(chǎn)品的空閑資源借調(diào)給其他已經(jīng)超過(guò)配額控制但是需要繼續(xù)使用更多資源的業(yè)務(wù),這樣配額就有了靈活的彈性。
同時(shí)我們也利用了DynamicQuota控制在線業(yè)務(wù)和離線業(yè)務(wù)占用資源的比例,主要是為了保證在線業(yè)務(wù)始終會(huì)有一定的配額可以使用,防止離線業(yè)務(wù)無(wú)限制侵占整個(gè)平臺(tái)的資源,同時(shí)也能更好的控制集群負(fù)載。
大規(guī)模和高性能的彈性伸縮
在擴(kuò)縮容方面,這里主要介紹縱向擴(kuò)縮容和橫向擴(kuò)縮容做的工作。社區(qū)的VPA不太適合很多騰訊的自研業(yè)務(wù),因?yàn)閿U(kuò)縮容都是基于Pod的重建機(jī)制,在擴(kuò)容效果和對(duì)業(yè)務(wù)的感知方面,都不是很好。
我們自研了Vertical Workload AutoScaler(VWA)CRD用于Pod的垂直擴(kuò)縮容,主要解決的問(wèn)題是:
1.當(dāng)業(yè)務(wù)出現(xiàn)突發(fā)流量的時(shí)候,HPA擴(kuò)容不及時(shí),導(dǎo)致下面Pod的資源利用率暴漲,進(jìn)而引發(fā)業(yè)務(wù)的雪崩。VWA有更快的響應(yīng)速度,并且不需要重建Pod,因此比HPA更快更安全。
2.業(yè)務(wù)在使用容器規(guī)格的時(shí)候,經(jīng)常把容器規(guī)格配置得比較高,Pod資源使用率會(huì)比較低,通過(guò)VWA自動(dòng)進(jìn)行降配,優(yōu)化資源利用率。
3.當(dāng)節(jié)點(diǎn)出現(xiàn)高負(fù)載的情況下,這個(gè)節(jié)點(diǎn)上面跑著在線和離線業(yè)務(wù),我們會(huì)通過(guò)VWA快速地對(duì)離線業(yè)務(wù)容器進(jìn)行在線降配,從而保證在線業(yè)務(wù)的服務(wù)質(zhì)量。
這里面核心的特性,包括提供原地升級(jí)容器規(guī)格的能力,而不需要重建Container,性能上做了優(yōu)化,單集群能支持上千個(gè)VWA對(duì)象的擴(kuò)縮容。同時(shí)也支持VWA的個(gè)性化配置,比如可以配置每一個(gè)VWA對(duì)象的循環(huán)同步周期,每次擴(kuò)容的最大比例以及縮容的最大比例等。
最后再介紹一下在HPA方面我們做的工作。Kubernetes原生的HPA Controller是內(nèi)置在kube-controller-manager里面的,它存在著以下缺陷:
1.它不能獨(dú)立部署,如果集群中有成千上萬(wàn)的HPA對(duì)象,原生HPA Controller是很難承受的,穩(wěn)定性也直接受限于kube-controller-manager。
2.另外在性能方面,原生HPA Controller在一個(gè)協(xié)程里面遍歷所有HPA對(duì)象,所以在大規(guī)模HPA場(chǎng)景下,同步實(shí)時(shí)性得不到保證。
我們自研了一個(gè)HPAPlus Controller,它兼容了原生的HPA對(duì)象,然后可以獨(dú)立部署,在性能方面類似VWA一樣做了很多性能優(yōu)化,同時(shí)豐富了每個(gè)HPA對(duì)象可自定義的配置,比如同步周期、擴(kuò)容比例、容忍度等。
HPAPlus-Controller還實(shí)現(xiàn)了與CronHPA和VWA進(jìn)行聯(lián)動(dòng)決策,比如當(dāng)VWA持續(xù)擴(kuò)縮容達(dá)到了所屬節(jié)點(diǎn)的上限,無(wú)法繼續(xù)擴(kuò)容的時(shí)候,這個(gè)時(shí)候會(huì)自動(dòng)托管給HPA觸發(fā)橫向擴(kuò)容。
總結(jié)
騰訊自研業(yè)務(wù)海量規(guī)模,除了文中介紹到彈性伸縮、調(diào)度和資源管理、灰度發(fā)布等方面面臨的挑戰(zhàn)外,我們還在多集群管理、在離線混部、ServiceMesh、異構(gòu)計(jì)算、AI/大數(shù)據(jù)框架支持等多方面做了大量工作。另外,TKEx底層正在大量使用EKS彈性容器服務(wù)來(lái)提供更好的容器資源隔離能力、彈性能力,以實(shí)現(xiàn)真正的零集群運(yùn)維成本和高資源利用率的目標(biāo)。
王濤,騰訊云專家工程師,從事Kubernetes容器平臺(tái)的研發(fā)近6年,目前主要負(fù)責(zé)騰訊海量自研業(yè)務(wù)容器化上云的平臺(tái)研發(fā)。在利用云原生技術(shù)構(gòu)建DevOps、ServiceMesh、AI、大數(shù)據(jù)平臺(tái)等場(chǎng)景有豐富經(jīng)驗(yàn)。