日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > windows >内容正文

windows

[译] kubernetes:kube-scheduler 调度器代码结构概述

發布時間:2024/1/21 windows 43 coder
生活随笔 收集整理的這篇文章主要介紹了 [译] kubernetes:kube-scheduler 调度器代码结构概述 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文翻譯自 https://github.com/kubernetes/community/blob/master/contributors/devel/sig-scheduling/scheduling_code_hierarchy_overview.md
譯者:胡云 Troy

調度器代碼層次結構概述

介紹

調度器監視新創建的還沒有分配節點的 Pod。當發現這樣的 Pod 后,調度器將 Pod 調度到最適合它的節點。一般來說,調度是計算機科學中一個相當廣泛的領域,它考慮了各種各樣的約束和限制。調度器的每個工作負載可能需要不同的方法來實現最佳調度結果。Kubernetes 項目提供的 kube-scheduler 調度器的目標是以簡單為代價提供高吞吐量。為了幫助構建調度器(默認或者定制化)和共享調度邏輯,kube-scheduler 實現了 調度框架。該框架沒有提供構建新調度器的所有部分。組裝一個功能齊全的單元仍然需要隊列、緩存、調度算法和其他構建元素。本文檔旨在描述所有單獨的部分是如何組合在一起,以及它們在整個體系結構中的作用,以便開發人員能夠快速了解調度器代碼。

調度 Pod

默認的調度器實例運行無限期的循環,該循環(每次有 Pod 時)負責調用調度邏輯,確保 Pod 分配或重新排隊以供后續處理。每個循環由一個阻塞調度周期和一個非阻塞綁定周期組成。調度周期負責運行調度算法,選擇最合適的節點分配給 Pod。綁定周期確保 kube-apiserver 及時接收分配給 Pod 的節點。一個 Pod 可以立即綁定,或者在群調度中,等所有同級 Pod 分配節點之后再綁定。

圖片來源 調度框架

調度周期

每個周期遵循以下步驟:

  1. 獲取下一個調度的 Pod
  2. 根據提供的調度算法調度 Pod
  3. 如果調度 Pod 時出現 FitError 錯誤,調度器將運行 PostFilterPlugin 搶占插件(如果該插件已注冊),該插件將指定一個可以運行 Pod 的節點。如果搶占成功,讓當前 Pod 知道分配的節點。調度器將處理錯誤,獲取下一個 Pod 并重新開始調度。
  4. 如果調度算法找到了合適的節點,則將 Pod 存儲到調度器緩存中(AssumePod 操作),然后按順序運行 ReservePermit 擴展點插件。任何插件運行失敗將結束當前調度周期,增加相關的指標,調度器的 Error handler 將處理調度錯誤。
  5. 成功運行所有擴展點后,繼續綁定循環。在執行綁定循環的同時,調度周期開始處理下一個調度的 Pod(如果有的話)。

綁定周期

按相同順序運行以下四個步驟:

  • Permit 擴展點調用插件的 WaitOnPermit (內部 API)。擴展點的一些插件會發送操作請求去等待相應的條件(例如,等待額外的可用資源或者一組中的所有 Pod 被分配)。WaitOnPermit 等待條件滿足直到超時。
  • 調用 PreBind 擴展點的插件
  • 調用 Bind 擴展點的插件
  • 調用 PostBind 擴展點的插件

任何擴展點執行失敗將調用所有 Reserve 插件的 Unreserve 操作(例如,為一群 Pod 分配空閑資源)。

配置和組裝調度器

調度器代碼庫分散在不同的地方:

  • cmd/kube-scheduler/app:控制器代碼的位置以及 CLI 參數的定義(遵守所有 Kubernetes 控制器的標準設定)
  • pkg/scheduler:默認調度器代碼庫的根目錄
  • pkg/scheduler/core:默認調度算法的位置
  • pkg/scheduler/framework:調度框架和插件
  • pkg/scheduler/internal:緩存,隊列和其它元素的實現
  • staging/src/k8s.io/kube-scheduler:ComponentConfig API 類型的位置
  • test/e2e/scheduling:調度 e2e
  • test/integration/scheduler:調度集成測試
  • test/integration/scheduler_perf:調度性能基準

初始啟動配置

cmd/kube-scheduler/app 下的代碼負責收集調度器配置和調度器初始化邏輯,它是 kube-scheduler 作為 Kubernetes 控制面運行的一部分。代碼包括:

  • 初始化 命令行選項(以及默認的 ComponentConfig) 和 驗證
  • 初始化 指標,健康檢查 和 其它 handlers
  • KubeSchedulerConfiguration 的讀取和默認配置
  • 通過插件構建 registry(in-tree, out-of-tree)
  • 多種選項初始化調度器,例如 profiles,算法源,pod back off,等等。
  • 調用 LogOrWriteConfig,用于記錄最終調度程序配置以進行調試
  • 運行之前,/configz 已注冊,事件廣播程序已啟動,*選舉已啟動,server(包含所有配置的 handlers 和 informers)已啟動。

初始化之后,調度器開始運行。

更詳細地說,Setup 函數完成了調度器核心流程的初始化。首先,Setup 驗證傳遞的選項(NewSchedulerCommand() 中添加的 flags 直接設置在此選項結構的字段上)。如果傳遞的選項沒有引發任何錯誤,那么它將調用 opts.Config(),用于設置最終的內部配置,包括安全服務、*選舉、客戶端,并開始解析與算法源相關的選項(比如,加載配置文件和初始化空 profiles,以及處理不推薦使用的選項像策略配置)。接下來,調用 c.Complete() 填充配置 Config 中的空值。此時,創建一個空 registry 注冊 out-of-tree 插件,在 registry 中為每個插件的 New 函數添加條目。Registry 只是插件名稱到插件工廠函數的映射。對于默認調度器,注冊 registry 這一步什么都不做(因為 cmd/kube-chuler/scheduler.go 中的 main 函數不向 NewSchedulerCommand() 傳遞任何信息)。這意味著默認的插件在 scheduler.New() 中初始化。

初始化是在調度框架之外執行的,使用框架的用戶可以以不同的方式初始化環境來滿足自身的需求。例如,模擬器可以通過 informer 注入自身需要的對象。或者自定義的插件可以替換默認的插件。調度框架的已知使用者:

  • cluster-autoscaler
  • cluster-capacity

組裝調度器

默認調度器實現的目錄在 pkg/scheduler,調度器的各種元素在這里初始化并組合在一起:

  • 默認調度選項,例如 node percentage, 初始化和最大 backoff, profiles
  • 調度器緩存和隊列
  • 實例化調度的 profiles 以定制框架,每個 profile 可以更好的安置 Pod(每個 profile 定義自身使用的插件集合)
  • Handler 函數用于獲取下一個調度的 Pod(NextPod)和處理錯誤(Error

在創建調度器實例的過程中,將執行以下步驟:

  • 初始化調度器 緩存
  • 合并 帶插件的 in-treeout-of-tree 注冊表
  • Metrics 已注冊
  • 配置器 構建調度器實例(連接緩存,插件注冊表,調度算法和其它元素)
  • 注冊 Event handlers 以允許調度器對 PV、PVC、服務和其它與調度相關的資源的更新做出反應(最終,每個插件都將定義一組事件,并對其作出反應,更詳細的可參考 kubernetes/kubernetes#100347)。

下圖表明了初始化后各個元素是如何連接在一起的。Event handlers 確保 Pod 在 調度隊列中排隊,緩存隨 Pod 和節點的更新而更新(提供最新的快照 snapshot)。調度框架有對應的調度算法和綁定周期(每個框架實例有自己的 profile)。

調度框架

調度器的框架代碼目前位于 pkg/scheduler/framework 下。它包含 各種插件,負責過濾和評分節點(以及其他)。常常用作調度算法的構建模塊。

當 插件初始化 后,它會傳遞一個 框架 handler,該框架 handler 提供訪問和/或操作 pod、節點、clientset、事件記錄器和每個插件實現其功能所需的其他 handler 的接口。

調度緩存

緩存負責記錄集群的最新狀態。保存節點和 assumed Pod 以及 Pod 和 images 的狀態。緩存提供了協調 Pod 和節點對象(調用 event handlers)的方法,使集群的狀態保持最新。允許在每個調度周期開始時使用最新狀態(在運行調度算法時固定集群狀態)更新集群的快照。

緩存還允許運行假定的操作,該操作將 Pod 臨時存儲在緩存中,使得 Pod 看起來像已經在快照的所有消費者的指定節點上運行那樣。假定操作忽視了 kube-apiserver 和 Pod 實際更新的時間,從而增加調度器的吞吐量。

以下操作使用假定的 Pod 進行操作:

  • AssumePod:用于通知調度算法找到可行的節點,以便在當前 Pod 進入綁定周期時可以調度下一個 Pod
  • FinishBinding:用于發出綁定完成的信號,以便可以將 Pod 從假定 Pod 列表中刪除
  • ForgetPod:從假定的 Pod 列表中刪除 Pod,用于綁定周期中未能成功處理 Pod 的情況(例如,Reserve,Permit,PreBind 或者 Bind 評估)

緩存跟蹤以下三個指標:

  • scheduler_cache_size_assumed_pods:在假定 Pod 列表中的 Pod 數量
  • scheduler_cache_size_pods:在緩存中的 Pod 數量
  • scheduler_cache_size_nodes:在緩存中的節點數量

快照

快照 捕獲集群的狀態,其中包含集群中所有節點和每個節點上對象的信息。即節點對象、分配在每個節點上的 Pod、每個節點上所有 Pod 的請求資源、節點的可分配資源、拉取的鏡像以及做出調度決策所需的其他信息。每次調度 Pod 時,都會捕獲集群當前狀態的快照。這樣是為了避免在處理插件時更改 Pod 或節點時導致的數據不一致,因為一些插件可能會獲得不同的集群狀態。

配置器

配置器 通過將插件、緩存、隊列、handlers 和其他元素連接在一起來構建調度器實例。每個 profile 都使用自己的框架(所有框架共享 informers,event recorders 等)進行 初始化。

也可以讓配置器根據 策略文件 創建實例。不過,這種方法已被棄用,最終將從配置中刪除。只保留調度器配置作為提供給配置器配置的唯一方式。

默認調度算法

代碼庫定義了 ScheduleAlgorithm 接口。任何該接口的實現都可以用作調度算法。這里有兩種方法:

  • Schedule:負責使用從 PreFilterNormalizeScore 擴展點的插件來調度 Pod,提供包含調度決策(最合適的節點)和附帶信息的 ScheduleResult,其中附帶信息包括評估了多少節點以及發現有多少節點可用于調度。
  • Extenders: 當前僅用于測試

默認算法實現的每個周期包括:

  1. 從調度緩存中獲取 當前快照
  2. 過濾掉所有無法調度 Pod 的節點
    • 運行 PreFilter 插件(預處理階段,例如計算 Pod 親和性關系)
    • 并行運算 Filter 插件:過濾掉不滿足 Pod 限制條件(例如資源,節點親和性等)的節點,包括運行 Filter 擴展器
    • 運行 PostFilter 插件 如果沒有節點滿足要調度的 Pod
  3. 在 Pod 至少有兩個可行節點可以調度的情況下,運行 scoring 插件:
    • 運行 PreScore 插件(預處理階段)
    • 并行運行 Score 插件:每個節點都有一個分數向量(每個坐標對應一個插件)
    • 運行 NormalizeScore 插件:給所有插件打分,間隔為 [0, 100]
    • 計算每個節點的 權重分數 (每個分數插件都可以分配一個權重,指示其分數在多大程度上優于其他插件)
    • 運行 打分擴展器,并且將分數計入每個節點的總分
  4. 選擇 并 返回 得分最高的節點。如果只有一個可供調度的節點則跳過 PrescoreScoreNormalizeScore 擴展點,并且立即返回調度的節點。如果沒有可供調度的節點,將結果返回給調度器。

值得注意的是:

  • 如果插件提供 score normalization,當調用 ScoreExtensions() 時,插件需要返回非 nil

總結

以上是生活随笔為你收集整理的[译] kubernetes:kube-scheduler 调度器代码结构概述的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。