共计 1843 个字符,预计需要花费 5 分钟才能阅读完成。
k8s 的发展越来越像是一个框架,然后把各种扩展的能力留给开发者。开发者可以基于这些接口结合自己的业务场景,实现自己的场景化需求。其中 kube scheduler 就是充分体现了这个特质,关于 kube scheduler 本身的介绍参加之前的文章,今天我想介绍如何给 scheduler 添加一个调度 plugin。
我们首先通过 yaml 定义这个 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
我们定义了一个 HelloWorldPlugin 的插件,并且定义了这个插件的启动参数。然后需要修改 kube scheduler 启动参数通过 –config 指定上面的配置文件。
接下来我们就需要实现这个插件,scheduler 是通过每个插件的打分的方式确定调度的主机。所以我们需要实现一个打分的接口
type ScorePlugin interface {
Plugin
// 打分
Score(ctx context.Context, state *CycleState, p *v1.Pod, nodeName string) (int64, *Status)
ScoreExtensions() ScoreExtensions}
type ScoreExtensions interface {
// 打分归一化,保证每个插件的公平性
NormalizeScore(ctx context.Context, state *CycleState, p *v1.Pod, scores NodeScoreList) *Status
}
我们根据自己的业务需求实现这个接口,譬如下面这个例子,基于主机网络带宽的调度:首先通过 promethues 获取主机的网络流量,打分依据网络流量大小。
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
}
我们希望网络流量越大,得分越少,于是在归一化处理的时候,我们通过下面简单公式转化成最终的分数。
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
}
这样一个简单的,基于网络流量调度的插件就实现了。
正文完
星哥玩云-微信公众号