Author: xidianwangtao@gmail.comnode
摘要:Kubernetes的資源編排調度使用的是靜態調度,將Pod Request Resource與Node Allocatable Resource進行比較來決定Node是否有足夠資源容納該Pod。靜態調度帶來的問題是,集羣資源很快被業務容器分配完,可是集羣的總體負載很是低,各個節點的負載也不均衡。本文將介紹優化Kubernetes集羣負載的多種技術方案。web
靜態調度,是指根據容器請求的資源進行裝箱調度,而不考慮節點的實際負載。靜態調度最大的優勢就是調度簡單高效、集羣資源管理方便,最大的缺點也很明顯,就是無論節點實際負載,極容易致使集羣負載不高。後端
Kubernetes爲何會使用靜態調度呢?由於要作好通用的動態調度幾乎是不可能的,對,是通用的動態調度很難都知足不一樣企業不一樣業務的訴求,結果可能拔苗助長。那是否是咱們就不必去往動態調度作技術嘗試呢?未必!平臺根據託管的業務屬性,能夠適當的經過scheduler extender的方式擴展Kubernetes Scheduler來作必定權重的動態調度決策。api
以cpu資源爲例,一個大規模Kubernetes集羣的資源組成結構大體以下:性能
由如下幾部分組成:優化
除了藉助強大的容器監控數據作必定權重的動態調度決策以外,是否還有其餘方案能夠用於解決靜態調度帶來的集羣低負載問題呢?下面我將給出一整套技術方案,從多個技術維度來嘗試提高Kubernetes集羣負載。ui
前面提到,研發同窗部署業務選擇容器資源規格時,帶有必定的盲目性,並且Kubernetes原生也不支持實時無感知的修改容器規格(雖然這能夠經過Static VPA方案解決),致使業務容器負載低。爲了解決這個問題,咱們能夠給Pod Request Resource作必定比例的壓縮(Pod Limit Resource不壓縮)。注意壓縮Pod Request Resource只發生在Pod建立或者重建的時候,好比業務作變動發佈之時,對於正常運行中的Pod不能作這一動做,不然可能致使對應Workload Controller重建Pod(取決於Workload的UpdateStrategy)對業務帶來影響。code
須要注意的是:orm
每一個Workload負載變更規律不一樣,所以Pod分配資源壓縮比例也對應不同,須要支持每一個Workload自定義配置,並且這是對用戶無感知的。這個壓縮比,咱們設置到Workload的Annotation中,好比cpu資源壓縮對應Annotation stke.platform/cpu-requests-ratio
;server
壓縮比,誰去設置?自研組件(Pod-Resource-Compress-Ratio-Reconciler)基於Workload的歷史監控數據,動態的/週期性去調整壓縮比。好比某Workload連續7d/1M的負載持續很低,那麼能夠把壓縮比設置的更大,以此讓集羣剩餘可分配資源更大,容納更多的業務容器。固然實際上壓縮比的調整策略並不會這麼簡單,須要更多的監控數據來輔助。
Pod分配壓縮特性必定要是能夠關閉的和恢復的,經過Workload Annotation stke.platform/enable-resource-compress: "n"
針對Workload級別disable,經過設置壓縮比爲1進行壓縮恢復。
什麼時候經過壓縮比去調整Pod Spec中的Request Resource?Kubernetes發展到現階段,直接改Kubernetes代碼是最愚蠢的方式,咱們要充分利用Kubernetes的擴展方式。這裏,咱們經過kube-apiserver的Mutating Admission Webhook
對Pod的Create事件進行攔截,自研webhook(pod-resource-compress-webhook)檢查Pod Annotations中是否enable了壓縮特性,而且配置了壓縮比,若是配置了,則根據壓縮比從新計算該Pod的Request Resource,Patch到APIServer。
Pod資源壓縮方案,是針對每一個Workload級別的資源動態調整方案,優勢是細化到每一個Workload,能作到有的放矢,缺點是業務不作變動發佈,就沒有效果,見效慢。
Node資源超賣方案是針對Node級別的資源動態調整方案,根據每一個節點的真實歷史負載數據,進行不一樣比例的資源超賣。
每一個節點的資源超賣比例,咱們設置到Node的Annotation中,好比cpu超賣對應Annotation stke.platform/cpu-oversale-ratio
。
每一個節點的超賣比例,誰去設置?自研組件(Node-Resource-Oversale-Ratio-Reconciler)基於節點歷史監控數據,動態的/週期性的去調整超賣比例。好比某個Node連續7d/1M持續低負載而且節點已分配資源水位線很高了,那麼能夠把超賣比例適當調高,以此使Node能容納更多的業務Pod。
Node超賣特性必定要是能夠關閉和還原的,經過Node Annotation stke.platform/mutate: "false"
關閉Node超賣,Node在下一個心跳會完成資源復原。
什麼時候經過壓縮比去調整Node Status中的Allocatable&Capacity Resource?一樣的,咱們經過kube-apiserver的Mutating Admission Webhook
對Node的Create和Status Update事件進行攔截,自研webhook(node-resource-oversale-webhook)檢查Node Annotations中是否enable了超賣而且配置了超賣比,若是配置了,則根據安超賣比從新計算該Node的Allocatable&Capacity Resource,Patch到APIServer。
Node資源超賣,表面上看起來很簡單,但實際上要考慮的細節還不少:
Kubelet Register Node To ApiServer的詳細原理是什麼,經過webhook直接Patch Node Status是否可行?
當節點資源超賣後,Kubernetes對應的Cgroup動態調整機制是否能繼續正常工做?
Node status更新太頻繁,每次status update都會觸發webhook,大規模集羣容易對apiserver形成性能問題,怎麼解決?
節點資源超賣對Kubelet Eviction的配置是否也有超配效果,仍是仍然按照實際Node配置和負載進行evict? 若是對Evict有影響,又該如解決?
超賣比例從大往小調低時,存在節點上 Sum(pods' request resource) > node's allocatable
狀況出現,這裏是否有風險,該如何處理?
監控系統對Node的監控與Node Allocatable&Capacity Resource有關,超賣後,意味着監控系統對Node的監控再也不正確,須要作必定程度的修正,如何讓監控系統也能動態的感知超賣比例進行數據和視圖的修正?
Node Allocatable和Capacity分別該如何超賣?超賣對節點預留資源的影響是如何的?
這裏涉及的Kubernetes技術細節比較多,我將在下一篇文章中詳細介紹。
提起Kubernetes的彈性伸縮,你們比較熟悉的是HPA和HNA,一個對Workload的Pod進行橫向伸縮,一個對集羣中Node進行橫向伸縮。社區中還有一個VPA項目,用來對Pod的資源進行調整,可是須要重建Pod才能生效,VPA存在的意義就是要快速擴容,若是像HPA同樣,須要重建Pod啓動應用來擴容,其實已經失去了價值。
Kube-controller-manager內置的HPA-Controller存在如下問題:
性能問題:一個goroutine中循環遍歷集羣中全部的HPA對象,針對每一個HPA對象獲取對應的Pod監控數據、計算新Replicas,這對於大業務是比較耗時的。
核心配置不支持Workload自定義:HPA伸縮響應時間是每一個業務均可能不同的,有些業務指望能5s進行響應,有些業務以爲60s就夠了。而內置HPA Controller在響應時間控制上只能配置全局的啓動參數horizontal-pod-autoscaler-sync-period
。還有每一個業務對負載的抖動容忍是不同的,在內置的HPA Controller中只能經過horizontal-pod-autoscaler-tolerance
作全局配置,沒法提供業務級的自定義。
Kubernetes目前對custom metrics的支持,只能註冊一個後端監控服務,若是集羣中有些業務經過prometheus來expose應用自定義指標,也有一些業務經過Monitor來監控應用自定義指標,這個時候就作不到All in了,這在for自研上雲的場景中,是必定存在的場景。
咱們自研了HPAPlus-Controller組件:
每一個HPA對象會啓動一個goroutine協程專門負責該HPA對象的管理和計算工做,各個協程並行執行,極大的優化了性能。HPAPlus-Controller獨立部署,其資源需求能夠是集羣規模和HPA數量進行合理調整,相比於原內置HPA-Controller有更大的靈活性。
HPAPlus-Controller支持各個HPA對象自定義伸縮響應時間,支持自動感應業務是否在變動發佈並決定是否要禁用HPA(某些業務有這樣的需求:升級時禁止觸發彈性伸縮),支持基於pod resource limit爲基數進行Pod資源利用率計算,從而推導出擴縮容後的指望replicas,這一點對於節點超賣和Pod資源壓縮後的集羣很是重要。
支持業務級別對負載的抖動容忍度的個性化配置。
支持基於更多維度的監控數據進行Scale決策,好比Pod歷史7d/1M的cpu負載。
支持CronHPA,知足規律性擴縮容的業務訴求。
經過Extension APIServer的方式對接公司Monitor監控,保留Prometheus-Adaptor的方式來支持基於Prometheus的應用監控,知足基於多種應用監控系統的custom metrics進行HPA。
注意:HPAPlus-Controller與Kubernetes buit-in HPA-Controller存在功能衝突,上線前須要disable kube-controller-manager的HPA-Controller控制器。
除了HPA的優化和加強以外,咱們也在進行Dynamic VPA技術研發,後續再單獨文章介紹。
另外,經過scheduler extender的方式開發動態調度器、基於業務級的配額動態管理組件、基於業務優先級和配額管理的在線離線業務混部能力、主動探測節點資源碎片信息並上報到控制器進行Pod的再漂移進行資源碎片管理等方案,也是咱們正在進行實踐的方向,對應方案及實現複雜度更高,後續再單獨文章介紹。
本文介紹了Kubernetes靜態調度帶來的集羣資源分配水位線高但集羣實際負載低的問題進行了技術方案上的探討,詳細介紹了Pod資源動態壓縮、節點資源動態超賣、優化AutoScale的能力的技術方案,後面會再對動態調度、動態業務配額管理、在線離線業務混部方案進行介紹。全部這些集羣負載提高方案,要作到動態,都強依賴於強大的容器監控系統。咱們正與騰訊雲監控產品團隊深刻合做,更好的服務於騰訊自研業務上雲。