如何自定義 Kube-Scheduler 插件
k8s的發(fā)展越來越像是一個(gè)框架,然后把各種擴(kuò)展的能力留給開發(fā)者。開發(fā)者可以基于這些接口結(jié)合自己的業(yè)務(wù)場景,實(shí)現(xiàn)自己的場景化需求。其中kube scheduler 就是充分體現(xiàn)了這個(gè)特質(zhì),關(guān)于kube scheduler 本身的介紹參加之前的文章,今天我想介紹如何給scheduler 添加一個(gè)調(diào)度plugin。
我們首先通過yaml定義這個(gè)plugin
- apiVersion: kubescheduler.config.k8s.io/v1beta1
- kind: KubeSchedulerConfiguration
- clientConnection:
- kubeconfig: "/etc/kubernetes/scheduler.conf"
- profiles:
- - schedulerName: default-scheduler
- plugins:
- score:
- enabled:
- - name: HelloWorldPlugin
- disabled:
- - name: "*"
- pluginConfig:
- - name: HelloWorldPlugin
- args:
- xxx: "xxx"
- yyy: "123"
- zzz: 3
我們定義了一個(gè) HelloWorldPlugin 的插件,并且定義了這個(gè)插件的啟動(dòng)參數(shù)。然后需要修改kube scheduler啟動(dòng)參數(shù)通過 --config 指定上面的配置文件。
接下來我們就需要實(shí)現(xiàn)這個(gè)插件,scheduler是通過每個(gè)插件的打分的方式確定調(diào)度的主機(jī)。所以我們需要實(shí)現(xiàn)一個(gè)打分的接口
- type ScorePlugin interface {
- Plugin
- // 打分
- Score(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) (int64, *Status)
- ScoreExtensions() ScoreExtensions
- }
- type ScoreExtensions interface {
- // 打分歸一化,保證每個(gè)插件的公平性
- NormalizeScore(ctx context.Context, state *CycleState, p *v1.Pod, scores NodeScoreList) *Status
- }
我們根據(jù)自己的業(yè)務(wù)需求實(shí)現(xiàn)這個(gè)接口,譬如下面這個(gè)例子,基于主機(jī)網(wǎng)絡(luò)帶寬的調(diào)度:首先通過promethues獲取主機(jī)的網(wǎng)絡(luò)流量,打分依據(jù)網(wǎng)絡(luò)流量大小。
- func (n *HelloWorldPlugin) Score(ctx context.Context, state *framework.CycleState, p *v1.Pod, nodeName string) (int64, *framework.Status) {
- nodeBandwidth, err := n.prometheus.GetNodeBandwidthMeasure(nodeName)
- if err != nil {
- return 0, framework.NewStatus(framework.Error, fmt.Sprintf("error getting node bandwidth measure: %s", err))
- }
- klog.Infof("[NetworkTraffic] node '%s' bandwidth: %s", nodeName, nodeBandwidth.Value)
- return int64(nodeBandwidth.Value), nil
- }
我們希望網(wǎng)絡(luò)流量越大,得分越少,于是在歸一化處理的時(shí)候,我們通過下面簡單公式轉(zhuǎn)化成最終的分?jǐn)?shù)。
- func (n *HelloWorldPlugin) NormalizeScore(ctx context.Context, state *framework.CycleState, pod *v1.Pod, scores framework.NodeScoreList) *framework.Status {
- for i, node := range scores {
- scores[i].Score = framework.MaxNodeScore - (node.Score * framework.MaxNodeScore / higherScore)
- }
- klog.Infof("[NetworkTraffic] Nodes final score: %v", scores)
- return nil
- }
這樣一個(gè)簡單的,基于網(wǎng)絡(luò)流量調(diào)度的插件就實(shí)現(xiàn)了。