You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何查看Kubernetes v1.26.3调度器框架中已注册的插件?

如何确定Kubernetes调度器Framework中已注册的插件(v1.26.3版本)

在v1.26.3版本的Kubernetes调度器源码里,要确定哪些插件完成注册,直接看NewFramework函数的逻辑就行:

1. 先筛选出配置要求的插件集合

函数里通过pg := f.pluginsNeeded(profile.Plugins)生成一个插件名称集合,这个集合包含了调度器配置文件(profile.Plugins)里所有启用的插件——不管是QueueSort、Filter这类单一扩展点的插件,还是MultiPoint类型的插件,都会被收集进来。

2. 初始化并存储已注册的插件

接下来会创建pluginsMap映射,用来存储所有初始化完成的插件实例:

  • 遍历传入的插件注册表r,对每个插件先检查是否在pg集合里,只有配置需要的插件才会继续处理
  • 调用插件的工厂函数factory(args, f)创建实例,成功后将插件存入pluginsMap——这个pluginsMap里的插件,就是已经完成注册的

3. 把插件关联到对应调度阶段

最后通过updatePluginList和expandMultiPointPlugins,把pluginsMap里的插件实例分别放到frameworkImpl结构体对应的扩展点切片里,比如:

  • queueSortPlugins:队列排序阶段的插件
  • filterPlugins:节点过滤阶段的插件
  • scorePlugins:节点打分阶段的插件
  • bindPlugins:绑定阶段的插件

这些切片里的内容,也能直接看到对应调度阶段已注册的插件。

对应源码片段

// NewFramework initializes plugins given the configuration and the registry.
func NewFramework(r Registry, profile *config.KubeSchedulerProfile, stopCh <-chan struct{}, opts ...Option) (framework.Framework, error) {
    options := defaultFrameworkOptions(stopCh)
    for _, opt := range opts {
        opt(&options)
    }

    f := &frameworkImpl{
        registry:             r,
        snapshotSharedLister: options.snapshotSharedLister,
        scorePluginWeight:    make(map[string]int),
        waitingPods:          newWaitingPodsMap(),
        clientSet:            options.clientSet,
        kubeConfig:           options.kubeConfig,
        eventRecorder:        options.eventRecorder,
        informerFactory:      options.informerFactory,
        metricsRecorder:      options.metricsRecorder,
        extenders:            options.extenders,
        PodNominator:         options.podNominator,
        parallelizer:         options.parallelizer,
    }

    if profile == nil {
        return f, nil
    }

    f.profileName = profile.SchedulerName
    f.percentageOfNodesToScore = profile.PercentageOfNodesToScore
    if profile.Plugins == nil {
        return f, nil
    }

    // get needed plugins from config
    pg := f.pluginsNeeded(profile.Plugins)

    pluginConfig := make(map[string]runtime.Object, len(profile.PluginConfig))
    for i := range profile.PluginConfig {
        name := profile.PluginConfig[i].Name
        if _, ok := pluginConfig[name]; ok {
            return nil, fmt.Errorf("repeated config for plugin %s", name)
        }
        pluginConfig[name] = profile.PluginConfig[i].Args
    }
    outputProfile := config.KubeSchedulerProfile{
        SchedulerName:            f.profileName,
        PercentageOfNodesToScore: f.percentageOfNodesToScore,
        Plugins:                  profile.Plugins,
        PluginConfig:             make([]config.PluginConfig, 0, len(pg)),
    }

    pluginsMap := make(map[string]framework.Plugin)
    for name, factory := range r {
        // initialize only needed plugins.
        if !pg.Has(name) {
            continue
        }

        args := pluginConfig[name]
        if args != nil {
            outputProfile.PluginConfig = append(outputProfile.PluginConfig, config.PluginConfig{
                Name: name,
                Args: args,
            })
        }
        p, err := factory(args, f)
        if err != nil {
            return nil, fmt.Errorf("initializing plugin %q: %w", name, err)
        }
        pluginsMap[name] = p

        // Update ClusterEventMap in place.
        fillEventToPluginMap(p, options.clusterEventMap)
    }

    // initialize plugins per individual extension points
    for _, e := range f.getExtensionPoints(profile.Plugins) {
        if err := updatePluginList(e.slicePtr, *e.plugins, pluginsMap); err != nil {
            return nil, err
        }
    }

    // initialize multiPoint plugins to their expanded extension points
    if len(profile.Plugins.MultiPoint.Enabled) > 0 {
        if err := f.expandMultiPointPlugins(profile, pluginsMap); err != nil {
            return nil, err
        }
    }

    if len(f.queueSortPlugins) != 1 {
        return nil, fmt.Errorf("only one queue sort plugin required for profile with scheduler name %q, but got %d", profile.SchedulerName, len(f.queueSortPlugins))
    }
    if len(f.bindPlugins) == 0 {
        return nil, fmt.Errorf("at least one bind plugin is needed for profile with scheduler name %q", profile.SchedulerName)
    }

    if err := getScoreWeights(f, pluginsMap, append(profile.Plugins.Score.Enabled, profile.Plugins.MultiPoint.Enabled...)); err != nil {
        return nil, err
    }

    // Verifying the score weights again since Plugin.Name() could return a different
    // value from the one used in the configuration.
    for _, scorePlugin := range f.scorePlugins {
        if f.scorePluginWeight[scorePlugin.Name()] == 0 {
            return nil, fmt.Errorf("score plugin %q is not configured with weight", scorePlugin.Name())
        }
    }

    if options.captureProfile != nil {
        if len(outputProfile.PluginConfig) != 0 {
            sort.Slice(outputProfile.PluginConfig, func(i, j int) bool {
                return outputProfile.PluginConfig[i].Name < outputProfile.PluginConfig[j].Name
            })
        } else {
            outputProfile.PluginConfig = nil
        }
        options.captureProfile(outputProfile)
    }

    return f, nil
}

内容的提问来源于stack exchange,提问作者fuyou001

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 00:47:51