如何在K8s调度器API中获取经过过滤的节点?
获取K8s默认过滤器筛选后的节点(自定义调度器打分阶段)
情况1:在自定义打分插件中直接使用过滤后的节点
在标准调度器执行流程里,过滤阶段会先筛选出符合条件的节点,之后才进入打分阶段。如果你的自定义逻辑是基于调度器框架开发的打分插件,那么Score方法的入参中已经包含了经过默认过滤器(及你配置的其他过滤器)筛选后的节点列表。
比如在framework.Plugin的Score方法中,可通过CycleState获取全部过滤后的节点:
func (p *yourCustomPlugin) Score(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeName string) (int64, *framework.Status) { allFilteredNodes, err := state.Read(framework.NodesToScoreKey) if err == nil { nodes := allFilteredNodes.([]*v1.Node) // 在这里处理过滤后的节点集合 } // ... 你的打分逻辑 }
另外,方法参数里的nodeName对应的节点,本身就是通过过滤阶段的合规节点。
情况2:手动调用默认过滤器筛选节点
如果需要在自定义逻辑中手动触发默认过滤器的筛选,可直接调用调度器predicates包中的默认过滤函数集合:
- 先获取默认的过滤谓词(Predicates)列表:
import "k8s.io/kubernetes/pkg/scheduler/framework/plugins/legacyregistry" defaultPredicates := legacyregistry.DefaultPredicates()
- 遍历全量节点,调用谓词集合完成筛选:
import ( "k8s.io/kubernetes/pkg/scheduler/predicates" ) // 假设你已持有pod对象和全量节点列表allNodes filteredNodes := []*v1.Node{} for _, node := range allNodes { fit, _, err := predicates.RunPredicateSuite(ctx, defaultPredicates, pod, node, nil) if err == nil && fit { filteredNodes = append(filteredNodes, node) } }
RunPredicateSuite会依次执行所有默认过滤规则,返回节点是否符合调度条件。
关键提示
- 优先依赖调度器框架的流程传递数据,打分阶段拿到的节点已经是过滤后的合规节点,无需重复筛选。
- 如果扩展调度器插件,尽量使用框架提供的
CycleState获取数据,避免直接调用底层函数引发兼容性问题。
内容的提问来源于stack exchange,提问作者lhb6540
相关产品推荐
相关产品推荐

