【kubernetes学习笔记】kube-scheduler中的自定义插件

118 阅读2分钟

调度框架

基于kubernetes v1.32.0

在启动kube-scheduler的时候可以通过--config来指定scheduler运行的配置(此时--kubeconfig会被忽略)。

apiVersion: kubescheduler.config.k8s.io/v1
kind: KubeSchedulerConfiguration
clientConnection:
  kubeconfig: /etc/kubernetes/scheduler.conf
leaderElection:
  leaderElect: false
profiles:
  - schedulerName: my-scheduler
    plugins:
      score:
        enabled:
          - name: MyPlugin
        disabled:
          - name: "*"

上面的scheduler配置文件中:

  • apiVersion:API对象的版本,由GroupNameVersion组成,可以在Configuration APIs | Kubernetes中查询,也可以在对应代码仓库的staging/src/k8s.io/kube-scheduler中检索GroupName获得。
  • kubeconfig:用于和apiserver交互,使用kubectl config view --raw生成的配置就是可用的。
  • leaderElection:决定是否选举主节点。
  • profiles:调度器配置,每个数组元素最终都会被读取解析成KubeSchedulerProfile对象(staging/src/k8s.io/kube-scheduler/config/v1/types.go)。

framework配置解析

kube-scheduler启动的时候将配置文件中的profiles解析成一个KubeSchedulerProfile的数组,每个KubeSchedulerProfile代表一个调度器(默认调度器名称为default-scheduler)。kube-scheduler为数组中的每个调度器新建一个framework,其主要调度流程均由framework下的插件负责,每个调度流程呈现在配置文件中就是profiles[*]/plugins下的一个字段,该字段包含enableddisabled,分别表示启用的插件和不启用的插件。比如上面的例子,在my-scheduler这个调度器的score调度流程中会启用MyPlugin这个插件,不启用除此之外的其他插件。

frameworkNewFrameworkpkg/scheduler/framework/runtime/framework.go)方法创建。NewFrameworkRegistry类型入参中包含了所有插件的{名称,构造方法}组合。生成framework时代码会先根据构造方法生成这个插件的实例,用map进行存储,然后遍历每个调度流程下的插件(本例profiles[*]/plugins/score下所有的插件),如果有插件在enabled数组中则需要检查该插件实例是否实现了对应的接口。

插件的注册

一个framework代表一个调度器,一个plugin(插件)表示一个调度功能(或者叫约束?),pod在调度的时候需要满足的某个约束条件的判别就是由插件来完成的。插件的实现位于pkg/scheduler/framework/plugins,每个插件必须实现k8s.io/kubernetes/pkg/scheduler/framework包下的Plugin接口,根据涉及的调度流程额外实现对应的接口(对应的接口查看pkg/scheduler/framework/interface.go)。

编写完成后需要在pkg/scheduler/framework/plugins/registry.goNewInTreeRegistry方法中将插件添加到Registry中,Registry随后将插件注册到framework中。

除此之外,Registry.Merge也可以添加对应的插件,但该调用路径最终指向了test。而NewInTreeRegistry的调用路径最终指向了kube-schedulerNewSchedulerCommand方法,该方法在kube-scheduler启动时并没有传入参数。因此,当前无法像crd那样对kube-scheduler进行扩展(实践中...)。

插件的使用

补充实践中...