1. 程式人生 > 其它 >[原始碼分析-kubernetes]4. 一般排程過程

[原始碼分析-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個步驟:

  1. "Computing predicates":呼叫findNodesThatFit()方法;
  2. "Prioritizing":呼叫PrioritizeNodes()方法;
  3. "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