Skip to content

Commit

Permalink
Add PreScore extension point in kube-scheduler
Browse files Browse the repository at this point in the history
  • Loading branch information
mcsos committed Jan 5, 2021
1 parent d5c43aa commit 2e2204e
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 1 deletion.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
- 调度过程分析
- [PreFilter](./kube-scheduler/scheduling/pre-filter.md)
- [Filter](./kube-scheduler/scheduling/filter.md)
- [PreScore](./kube-scheduler/scheduling/pre-score.md)

- 调度算法详解

Expand Down
2 changes: 1 addition & 1 deletion kube-scheduler/scheduling/pre-filter.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# prefilter #
# PreFilter 扩展点的执行 #

`sched.Algorithm.Schedule()` 中首先会做一些基本的检测,然后执行所有实现了 PreFilter 扩展点的插件。

Expand Down
79 changes: 79 additions & 0 deletions kube-scheduler/scheduling/pre-score.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# PreScore 扩展点的执行 #

PreScore 扩展点和 PreFilter 扩展点作用类似,一般也是用于数据的预处理,处理后将其存入调度框架的缓存中,然后供后续的 Score 扩展点的插件使用。

`sched.Algorithm.Schedule()` 中执行完 PreFilter 和 Filter 扩展点后会接着执行 PreScore 扩展点。

``` go
// Run "prescore" plugins.
prescoreStatus := prof.RunPreScorePlugins(ctx, state, pod, filteredNodes)
if !prescoreStatus.IsSuccess() {
return result, prescoreStatus.AsError()
}
trace.Step("Running prescore plugins done")
```

通过 Framework 的 `RunPreScorePlugins()` 执行。

``` go
func (f *framework) RunPreScorePlugins(
ctx context.Context,
state *CycleState,
pod *v1.Pod,
nodes []*v1.Node,
) (status *Status) {
startTime := time.Now()
defer func() {
metrics.FrameworkExtensionPointDuration.WithLabelValues(preScore, status.Code().String()).Observe(metrics.SinceInSeconds(startTime))
}()
for _, pl := range f.preScorePlugins {
status = f.runPreScorePlugin(ctx, pl, state, pod, nodes)
if !status.IsSuccess() {
msg := fmt.Sprintf("error while running %q prescore plugin for pod %q: %v", pl.Name(), pod.Name, status.Message())
klog.Error(msg)
return NewStatus(Error, msg)
}
}

return nil
}
```

会遍历 Framework 的 `preScorePlugins []PreScorePlugin` 字段,最终会执行到每个调度插件的 `PreScore()` 函数。

``` go
func (f *framework) runPreScorePlugin(ctx context.Context, pl PreScorePlugin, state *CycleState, pod *v1.Pod, nodes []*v1.Node) *Status {
if !state.ShouldRecordPluginMetrics() {
return pl.PreScore(ctx, state, pod, nodes)
}
startTime := time.Now()
status := pl.PreScore(ctx, state, pod, nodes)
f.metricsRecorder.observePluginDurationAsync(preScore, pl.Name(), status, metrics.SinceInSeconds(startTime))
return status
}
```

[SelectorSpread](../scheduler-plugins/selector-spread.md) 插件为例,它的 PreScore 扩展点所做的操作就是根据当前 Pod 的 Label 找出包含此 Pod 的 "上级" 资源的 Label,并将结果存入到调度缓存中,在此插件的 Score 扩展点会取回这些信息然后进一步进行处理。

``` go
func (pl *SelectorSpread) PreScore(ctx context.Context, cycleState *framework.CycleState, pod *v1.Pod, nodes []*v1.Node) *framework.Status {
if skipSelectorSpread(pod) {
return nil
}
var selector labels.Selector
selector = helper.DefaultSelector(
pod,
pl.services,
pl.replicationControllers,
pl.replicaSets,
pl.statefulSets,
)
state := &preScoreState{
selector: selector,
}
cycleState.Write(preScoreStateKey, state)
return nil
}
```

下一节会对 Score 扩展点的执行进行分析。

0 comments on commit 2e2204e

Please sign in to comment.