103 - kube-scheduler源碼分析 - 調度算法-尋找predicates和priorities


 

 

scheduler的主要邏輯是predicate和priority,前者回答哪些節點可以運行pod的問題,后者回答哪個節點更合適運行pod的問題。今天我們的任務是:從主函數出發,尋找predicates和priorities的入口!

 

前面我們提到過Execute()其實是運行了這個Run方法,在cmd/kube-scheduler/app/server.go的337行。

順着opts.Run()往里跟:

 

可以很清楚看到opts.Run()的邏輯,初始化一個server,然后執行server.Run()方法。這里的server類型是*SchedulerServer,這個類型的官方解釋是:

SchedulerServer represents all the parameters required to start the kubernetes scheduler server. 也就是說運行scheduler server所需的所有參數集合:

 

 

我們順着主干往下走,看一下server.Run()方法的定義:

 如上圖,我們需要關注一下函數開頭的注釋,這個Run是要運行SchedulerServer,永遠不退出!也就是說到這里就啟動了一個server,開始無怨無悔永不停息地處理pod的scheduler流程!接着通過一個方法SchedulerConfig()獲取到一個對象叫做schedulerConfig,我們也看一下這個對象的定義:Config is an implementation of the Scheduler's configured input data.

 

 最后一個sched的創建代表着scheduler的daemon程序准備差不多了!sched的類型如下:

 

 從注釋中我們可以得到很多信息,Scheduler監視者未調度的pods,嘗試尋找合適的node,把pod和node的綁定關系告訴api server!Run函數繼續往后看可以找到(server.go的602行):

 

 可以看到准備好了一個sched.Run(),但是沒有立刻執行,626行有一個run(stop),就不貼截圖了,我們直接跟到sched.Run()這個方法看一下里面寫了啥:

 

 這個Run()方法開始watching and scheduling,最后面的紅框需要注意幾點,這是新開一個goroutine執行,然后立刻返回的。新開的goroutine是干嘛呢?每隔0秒就執行一次sched.scheduleOne方法!這里的0秒可能需要理解一下,我們看一下wait.Until()方法的定義:

 

 ok,其實是當f這個函數被調用完成后過0秒開始下一次調用,說白了就是前赴后繼中間不休息!后面我們當然繼續看scheduleOne()方法做了啥:

 

 可以看到scheduleOne()方法能夠處理一個pod完整的schedulering工作流。第一步是獲取一個pod,這個pod的獲取方法是這樣定義的:

 

 這里我們關注一下這個方法首先是阻塞的,也就是不返回一個結果就一直卡住。接着看一下suggestedHost是什么:

 

 可以看到,這個類型是string,string不就意味着這就是最后的結果嗎?不然怎么着也是一個[]string是吧???所以這里的suggestedHost也就是最后調度算法所給出建議跑pod的host!!!ok,我們的路沒有偏離主線,繼續看schedule方法的邏輯(上圖中可以看到host是通過方法:sched.config.Algorithm.Schedule()獲取的,我們直接看Schedule()方法):

 

 

 

 這個方法的參數是pod信息和node信息(獲取node信息的接口),返回值是string類型,也就是根據pod信息和nodes信息看pod能夠跑在哪個node上,然后返回這個node的名字!

 

 上圖從generic_scheduler.go的134行開始,這個msg信息很有意思,"Computing predicates",后面的findNodesThatFit()函數返回filteredNodes,也就是predicates過程的結果,返回的filteredNodes也就是可以運行pod的node集合!往下看150行處:

 

 可以看到priorities過程在這里,PrioritizeNodes()函數返回一個priorityList,這個priorityList是schedulerapi.HostPriorityList類型,也就是[]HostPriority類型,HostPriority類型的定義如下:

 

 可以看到,這個類型其實存的數據就是一個節點的名字和分數信息,也就是說PrioritizeNodes()函數完成了所有可以跑pod的node的分數計算!結尾的selectHost()方法就很簡單是,選擇一個分高的host返回:

 

 ok,總算跟完了,到這里我們就完成了整個調度過程的略讀,下次開始我們可以看具體的predicates和priorities算法了! 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM