调度框架 [1]
本文基于 kubernetes 1.24 进行分析
调度框架(Scheduling Framework)是Kubernetes 的调度器 kube-scheduler 设计的的可插拔架构,将插件(调度算法)嵌入到调度上下文的每个扩展点中,并编译为 kube-scheduler
在 kube-scheduler 1.22 之后,在 pkg/scheduler/framework/interface.go 中定义了一个 Plugin 的 interface,这个 interface 作为了所有插件的父级。而每个未调度的 Pod,Kubernetes 调度器会根据一组规则尝试在集群中寻找一个节点。- type Plugin interface {
- Name() string
- }
复制代码 下面会对每个算法是如何实现的进行分析
在初始化 scheduler 时,会创建一个 profile,profile是关于 scheduler 调度配置相关的定义- func New(client clientset.Interface,
- ...
- profiles, err := profile.NewMap(options.profiles, registry, recorderFactory, stopCh,
- frameworkruntime.WithComponentConfigVersion(options.componentConfigVersion),
- frameworkruntime.WithClientSet(client),
- frameworkruntime.WithKubeConfig(options.kubeConfig),
- frameworkruntime.WithInformerFactory(informerFactory),
- frameworkruntime.WithSnapshotSharedLister(snapshot),
- frameworkruntime.WithPodNominator(nominator),
- frameworkruntime.WithCaptureProfile(frameworkruntime.CaptureProfile(options.frameworkCapturer)),
- frameworkruntime.WithClusterEventMap(clusterEventMap),
- frameworkruntime.WithParallelism(int(options.parallelism)),
- frameworkruntime.WithExtenders(extenders),
- )
- if err != nil {
- return nil, fmt.Errorf("initializing profiles: %v", err)
- }
- if len(profiles) == 0 {
- return nil, errors.New("at least one profile is required")
- }
- ....
- }
复制代码 关于 profile 的实现,则为 KubeSchedulerProfile,也是作为 yaml生成时传入的配置- // KubeSchedulerProfile 是一个 scheduling profile.
- type KubeSchedulerProfile struct {
- // SchedulerName 是与此配置文件关联的调度程序的名称。
- // 如果 SchedulerName 与 pod “spec.schedulerName”匹配,则使用此配置文件调度 pod。
- SchedulerName string
- // Plugins指定应该启用或禁用的插件集。
- // 启用的插件是除了默认插件之外应该启用的插件。禁用插件应是禁用的任何默认插件。
- // 当没有为扩展点指定启用或禁用插件时,将使用该扩展点的默认插件(如果有)。
- // 如果指定了 QueueSort 插件,
- // 则必须为所有配置文件指定相同的 QueueSort Plugin 和 PluginConfig。
- // 这个Plugins展现的形式则是调度上下文中的所有扩展点(这是抽象),实际中会表现为多个扩展点
- Plugins *Plugins
- // PluginConfig 是每个插件的一组可选的自定义插件参数。
- // 如果省略PluginConfig参数等同于使用该插件的默认配置。
- PluginConfig []PluginConfig
- }
复制代码 对于 profile.NewMap 就是根据给定的配置来构建这个framework,因为配置可能是存在多个的。而 Registry 则是所有可用插件的集合,内部构造则是 PluginFactory ,通过函数来构建出对应的 plugin
[code]func NewMap(cfgs []config.KubeSchedulerProfile, r frameworkruntime.Registry, recorderFact RecorderFactory, stopCh |