Crane-scheduler:基於真實負載進行調度

作者

邱天,騰訊雲高級工程師,負責騰訊雲 TKE 動態調度器與重調度器產品。

背景

原生 kubernetes 調度器只能基於資源的 resource request 進行調度,然而 Pod 的真實資源使用率,往往與其所申請資源的 request/limit 差異很大,這直接導致了集群負載不均的問題:

  1. 集群中的部分節點,資源的真實使用率遠低於 resource request,卻沒有被調度更多的 Pod,這造成了比較大的資源浪費;

  2. 而集群中的另外一些節點,其資源的真實使用率事實上已經過載,卻無法為調度器所感知到,這極大可能影響到業務的穩定性。

這些無疑都與企業上雲的最初目的相悖,為業務投入了足夠的資源,卻沒有達到理想的效果。

既然問題的根源在於 resource request 與真實使用率之間的「鴻溝」,那為什麼不能讓調度器直接基於真實使用率進行調度呢?這就是 Crane-scheduler 設計的初衷。Crane-scheduler 基於集群的真實負載數據構造了一個簡單卻有效的模型,作用於調度過程中的 Filter 與 Score 階段,並提供了一種靈活的調度策略配置方式,從而有效緩解了 kubernetes 集群中各種資源的負載不均問題。換句話說,Crane-scheduler 著力於調度層面,讓集群資源使用最大化的同時排除了穩定性的後顧之憂,真正實現「降本增效」。

整體架構

如上圖所示,Crane-scheduler 依賴於 Node-exporter 與 Prometheus 兩個組件,前者從節點收集負載數據,後者則對數據進行聚合。而 Crane-scheduler 本身也包含兩個部分:

  1. Scheduler-Controller 周期性地從 Prometheus 拉取各個節點的真實負載數據, 再以 Annotation 的形式標記在各個節點上;

  2. Scheduler 則直接在從候選節點的 Annotation 讀取負載資訊,並基於這些負載資訊在 Filter 階段對節點進行過濾以及在 Score 階段對節點進行打分;

基於上述架構,最終實現了基於真實負載對 Pod 進行有效調度。

調度策略

下圖是官方提供的 Pod 的調度上下文以及調度框架公開的擴展點:

Crane-scheduler 主要作用於圖中的 Filter 與 Score 階段,並對用戶提供了一個非常開放的策略配置。這也是 Crane-Scheduler 與社區同類型的調度器最大的區別之一:

  1. 前者提供了一個泛化的調度策略配置介面,給予了用戶極大的靈活性;
  2. 後者往往只能支援 cpu/memory 等少數幾種指標的感知調度,且指標聚合方式,打分策略均受限。
    在 Crane-scheduler 中,用戶可以為候選節點配置任意的評價指標類型(只要從 Prometheus 能拉到相關數據),不論是常用到的 CPU/Memory 使用率,還是 IO、Network Bandwidth 或者 GPU 使用率,均可以生效,並且支援相關策略的自定義配置。

數據拉取

如「整體架構」中所述,Crane-scheduler 所需的負載數據均是通過 Controller 非同步拉取。這種數據拉取方式:

  1. 一方面,保證了調度器本身的性能;

  2. 另一方面,有效減輕了 Prometheus 的壓力,防止了業務突增時組件被打爆的情況發生。

此外,用戶可以直接 Describe 節點,查看到節點的負載資訊,方便問題定位:

[root@test01 ~]# kubectl describe node test01
Name:               test01
...
Annotations:        cpu_usage_avg_5m: 0.33142,2022-04-18T00:45:18Z
                    cpu_usage_max_avg_1d: 0.33495,2022-04-17T23:33:18Z
                    cpu_usage_max_avg_1h: 0.33295,2022-04-18T00:33:18Z
                    mem_usage_avg_5m: 0.03401,2022-04-18T00:45:18Z
                    mem_usage_max_avg_1d: 0.03461,2022-04-17T23:33:20Z
                    mem_usage_max_avg_1h: 0.03425,2022-04-18T00:33:18Z
                    node.alpha.kubernetes.io/ttl: 0
                    node_hot_value: 0,2022-04-18T00:45:18Z
                    volumes.kubernetes.io/controller-managed-attach-detach: true
...

用戶可以自定義負載數據的類型與拉取周期,默認情況下,數據拉取的配置如下:

  syncPolicy:
    ## cpu usage
    - name: cpu_usage_avg_5m
      period: 3m
    - name: cpu_usage_max_avg_1h
      period: 15m
    - name: cpu_usage_max_avg_1d
      period: 3h
    ## memory usage
    - name: mem_usage_avg_5m
      period: 3m
    - name: mem_usage_max_avg_1h
      period: 15m
    - name: mem_usage_max_avg_1d
      period: 3h

Filter 策略

用戶可以在 Filter 策略中配置相關指標的閾值,若候選節點的當前負載數據超過了任一所配置的指標閾值,則這個節點將會被過濾,默認配置如下:

  predicate:
    ## cpu usage
    - name: cpu_usage_avg_5m
      maxLimitPecent: 0.65
    - name: cpu_usage_max_avg_1h
      maxLimitPecent: 0.75
    ## memory usage
    - name: mem_usage_avg_5m
      maxLimitPecent: 0.65
    - name: mem_usage_max_avg_1h
      maxLimitPecent: 0.75

Score 策略

用戶可以在 Score 策略中配置相關指標的權重,候選節點的最終得分為不同指標得分的加權和,默認配置如下:

  priority:
    ### score = sum((1 - usage) * weight) * MaxScore / sum(weight)
    ## cpu usage
    - name: cpu_usage_avg_5m
      weight: 0.2
    - name: cpu_usage_max_avg_1h
      weight: 0.3
    - name: cpu_usage_max_avg_1d
      weight: 0.5
    ## memory usage
    - name: mem_usage_avg_5m
      weight: 0.2
    - name: mem_usage_max_avg_1h
      weight: 0.3
    - name: mem_usage_max_avg_1d
      weight: 0.5

調度熱點

在實際生產環境中,由於 Pod 創建成功以後,其負載並不會立馬上升,這就導致了一個問題:如果完全基於節點實時負載對 Pod 調度,常常會出現調度熱點(短時間大量 pod 被調度到同一個節點上)。為了解決這個問題,我們設置了一個單列指標 Hot Vaule,用來評價某個節點在近段時間內被調度的頻繁程度,對節點實時負載進行對沖。最終節點的 Priority 為上一小節中的 Score 減去 Hot Value。Hot Value 默認配置如下:

  hotValue:
    - timeRange: 5m
      count: 5
    - timeRange: 1m
      count: 2

註:該配置表示,節點在 5 分鐘內被調度 5 個 pod,或者 1 分鐘內被調度 2 個 pod,HotValue 加 10 分。

案例分享

Crane-scheduler 目前有眾多公有雲用戶,包括鬥魚直播、酷狗、一汽大眾、獵豹移動等公司均在使用,並給予了產品不錯的回饋。這裡我們先分享一個某公有雲用戶的真實案例。該客戶集群中的業務大多是記憶體消耗型的,因此極易出現記憶體利用率很高的節點,並且各個節點的記憶體利用率分布也很不平均,如下圖所示:

了解到用戶的情況後,我們推薦其使用 Crane-scheduler,組件運行一段時間後,該用戶集群內各節點的記憶體利用率數據分布發生了顯著變化,如下圖 :

可見,用戶集群的記憶體使用率更加趨於均衡。

另外, Crane-scheduler 也在公司內部各個 BG 的自研上雲環境中,也得到了廣泛的使用。下面是內部自研上雲平台 TKEx-CSIG 的兩個生產集群的 CPU 使用率分布情況,其中集群 A 未部署 Crane-scheduler:

集群 B 部署了組件並運行過一段時間:

很明顯,在集群 B 中,節點 CPU 使用率分布在兩端( < 10% 與 > 80%)所佔的比例,要顯著小於集群 A,並且整體分布也更加緊湊,相對而言更加均衡與健康。

衍生閱讀:什麼是 Crane

為推進雲原生用戶在確保業務穩定性的基礎上做到真正的極致降本,騰訊推出了業界第一個基於雲原生技術的成本優化開源項目 Crane( Cloud Resource Analytics and Economics )。Crane 遵循 FinOps 標準,旨在為雲原生用戶提供雲成本優化一站式解決方案。

Crane-scheduler 作為 Crane 的調度插件實現了基於真實負載的調度功能,旨在從調度層面幫助業務降本增效。

近期,Crane 成功加入 CNCF Landscape,歡迎關注項目://github.com/gocrane/crane。

關於我們

更多關於雲原生的案例和知識,可關注同名【騰訊雲原生】公眾號~

福利:

①公眾號後台回復【手冊】,可獲得《騰訊雲原生路線圖手冊》&《騰訊雲原生最佳實踐》~

②公眾號後台回復【系列】,可獲得《15個系列100+篇超實用雲原生原創乾貨合集》,包含Kubernetes 降本增效、K8s 性能優化實踐、最佳實踐等系列。

③公眾號後台回復【白皮書】,可獲得《騰訊雲容器安全白皮書》&《降本之源-雲原生成本管理白皮書v1.0》

④公眾號後台回復【光速入門】,可獲得騰訊雲專家5萬字精華教程,光速入門Prometheus和Grafana。

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