[原始碼分析-kubernetes]4. 一般排程過程
一般排程過程
進入Scheduler的第三層邏輯
今天分析的程式碼,就已經算kube-scheduler的第三層邏輯了,我們要找到預選和優選的入口,講完太長,乾脆後面單獨分2節講預選和優選過程。所以本小節會比較簡短哦~
今天我們從pkg/scheduler/core/generic_scheduler.go:139
開始,也就是從這個generic scheduler的Schedule()方法下手!
我們依舊關心主幹先,這個方法主要涉及的是預選過程+優選過程,看下主要程式碼:
!FILENAME pkg/scheduler/core/generic_scheduler.go:139
func (g *genericScheduler) Schedule(pod *v1.Pod, nodeLister algorithm.NodeLister) (string, error) { nodes, err := nodeLister.List() trace.Step("Computing predicates") filteredNodes, failedPredicateMap, err := g.findNodesThatFit(pod, nodes) trace.Step("Prioritizing") priorityList, err := PrioritizeNodes(pod, g.cachedNodeInfoMap, metaPrioritiesInterface, g.prioritizers, filteredNodes, g.extenders) trace.Step("Selecting host") return g.selectHost(priorityList) }
如上,我手一抖就刪的只剩下這幾行了,大夥應該從這不到十行的程式碼裡找到3個步驟:
- "Computing predicates":呼叫findNodesThatFit()方法;
- "Prioritizing":呼叫PrioritizeNodes()方法;
- "Selecting host":呼叫selectHost()方法。
接著當然是先瀏覽一下這3步分別完成了哪些工作咯~
Computing predicates
這個過程的入口是:
filteredNodes, failedPredicateMap, err := g.findNodesThatFit(pod, nodes)
從變數命名上其實就可以猜到一大半,filteredNodes肯定就是過濾出來的nodes,也就是經受住了預選演算法考驗的node集合,我們從findNodesThatFit
!FILENAME pkg/scheduler/core/generic_scheduler.go:389
func (g *genericScheduler) findNodesThatFit(pod *v1.Pod, nodes []*v1.Node) ([]*v1.Node, FailedPredicateMap, error)
入參是1個pod + 一堆node,返回值是一堆node(這個堆堆當然<=入參的nodes),很明顯,predicates就是幹這個事情了!
Prioritizing
Prioritizing的入口看著複雜一點:
priorityList, err := PrioritizeNodes(pod, g.cachedNodeInfoMap, metaPrioritiesInterface, g.prioritizers, filteredNodes, g.extenders)
注意到這裡的返回值叫做priorityList,什麼什麼List也就是不止一個了,優選過程不是選出1個最佳節點嗎?我們繼續看:
!FILENAME pkg/scheduler/core/generic_scheduler.go:624
func PrioritizeNodes(
pod *v1.Pod,
nodeNameToInfo map[string]*schedulercache.NodeInfo,
meta interface{},
priorityConfigs []algorithm.PriorityConfig,
nodes []*v1.Node,
extenders []algorithm.SchedulerExtender,
) (schedulerapi.HostPriorityList, error)
首選關注返回值是什麼意思:
!FILENAME pkg/scheduler/api/types.go:305
type HostPriority struct {
// Name of the host
Host string
// Score associated with the host
Score int
}
// HostPriorityList declares a []HostPriority type.
type HostPriorityList []HostPriority
看到這裡就清晰了,原來有個HostPriority
型別記錄一個Host的名字和分值,HostPriorityList
型別也就是HostPriority
型別的集合,意味著記錄了多個Host的名字和分值,於是我們可以判斷PrioritizeNodes()
方法的作用是計算前面的predicates過程篩選出來的nodes各自的Score.所以肯定還有一個根據Score決定哪個node勝出的邏輯咯~,繼續往下看吧~
Selecting host
這個過程比較明顯了,我們直接看程式碼:
!FILENAME pkg/scheduler/core/generic_scheduler.go:227
func (g *genericScheduler) selectHost(priorityList schedulerapi.HostPriorityList) (string, error)
這個selectHost()方法大家應該都已經猜到了,就是從上一步的優選過程的結果集中選出一個Score最高的Host,並且返回這個Host的name.
genericScheduler的Schedule()方法主要就是這3個過程,下一講我們開始分析predicates過程。
引用連結:
gitbook:https://farmer-hutao.github.io/k8s-source-code-analysis/
github:https://hub.fastgit.org/daniel-hutao/k8s-source-code-analysis