【云原生系列-K8s】- Cluster Autoscaler模塊及對應(yīng)華為云插件Deep Dive

      網(wǎng)友投稿 808 2025-03-31

      背景信息

      基于業(yè)務(wù)團(tuán)隊(duì)(Cloud BU 應(yīng)用平臺)在開發(fā)Serverless引擎框架的過程中完成的K8s Cluster Autoscaler華為云插件。 目前該插件已經(jīng)貢獻(xiàn)給了K8s開源社區(qū),見下圖:

      本文將會涉及到下述內(nèi)容:

      對K8s Cluster Autoscaler模塊的架構(gòu)和代碼的Deep Dive,尤其是核心功能點(diǎn)的所涉及的算法的介紹。

      K8s Cluster Autoscaler 華為云插件模塊的介紹。

      什么是K8s Cluster Autoscaler (CA)?

      什么是彈性伸縮?

      顧名思義是根據(jù)用戶的業(yè)務(wù)需求和策略,自動調(diào)整其彈性計(jì)算資源的管理服務(wù),其優(yōu)勢有:

      從應(yīng)用開發(fā)者的角度:能夠讓應(yīng)用程序開發(fā)者專注實(shí)現(xiàn)業(yè)務(wù)功能,無需過多考慮系統(tǒng)層資源

      從系統(tǒng)運(yùn)維者的角度:極大的降低運(yùn)維負(fù)擔(dān), 如果系統(tǒng)設(shè)計(jì)合理可以實(shí)現(xiàn)“零運(yùn)維”

      是實(shí)現(xiàn)Serverless架構(gòu)的基石,也是Serverless的主要特性之一

      在具體解釋CA概念之前,咋們先從宏觀上了解一下K8s所支持的幾種彈性伸縮方式(CA只是其中的一種)。

      VPA (Vertical Pod Autoscaler)

      A set of components that automatically adjust the amount of CPU and memory requested by Pods running in the Kubernetes Cluster. Current state - beta.

      簡而言之:?對于某一個(gè)POD,對其進(jìn)行擴(kuò)縮容(由于使用場景不多,不做過多介紹)

      HPA(Horizontal Pod Autoscaler)?- Pod級別伸縮

      A component that scales the number of pods in a replication controller, deployment, replica set or stateful set based on observed CPU utilization (or, with beta support, on some other, application-provided metrics).

      簡而言之:?對于某一Node, 根據(jù)預(yù)先設(shè)置的伸縮策略(如CPU, Memory使用率某設(shè)定的閥值),增加/刪減其中的Pods。

      HPA伸縮策略:

      HPA依賴metrics-server組件收集Pod上metrics, 然后根據(jù)預(yù)先設(shè)定的伸縮策略(如:CPU使用率大于50%),來決定擴(kuò)縮容Pods。計(jì)算CPU/Memory使用率時(shí),是取所有Pods的平均值。關(guān)于具體如何計(jì)算的,點(diǎn)擊此處有詳細(xì)算法介紹。

      注:metrics-server默認(rèn)只支持基于cpu和memory監(jiān)控指標(biāo)伸縮策略

      HPA架構(gòu)圖:

      圖中下半部門Prometheus監(jiān)控系統(tǒng)和K8s Prometheus Adapter組件的引入是為了能夠使用自定義的metrics來設(shè)置伸縮策略,由于不是本文的重點(diǎn),這里不做過多介紹,?K8s官方文檔有個(gè)Walkthrough案例一步一步在實(shí)操中掌握和理解該模塊。如果用戶只需要依據(jù)cpu/memory的監(jiān)控指標(biāo)來設(shè)置伸縮策略,只要deploy默認(rèn)的metrics-server組件(其安裝對K8s來說就是一次deployment,非常方便, 上面的鏈接里有安裝步驟)

      CA (Cluster Autoscaler)- Node級別伸縮

      A component that automatically adjusts the size of a Kubernetes Cluster so that: all pods have a place to run and there are no unneeded nodes.

      簡而言之:?對于K8S集群,增加/刪除其中的Nodes,達(dá)到集群擴(kuò)縮容的目的。

      Kubernetes(K8s) Cluster Autoscaler(CA)模塊源碼解析:

      前面做了這么多鋪墊,是時(shí)候切入本文主題了。下面我將主要從架構(gòu)和代碼兩個(gè)維度來揭開CA模塊的神秘面紗,并配合FAQ的形式解答常見的問題。

      【云原生系列-K8s】- Cluster Autoscaler模塊及對應(yīng)華為云插件Deep Dive

      CA整體架構(gòu)及所含子模塊

      如上圖所示, CA模塊包含以下幾個(gè)子模塊,?詳見K8S CA模塊在Github的源碼:

      autoscaler: 核心模塊,包含核心Scale Up和Scale Down功能(對應(yīng)Github里?core?Package)。

      在擴(kuò)容時(shí)候:其ScaleUp函數(shù)會調(diào)用estimator模塊來評估所需節(jié)點(diǎn)數(shù)

      在縮容時(shí):其ScaleDown函數(shù)會調(diào)用simulator模塊來評估縮容的節(jié)點(diǎn)數(shù)

      estimator: 負(fù)責(zé)計(jì)算擴(kuò)容需要多少Node (對應(yīng)Github里?estimator?Package)

      simulator: 負(fù)責(zé)模擬調(diào)度,計(jì)算縮容節(jié)點(diǎn) (對應(yīng)Github里?simulator?Package)

      expander: 負(fù)責(zé)擴(kuò)容時(shí),選擇合適的Node的算法 (對應(yīng)Github里?expander?Package),可以增加或定制化自己的算法

      cloudprovider: CA模塊提供給具體云提供商的接口 (對應(yīng)Github里cloudprovider?Package)。關(guān)于這個(gè)子模塊后面也會著重介紹,也是我們?nèi)A為云cloudprovider的擴(kuò)展點(diǎn)。

      autoscaler通過該模塊與具體云提供商對接(如上圖右下角方框所示 AWS, GCE等云提供商),并可以調(diào)度每個(gè)云提供商提供的Node.

      cloudprovider預(yù)先設(shè)定了一些列接口,供具體的云提供商實(shí)現(xiàn),來完成調(diào)度其提供的Node的目的

      通過對K8s CA模塊的架構(gòu)和源碼的織結(jié)構(gòu)的介紹,我總結(jié)有以下幾點(diǎn)最佳實(shí)踐值得學(xué)習(xí)和借鑒, 可以適用在任何編程語言上:

      SOLID設(shè)計(jì)原則無處不在,具體反映在:

      每個(gè)子模塊僅負(fù)責(zé)解決某一特定問題 - 單一職責(zé)

      每個(gè)子模塊都預(yù)留有擴(kuò)展點(diǎn) - 開閉原則

      每個(gè)子模塊的接口隔離做的很清晰 - 接口分離原則

      清晰的子模塊包的組織結(jié)構(gòu)

      插件式的擴(kuò)展點(diǎn)設(shè)計(jì)

      關(guān)于CA模塊的用戶常見問題

      CA和k8s其他彈性伸縮方式的關(guān)系?

      VPA更新已經(jīng)存在的Pod使用的resources

      HPA更新已經(jīng)存在的Pod副本數(shù)

      如果沒有足夠的節(jié)點(diǎn)在可伸縮性事件后運(yùn)行POD,則CA會擴(kuò)容新的Node到集群中,之前處于Pending狀態(tài)的Pods將會被調(diào)度到被新管理的node上

      CA何時(shí)調(diào)整K8S集群大小?

      何時(shí)擴(kuò)容: 當(dāng)資源不足,Pod調(diào)度失敗,即存在一直處于Pending狀態(tài)的Pod(見下頁流程圖), 從Cloud Provider處添加NODE到集群中

      何時(shí)縮容: Node的資源利用率較低,且Node上存在Pod都能被重新調(diào)度到其它Node上去

      CA多久檢查一次Pods的狀態(tài)?

      CA每隔10s檢查是否有處于pending狀態(tài)的Pods

      如何控制某些Node不被CA在縮容時(shí)刪除?

      Node上有Pod被PodDisruptionBudget控制器限制。PodDisruptionBudgetSpec

      Node上有命名空間是kube-system的Pods。

      Node上Pod被Evict之后無處安放,即沒有其他合適的Node能調(diào)度這個(gè)pod

      Node有annotation: “cluster-autoscaler.kubernetes.io/scale-down-disabled”: “true”

      Node上存有如下annotation的Pod:“cluster-autoscaler.kubernetes.io/safe-to-evict”: “false”.點(diǎn)擊見詳情

      若想更進(jìn)一步了解和學(xué)習(xí),請點(diǎn)擊這里查看更完整的常見問題列表及解答。

      CA模塊源碼解析

      由于篇幅關(guān)系,只對核心子模塊深入介紹,通過結(jié)合核心子模塊與其他子模塊之間如何協(xié)調(diào)和合作的方式順帶介紹一下其他的子模塊。

      程序啟動入口處:?kubernetes/autoscaler/cluster-autoscaler/main.go

      如上圖所示,autoscaler.go是接口,其默認(rèn)的實(shí)現(xiàn)是static_autoscaler.go, 該實(shí)現(xiàn)會分別調(diào)用scale_down.go和scale_up.go里的ScaleDown以及ScaleUp函數(shù)來完成擴(kuò)縮容。

      那么問題來了,合適ScaleUp和ScaleDown方法會被調(diào)用呢,咋們按照順序一步一步來捋一下, 回到CA整體入口,那里有一個(gè)RunOnce(在autoscaler接口的默認(rèn)實(shí)現(xiàn)static_autoscaler.go里)方法,會啟動一個(gè)Loop 一直運(yùn)行l(wèi)isten和watch系統(tǒng)里面是否有那些處于pending狀態(tài)的Pods(i.e. 需要協(xié)助找到Node的Pods), 如下面代碼片段(static_autoscaler.go里的RunOnce函數(shù))所示, 值得注意的是,在實(shí)際調(diào)用ScaleUp之前會有幾個(gè) if/else 判斷是否符合特定的條件:

      對于ScaleDown函數(shù)的調(diào)用,同理,也在RunOnce函數(shù)里, ScaleDown主要邏輯是遵循如下幾步:

      找出潛在的利用率低的Nodes (即代碼里的scaleDownCandidates數(shù)組變量)

      然后為Nodes里的Pods找到“下家”(即可以被安放的Nodes,對應(yīng)代碼里的podDestinations數(shù)組變量)

      然后就是下面截圖所示,幾個(gè)if/else判斷符合ScaleDown條件,就執(zhí)行TryToScaleDown函數(shù)

      通過上面的介紹結(jié)合代碼片段,我們了解到何時(shí)ScaleUp/ScaleDown函數(shù)會被調(diào)用。接下來,我們來看看當(dāng)這兩個(gè)核心函數(shù)被調(diào)用時(shí),里面具體都發(fā)生了什么。

      先來看一下ScaleUp:

      從上圖代碼片段,以及我里面標(biāo)注的注釋,可以看到,這里發(fā)生了下面幾件事:

      通過cloudprovider子模塊(下面專門介紹這個(gè)子模塊)從具體云提供商處獲取可以進(jìn)行擴(kuò)容的的NodeGroups

      把那些Unschedulable Pods按照擴(kuò)容需求進(jìn)行分組(對應(yīng)上面代碼里的對buildPodEquivalenceGroups函數(shù)的調(diào)用)

      把第1步得到的所有可用的NodeGroups和第2步得到的待分配的Pods, 作為輸入,送入給estimator子模塊的裝箱算法(該調(diào)用發(fā)生對上圖中computeExpansionOption函數(shù)調(diào)用內(nèi)部)?,得到一些候選的Pods調(diào)度/分配方案。由于estimator子模塊的核心就是裝箱算法,下圖就是實(shí)現(xiàn)了裝箱算法的Estimate函數(shù),這里實(shí)現(xiàn)有個(gè)小技巧,就是算法開始之前,先調(diào)用calculatePodScore把兩維問題降為一維問題(即Pod對CPU和Memory的需求),然后就是傳統(tǒng)的裝箱算法,兩個(gè)for loop來給 Pods找到合適的Node. 至于具體如何降維的,詳見binpacking.estimator.go里的calculatePodScore函數(shù)源碼。

      把第3步得到的一些方案,送入給?expander子模塊,得到最優(yōu)的分配方案(對應(yīng)代碼片段中ExpanderStrategy.BestOption的函數(shù)調(diào)用)expander提供了下面截圖中的集中策略,用戶可以通過實(shí)現(xiàn)expander接口的BestOption函數(shù),來實(shí)現(xiàn)自己的expander策略

      與具體的云提供商(i.e. AWS, GCP, Azure, Huawei Cloud)對接來對對應(yīng)云平臺上的Node Group(有的云平臺叫Node Pool)里的Node進(jìn)行增刪操作已達(dá)到擴(kuò)縮容的目的。其代碼對應(yīng)于與之同名的cloudprovider package。詳見Github代碼。 沒個(gè)云提供商,都需要按照k8s約定的方式進(jìn)行擴(kuò)展,開發(fā)自家的cloudprovider插件,如下圖:

      下文會專門介紹華為云如何擴(kuò)展該模塊的

      華為云cloudprovider插件開發(fā)及開源貢獻(xiàn)心得

      華為云cloudprovider插件如何擴(kuò)展和開發(fā)的?

      下圖是華為cloudprovider插件的大致的代碼結(jié)構(gòu), 綠色框里是SDK實(shí)際是對CCE(云容器引擎 CCE)?進(jìn)行必要操作所需要的 (對Node Pool/Group里的Node 進(jìn)行增加和刪除)。 按理說我們不需要自己寫這一部分,不過由于咋們云CCE 團(tuán)隊(duì)的SDK實(shí)在是不完善,所以我們開發(fā)了一些必要的對CCE進(jìn)行操作的SDK。重點(diǎn)是紅色框中的代碼:

      huaweicloud_cloud_provider.go是入口處,其負(fù)責(zé)總huaweicloud_cloud_config.go讀取配置,并實(shí)例化huaweicloud_manager.go對象。huaweicloud_manager.go對象里通過調(diào)用藍(lán)色框部門里的CCE SDK來獲取CCE整體的信息。 CCE整體的信息被獲取到后,可以調(diào)用huaweicloud_node_group.go 來完成對該CCE綁定的Node Group/Pool進(jìn)行Node的擴(kuò)縮容已達(dá)到對整體CCE的Node伸縮。

      如何從開源社區(qū)獲取所需資源及開源過程中需要注意的點(diǎn)?

      我剛開始接受該項(xiàng)目的時(shí)候,一頭霧水,不知道該如何下手。K8s關(guān)于這一塊的文檔寫的又不是很清楚。以往的經(jīng)驗(yàn)以及K8s Github README中提供的信息,我加入他們的Slack組織,找到相應(yīng)的興趣組channel( 對應(yīng)我的情況就是sig-autoscaling channel),提出了我的問題(如下面截圖)。 基于K8s代碼倉的大小,如果沒找到合適的擴(kuò)展點(diǎn),幾乎無法改動和擴(kuò)展的。

      劃重點(diǎn): 現(xiàn)在幾乎所有的開源組中都有Slack群組,加入找到相應(yīng)的興趣組,里面大牛很多,提出問題,一般會有人熱心解答的。 郵件列表也可以,不過我認(rèn)為Slack高效實(shí)時(shí)一點(diǎn),強(qiáng)烈推薦。對于我本人平常接觸到的開源項(xiàng)目,我一般都會加入到其 Slack中,有問題隨時(shí)提問。 當(dāng)然,中國貢獻(xiàn)的開源項(xiàng)目,好多以微信群的方式溝通 :)譬如咋們?nèi)A為開源出去的微服務(wù)框架項(xiàng)目 ServiceComb,我也有加微信群。總之, 對于開源項(xiàng)目,一定要找到高效的和組織溝通的方式。

      另外,對于貢獻(xiàn)代碼過程中,如果使用到了三方開源代碼,由于版權(quán)和二次分發(fā)的問題,盡量避免直接包含三方源代碼, 如果實(shí)在需要,可以對其進(jìn)行擴(kuò)展,并在新擴(kuò)展的文件附上華為的版權(quán)信息與免責(zé)聲明。 關(guān)于公司的具體要求和政策請參閱文件:?對外開源代碼出口自檢標(biāo)準(zhǔn)與指導(dǎo)書?以及?對外開源流程指導(dǎo)

      Kubernetes 華為開源鏡像站 Mirrors 云原生 GitHub

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:Excel表格如何制作分類折線圖(excel表格怎樣做折線圖)
      下一篇:如何在Excel中選擇最高或最低值?
      相關(guān)文章
      亚洲日韩看片无码电影| 国产亚洲玖玖玖在线观看| 日韩亚洲国产二区| 亚洲精品二三区伊人久久| 亚洲熟妇无码爱v在线观看| 亚洲视频中文字幕| 久久亚洲精品人成综合网| 亚洲综合精品香蕉久久网97| 亚洲AV无码成人精品区在线观看| 亚洲色欲色欲www在线丝| 亚洲无人区一区二区三区| 亚洲色偷拍另类无码专区| 亚洲色婷婷六月亚洲婷婷6月| 91麻豆国产自产在线观看亚洲| 国产亚洲精品不卡在线| 亚洲综合另类小说色区色噜噜| AV在线亚洲男人的天堂| 亚洲中文字幕无码一久久区| 一本色道久久综合亚洲精品| 亚洲精品乱码久久久久久久久久久久| 亚洲色婷婷综合久久| 亚洲av永久无码精品网站| 午夜亚洲AV日韩AV无码大全| 亚洲小视频在线观看| 亚洲视频免费一区| wwwxxx亚洲| 亚洲欧美日韩中文高清www777| 亚洲AV无码专区在线观看成人| 精品国产亚洲AV麻豆| 亚洲精品无码你懂的网站| 久久伊人亚洲AV无码网站| 亚洲精品无码高潮喷水在线| 无码乱人伦一区二区亚洲| 亚洲欧洲日产专区| 久久乐国产综合亚洲精品| 久久无码av亚洲精品色午夜| 亚洲日韩涩涩成人午夜私人影院| 国产a v无码专区亚洲av| 亚洲成a人片在线观看日本| 久久亚洲日韩看片无码| 国产精品亚洲精品观看不卡|