被集羣節點負載不均所困擾?TKE 重磅推出全鏈路調度解決方案

引言

在 K8s 集羣運營過程當中,經常會被節點 CPU 和內存的高使用率所困擾,既影響了節點上 Pod 的穩定運行,也會增長節點故障的概率。爲了應對集羣節點高負載的問題,平衡各個節點之間的資源使用率,應該基於節點的實際資源利用率監控信息,從如下兩個策略入手:node

  • 在 Pod 調度階段,應當優先將 Pod 調度到資源利用率低的節點上運行,不調度到資源利用率已經很高的節點上
  • 在監控到節點資源率較高時,能夠自動干預,遷移節點上的一些 Pod 到利用率低的節點上

爲此,咱們提供 動態調度器 + Descheduler 的方案來實現,目前在公有云 TKE 集羣內【組件管理】- 【調度】分類下已經提供這兩個插件的安裝入口,文末還針對具體的客戶案例提供了最佳實踐的例子。api

動態調度器

原生的 Kubernetes 調度器有一些很好的調度策略用來應對節點資源分配不均的問題,好比 BalancedResourceAllocation,可是存在一個問題是這樣的資源分配是靜態的,不能表明資源真實使用狀況,節點的 CPU/內存利用率 常常處於不均衡的狀態。因此,須要有一種策略能夠基於節點的實際資源利用率進行調度。動態調度器所作的就是這樣的工做。架構

技術原理

原生 K8s 調度器提供了 scheduler extender 機制來提供調度擴展的能力。相比修改原生 scheduler 代碼添加策略,或者實現一個自定義的調度器,使用 scheduler extender 的方式侵入性更少,實現更加靈活。因此咱們選擇基於 scheduler extender 的方式來添加基於節點的實際資源利用率進行調度的策略。優化

scheduler extender 能夠在原生調度器的預選和優選階段加入自定義的邏輯,提供和原生調度器內部策略一樣的效果。插件

架構

  • node-annotator:負責拉取 Prometheus 中的監控數據,按期同步到 Node 的 annotation 裏面,同時負責其餘邏輯,如動態調度器調度有效性衡量指標,防止調度熱點等邏輯。
  • dynamic-scheduler:負責 scheduler extender 的優選和預選接口邏輯實現,在預選階段過濾掉資源利用率高於閾值的節點,在優選階段優先選擇資源利用率低的節點進行調度。

實現細節

  1. 動態調度器的策略在優選階段的權重如何配置?

原生調度器的調度策略在優選階段有一個權重配置,每一個策略的評分乘以權重獲得該策略的總得分。對權重越高的策略,符合條件的節點越容易調度上。默認全部策略配置權重爲 1,爲了提高動態調度器策略的效果,咱們把動態調度器優選策略的權重設置爲 2。設計

  1. 動態調度器如何防止調度熱點?

在集羣中,若是出現一個新增的節點,爲了防止新增的節點調度上過多的節點,咱們會經過監聽調度器調度成功事件,獲取調度結果,標記每一個節點過去一段時間的調度 Pod 數,好比 1min、5min、30min 內的調度 Pod 數量,衡量節點的熱點值而後補償到節點的優選評分中。3d

產品能力

組件依賴

組件依賴較少,僅依賴基礎的節點監控組件 node-exporter 和 Prometheus。Prometheus 支持託管和自建兩種方式,使用託管方式能夠一鍵安裝動態調度器,而使用自建 Prometheus 也提供了監控指標配置方法。server

組件配置

調度策略目前能夠基於 CPU 和內存兩種資源利用率。blog

預選階段

配置節點 5分鐘內 CPU 利用率、1小時內最大 CPU 利用率,5分鐘內平均內存利用率,1小時內最大內存利用率的閾值,超過了就會在預選階段過濾節點。排序

優選階段

動態調度器優選階段的評分根據截圖中 6個指標綜合評分得出,6個指標各自的權重表示優選時更側重於哪一個指標的值,使用 1h 和 1d 內最大利用率的意義是要記錄節點 1h 和 1d 內的利用率峯值,由於有的業務 Pod 的峯值週期多是按照小時或者天,避免調度新的 Pod 時致使在峯值時間節點的負載進一步升高。

產品效果

爲了衡量動態調度器對加強 Pod 調度到低負載節點的提高效果,結合調度器的實際調度結果,獲取全部調度到的節點在調度時刻的的 CPU/內存利用率之後統計如下幾個指標:

  • cpu_utilization_total_avg :全部調度到的節點 CPU 利用率平均值。
  • memory_utilization_total_avg :全部調度到的節點內存利用率平均值。
  • effective_dynamic_schedule_count :有效調度次數,當調度到節點的 CPU 利用率小於當前全部節點 CPU 利用率的中位數,咱們認爲這是一次有效調度,effective_dynamic_schedule_count 加 0.5分,對內存也是同理。
  • total_schedule_count :全部調度次數,每次新的調度累加1。
  • effective_schedule_ratio :有效調度比率,即 effective_dynamic_schedule_count/total_schedule_count 下面是在同一集羣中不開啓動態調度和開啓動態調度各自運行一週的指標變化,能夠看到對於集羣調度的加強效果。
指標 未開啓動態調度 開啓動態調度
cpu_utilization_total_avg 0.30 0.17
memory_utilization_total_avg 0.28 0.23
effective_dynamic_schedule_count 2160 3620
total_schedule_count 7860 7470
effective_schedule_ratio 0.273 0.486

Descheduler

現有的集羣調度場景都是一次性調度,即一錘子買賣。後續出現節點 CPU 和內存利用率太高,也沒法自動調整 Pod 的分佈,除非觸發節點的 eviction manager 後驅逐,或者人工干預。這樣在節點 CPU/內存利用率高時,影響了節點上全部 Pod 的穩定性,並且負載低的節點資源還被浪費。

針對此場景,借鑑 K8s 社區 Descheduler 重調度的設計思想,給出基於各節點 CPU/內存實際利用率進行驅逐的策略。

架構

Descheduler 從 apiserver 中獲取 Node 和 Pod 信息,從 Prometheus 中獲取 Node 和 Pod 監控信息,而後通過Descheduler 的驅逐策略,驅逐 CPU/內存使用率高的節點上的 Pod ,同時咱們增強了 Descheduler 驅逐 Pod 時的排序規則和檢查規則,確保驅逐 Pod 時服務不會出現故障。驅逐後的 Pod 通過動態調度器的調度會被調度到低水位的節點上,實現下降高水位節點故障率,提高總體資源利用率的目的。

產品能力

產品依賴

依賴基礎的節點監控組件 node-exporter 和Prometheus。Prometheus 支持託管和自建兩種方式,使用託管方式能夠一鍵安裝 Descheduler,使用自建 Prometheus 也提供了監控指標配置方法。

組件配置

Descheduler 根據用戶配置的利用率閾值,超過閾值水位後開始驅逐 Pod ,使節點負載儘可能下降到目標利用率水位如下。

產品效果

經過 K8s 事件

經過 K8s 事件能夠看到 Pod 被重調度的信息,因此能夠開啓集羣事件持久化功能來查看 Pod 驅逐歷史。

節點負載變化

在相似以下節點 CPU 使用率監控視圖內,能夠看到在開始驅逐以後,節點的 CPU 利用率降低。

最佳實踐

集羣狀態

拿一個客戶的集羣爲例,因爲客戶的業務大可能是內存消耗型的,因此更容易出現內存利用率很高的節點,各個節點的內存利用率也很不平均,未使用動態調度器以前的各個節點監控是這樣的:

動態調度器配置

配置預選和優選階段的參數以下:

在預選階段過濾掉 5分鐘內平均內存利用率超過 60%或者 1h內最大內存利用率超過 70%的節點,即 Pod 不會調度到這些這些節點上。

在優選階段將 5分鐘平均內存利用率權重配置爲 0.8,1h 和1d 內最大內存利用率權重配置爲 0.二、0.2,而將 CPU 的指標權重都配置爲 0.1。這樣優選時更優先選擇調度到內存利用率低的節點上。

Descheduler配置

配置 Descheduler 的參數以下,當節點內存利用率超過 80%這個閾值的時候,Descheduler 開始對節點上的 Pod 進行驅逐,儘可能使節點內存利用率下降到目標值 60% 爲止。

集羣優化後狀態

經過以上的配置,運行一段時間後,集羣內各節點的內存利用率數據以下,能夠看到集羣節點的內存利用率分佈已經趨向於均衡:

【騰訊雲原生】雲說新品、雲研新術、雲遊新活、雲賞資訊,掃碼關注同名公衆號,及時獲取更多幹貨!!

相關文章
相關標籤/搜索