Skip to content

Commit 089e85e

Browse files
author
draveness
committed
feat: convert selector spread priority to score plugin
1 parent f35a92c commit 089e85e

File tree

7 files changed

+830
-14
lines changed

7 files changed

+830
-14
lines changed

pkg/scheduler/apis/config/testing/compatibility_test.go

Lines changed: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,6 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
149149
),
150150
wantPrioritizers: sets.NewString(
151151
"EqualPriority",
152-
"SelectorSpreadPriority",
153152
"TestServiceAntiAffinity",
154153
),
155154
wantPlugins: map[string][]config.Plugin{
@@ -167,6 +166,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
167166
{Name: "NodeResourcesBalancedAllocation", Weight: 2},
168167
{Name: "NodeResourcesLeastAllocated", Weight: 2},
169168
{Name: "NodeLabel", Weight: 4},
169+
{Name: "DefaultPodTopologySpread", Weight: 2},
170170
},
171171
},
172172
},
@@ -205,7 +205,6 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
205205
),
206206
wantPrioritizers: sets.NewString(
207207
"EqualPriority",
208-
"SelectorSpreadPriority",
209208
"TestServiceAntiAffinity",
210209
),
211210
wantPlugins: map[string][]config.Plugin{
@@ -229,6 +228,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
229228
{Name: "NodeResourcesLeastAllocated", Weight: 2},
230229
{Name: "NodeAffinity", Weight: 2},
231230
{Name: "NodeLabel", Weight: 4},
231+
{Name: "DefaultPodTopologySpread", Weight: 2},
232232
},
233233
},
234234
},
@@ -270,7 +270,6 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
270270
),
271271
wantPrioritizers: sets.NewString(
272272
"EqualPriority",
273-
"SelectorSpreadPriority",
274273
"InterPodAffinityPriority",
275274
),
276275
wantPlugins: map[string][]config.Plugin{
@@ -294,6 +293,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
294293
{Name: "ImageLocality", Weight: 2},
295294
{Name: "NodeResourcesLeastAllocated", Weight: 2},
296295
{Name: "NodeAffinity", Weight: 2},
296+
{Name: "DefaultPodTopologySpread", Weight: 2},
297297
{Name: "TaintToleration", Weight: 2},
298298
},
299299
},
@@ -338,7 +338,6 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
338338
),
339339
wantPrioritizers: sets.NewString(
340340
"EqualPriority",
341-
"SelectorSpreadPriority",
342341
"InterPodAffinityPriority",
343342
),
344343
wantPlugins: map[string][]config.Plugin{
@@ -364,6 +363,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
364363
{Name: "NodeResourcesMostAllocated", Weight: 2},
365364
{Name: "NodeAffinity", Weight: 2},
366365
{Name: "NodePreferAvoidPods", Weight: 2},
366+
{Name: "DefaultPodTopologySpread", Weight: 2},
367367
{Name: "TaintToleration", Weight: 2},
368368
},
369369
},
@@ -417,7 +417,6 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
417417
),
418418
wantPrioritizers: sets.NewString(
419419
"EqualPriority",
420-
"SelectorSpreadPriority",
421420
"InterPodAffinityPriority",
422421
),
423422
wantPlugins: map[string][]config.Plugin{
@@ -443,6 +442,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
443442
{Name: "NodeResourcesMostAllocated", Weight: 2},
444443
{Name: "NodeAffinity", Weight: 2},
445444
{Name: "NodePreferAvoidPods", Weight: 2},
445+
{Name: "DefaultPodTopologySpread", Weight: 2},
446446
{Name: "TaintToleration", Weight: 2},
447447
},
448448
},
@@ -507,7 +507,6 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
507507
),
508508
wantPrioritizers: sets.NewString(
509509
"EqualPriority",
510-
"SelectorSpreadPriority",
511510
"InterPodAffinityPriority",
512511
),
513512
wantPlugins: map[string][]config.Plugin{
@@ -533,6 +532,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
533532
{Name: "NodeResourcesMostAllocated", Weight: 2},
534533
{Name: "NodeAffinity", Weight: 2},
535534
{Name: "NodePreferAvoidPods", Weight: 2},
535+
{Name: "DefaultPodTopologySpread", Weight: 2},
536536
{Name: "TaintToleration", Weight: 2},
537537
},
538538
},
@@ -598,7 +598,6 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
598598
),
599599
wantPrioritizers: sets.NewString(
600600
"EqualPriority",
601-
"SelectorSpreadPriority",
602601
"InterPodAffinityPriority",
603602
),
604603
wantPlugins: map[string][]config.Plugin{
@@ -625,6 +624,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
625624
{Name: "NodeResourcesMostAllocated", Weight: 2},
626625
{Name: "NodeAffinity", Weight: 2},
627626
{Name: "NodePreferAvoidPods", Weight: 2},
627+
{Name: "DefaultPodTopologySpread", Weight: 2},
628628
{Name: "TaintToleration", Weight: 2},
629629
},
630630
},
@@ -693,7 +693,6 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
693693
),
694694
wantPrioritizers: sets.NewString(
695695
"EqualPriority",
696-
"SelectorSpreadPriority",
697696
"InterPodAffinityPriority",
698697
),
699698
wantPlugins: map[string][]config.Plugin{
@@ -720,6 +719,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
720719
{Name: "NodeResourcesMostAllocated", Weight: 2},
721720
{Name: "NodeAffinity", Weight: 2},
722721
{Name: "NodePreferAvoidPods", Weight: 2},
722+
{Name: "DefaultPodTopologySpread", Weight: 2},
723723
{Name: "TaintToleration", Weight: 2},
724724
},
725725
},
@@ -800,7 +800,6 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
800800
),
801801
wantPrioritizers: sets.NewString(
802802
"EqualPriority",
803-
"SelectorSpreadPriority",
804803
"InterPodAffinityPriority",
805804
),
806805
wantPlugins: map[string][]config.Plugin{
@@ -828,6 +827,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
828827
{Name: "NodeAffinity", Weight: 2},
829828
{Name: "NodePreferAvoidPods", Weight: 2},
830829
{Name: "RequestedToCapacityRatio", Weight: 2},
830+
{Name: "DefaultPodTopologySpread", Weight: 2},
831831
{Name: "TaintToleration", Weight: 2},
832832
},
833833
},
@@ -909,7 +909,6 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
909909
),
910910
wantPrioritizers: sets.NewString(
911911
"EqualPriority",
912-
"SelectorSpreadPriority",
913912
"InterPodAffinityPriority",
914913
),
915914
wantPlugins: map[string][]config.Plugin{
@@ -938,6 +937,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
938937
{Name: "NodeAffinity", Weight: 2},
939938
{Name: "NodePreferAvoidPods", Weight: 2},
940939
{Name: "RequestedToCapacityRatio", Weight: 2},
940+
{Name: "DefaultPodTopologySpread", Weight: 2},
941941
{Name: "TaintToleration", Weight: 2},
942942
},
943943
},
@@ -1018,7 +1018,6 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
10181018
),
10191019
wantPrioritizers: sets.NewString(
10201020
"EqualPriority",
1021-
"SelectorSpreadPriority",
10221021
"InterPodAffinityPriority",
10231022
),
10241023
wantPlugins: map[string][]config.Plugin{
@@ -1048,6 +1047,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
10481047
{Name: "NodeAffinity", Weight: 2},
10491048
{Name: "NodePreferAvoidPods", Weight: 2},
10501049
{Name: "RequestedToCapacityRatio", Weight: 2},
1050+
{Name: "DefaultPodTopologySpread", Weight: 2},
10511051
{Name: "TaintToleration", Weight: 2},
10521052
},
10531053
},
@@ -1132,7 +1132,6 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
11321132
),
11331133
wantPrioritizers: sets.NewString(
11341134
"EqualPriority",
1135-
"SelectorSpreadPriority",
11361135
"InterPodAffinityPriority",
11371136
),
11381137
wantPlugins: map[string][]config.Plugin{
@@ -1162,6 +1161,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
11621161
{Name: "NodeAffinity", Weight: 2},
11631162
{Name: "NodePreferAvoidPods", Weight: 2},
11641163
{Name: "RequestedToCapacityRatio", Weight: 2},
1164+
{Name: "DefaultPodTopologySpread", Weight: 2},
11651165
{Name: "TaintToleration", Weight: 2},
11661166
},
11671167
},
@@ -1255,6 +1255,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
12551255
"PodTopologySpread": "EvenPodsSpread",
12561256
}
12571257
scoreToPriorityMap := map[string]string{
1258+
"DefaultPodTopologySpread": "SelectorSpreadPriority",
12581259
"ImageLocality": "ImageLocalityPriority",
12591260
"NodeAffinity": "NodeAffinityPriority",
12601261
"NodePreferAvoidPods": "NodePreferAvoidPodsPriority",

pkg/scheduler/framework/plugins/BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ go_library(
99
"//pkg/scheduler/algorithm/predicates:go_default_library",
1010
"//pkg/scheduler/algorithm/priorities:go_default_library",
1111
"//pkg/scheduler/apis/config:go_default_library",
12+
"//pkg/scheduler/framework/plugins/defaultpodtopologyspread:go_default_library",
1213
"//pkg/scheduler/framework/plugins/imagelocality:go_default_library",
1314
"//pkg/scheduler/framework/plugins/interpodaffinity:go_default_library",
1415
"//pkg/scheduler/framework/plugins/nodeaffinity:go_default_library",
@@ -43,6 +44,7 @@ filegroup(
4344
name = "all-srcs",
4445
srcs = [
4546
":package-srcs",
47+
"//pkg/scheduler/framework/plugins/defaultpodtopologyspread:all-srcs",
4648
"//pkg/scheduler/framework/plugins/examples:all-srcs",
4749
"//pkg/scheduler/framework/plugins/imagelocality:all-srcs",
4850
"//pkg/scheduler/framework/plugins/interpodaffinity:all-srcs",

pkg/scheduler/framework/plugins/default_registry.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import (
2525
"k8s.io/kubernetes/pkg/scheduler/algorithm/predicates"
2626
"k8s.io/kubernetes/pkg/scheduler/algorithm/priorities"
2727
"k8s.io/kubernetes/pkg/scheduler/apis/config"
28+
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultpodtopologyspread"
2829
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/imagelocality"
2930
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/interpodaffinity"
3031
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeaffinity"
@@ -55,6 +56,7 @@ type RegistryArgs struct {
5556
// plugins can register additional plugins through the WithFrameworkOutOfTreeRegistry option.
5657
func NewDefaultRegistry(args *RegistryArgs) framework.Registry {
5758
return framework.Registry{
59+
defaultpodtopologyspread.Name: defaultpodtopologyspread.New,
5860
imagelocality.Name: imagelocality.New,
5961
tainttoleration.Name: tainttoleration.New,
6062
nodename.Name: nodename.New,
@@ -209,6 +211,11 @@ func NewDefaultConfigProducerRegistry() *ConfigProducerRegistry {
209211
})
210212

211213
// Register Priorities.
214+
registry.RegisterPriority(priorities.SelectorSpreadPriority,
215+
func(args ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
216+
plugins.Score = appendToPluginSet(plugins.Score, defaultpodtopologyspread.Name, &args.Weight)
217+
return
218+
})
212219
registry.RegisterPriority(priorities.TaintTolerationPriority,
213220
func(args ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
214221
plugins.Score = appendToPluginSet(plugins.Score, tainttoleration.Name, &args.Weight)
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
2+
3+
go_library(
4+
name = "go_default_library",
5+
srcs = ["default_pod_topology_spread.go"],
6+
importpath = "k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultpodtopologyspread",
7+
visibility = ["//visibility:public"],
8+
deps = [
9+
"//pkg/scheduler/algorithm/priorities:go_default_library",
10+
"//pkg/scheduler/framework/plugins/migration:go_default_library",
11+
"//pkg/scheduler/framework/v1alpha1:go_default_library",
12+
"//staging/src/k8s.io/api/core/v1:go_default_library",
13+
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
14+
],
15+
)
16+
17+
go_test(
18+
name = "go_default_test",
19+
srcs = ["default_pod_topology_spread_test.go"],
20+
embed = [":go_default_library"],
21+
deps = [
22+
"//pkg/scheduler/algorithm/priorities:go_default_library",
23+
"//pkg/scheduler/framework/plugins/migration:go_default_library",
24+
"//pkg/scheduler/framework/v1alpha1:go_default_library",
25+
"//pkg/scheduler/listers/fake:go_default_library",
26+
"//pkg/scheduler/nodeinfo/snapshot:go_default_library",
27+
"//staging/src/k8s.io/api/apps/v1:go_default_library",
28+
"//staging/src/k8s.io/api/core/v1:go_default_library",
29+
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
30+
],
31+
)
32+
33+
filegroup(
34+
name = "package-srcs",
35+
srcs = glob(["**"]),
36+
tags = ["automanaged"],
37+
visibility = ["//visibility:private"],
38+
)
39+
40+
filegroup(
41+
name = "all-srcs",
42+
srcs = [":package-srcs"],
43+
tags = ["automanaged"],
44+
visibility = ["//visibility:public"],
45+
)
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
Copyright 2019 The Kubernetes Authors.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package defaultpodtopologyspread
18+
19+
import (
20+
"context"
21+
"fmt"
22+
23+
v1 "k8s.io/api/core/v1"
24+
"k8s.io/apimachinery/pkg/runtime"
25+
"k8s.io/kubernetes/pkg/scheduler/algorithm/priorities"
26+
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/migration"
27+
framework "k8s.io/kubernetes/pkg/scheduler/framework/v1alpha1"
28+
)
29+
30+
// DefaultPodTopologySpread is a plugin that calculates selector spread priority.
31+
type DefaultPodTopologySpread struct {
32+
handle framework.FrameworkHandle
33+
calculateSpreadPriorityMap priorities.PriorityMapFunction
34+
calculateSpreadPriorityReduce priorities.PriorityReduceFunction
35+
}
36+
37+
var _ framework.ScorePlugin = &DefaultPodTopologySpread{}
38+
39+
// Name is the name of the plugin used in the plugin registry and configurations.
40+
const Name = "DefaultPodTopologySpread"
41+
42+
// Name returns name of the plugin. It is used in logs, etc.
43+
func (pl *DefaultPodTopologySpread) Name() string {
44+
return Name
45+
}
46+
47+
// Score invoked at the Score extension point.
48+
// The "score" returned in this function is the matching number of pods on the `nodeName`,
49+
// it is normalized later.
50+
func (pl *DefaultPodTopologySpread) Score(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeName string) (int64, *framework.Status) {
51+
nodeInfo, err := pl.handle.SnapshotSharedLister().NodeInfos().Get(nodeName)
52+
if err != nil {
53+
return 0, framework.NewStatus(framework.Error, fmt.Sprintf("getting node %q from Snapshot: %v", nodeName, err))
54+
}
55+
56+
meta := migration.PriorityMetadata(state)
57+
s, err := pl.calculateSpreadPriorityMap(pod, meta, nodeInfo)
58+
return s.Score, migration.ErrorToFrameworkStatus(err)
59+
}
60+
61+
// NormalizeScore invoked after scoring all nodes.
62+
func (pl *DefaultPodTopologySpread) NormalizeScore(ctx context.Context, state *framework.CycleState, pod *v1.Pod, scores framework.NodeScoreList) *framework.Status {
63+
meta := migration.PriorityMetadata(state)
64+
err := pl.calculateSpreadPriorityReduce(pod, meta, pl.handle.SnapshotSharedLister(), scores)
65+
return migration.ErrorToFrameworkStatus(err)
66+
}
67+
68+
// ScoreExtensions of the Score plugin.
69+
func (pl *DefaultPodTopologySpread) ScoreExtensions() framework.ScoreExtensions {
70+
return pl
71+
}
72+
73+
// New initializes a new plugin and returns it.
74+
func New(_ *runtime.Unknown, handle framework.FrameworkHandle) (framework.Plugin, error) {
75+
informerFactory := handle.SharedInformerFactory()
76+
calculateSpreadPriorityMap, calculateSpreadPriorityReduce := priorities.NewSelectorSpreadPriority(
77+
informerFactory.Core().V1().Services().Lister(),
78+
informerFactory.Core().V1().ReplicationControllers().Lister(),
79+
informerFactory.Apps().V1().ReplicaSets().Lister(),
80+
informerFactory.Apps().V1().StatefulSets().Lister(),
81+
)
82+
83+
return &DefaultPodTopologySpread{
84+
handle: handle,
85+
calculateSpreadPriorityMap: calculateSpreadPriorityMap,
86+
calculateSpreadPriorityReduce: calculateSpreadPriorityReduce,
87+
}, nil
88+
}

0 commit comments

Comments
 (0)