Skip to content

Commit dd5cb64

Browse files
authored
Merge pull request kubernetes#83849 from draveness/feature/node-locality-as-score-plugin
feat: implement imagelocality as a score plugin
2 parents a783404 + 6f6618f commit dd5cb64

File tree

8 files changed

+405
-27
lines changed

8 files changed

+405
-27
lines changed

pkg/scheduler/api/compatibility/compatibility_test.go

Lines changed: 45 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,6 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
171171
wantPrioritizers: sets.NewString(
172172
"EqualPriority",
173173
"NodeAffinityPriority",
174-
"ImageLocalityPriority",
175174
"LeastRequestedPriority",
176175
"BalancedResourceAllocation",
177176
"SelectorSpreadPriority",
@@ -185,6 +184,9 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
185184
{Name: "NodeResources"},
186185
{Name: "VolumeRestrictions"},
187186
},
187+
"ScorePlugin": {
188+
{Name: "ImageLocality", Weight: 2},
189+
},
188190
},
189191
},
190192

@@ -235,7 +237,6 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
235237
),
236238
wantPrioritizers: sets.NewString(
237239
"EqualPriority",
238-
"ImageLocalityPriority",
239240
"LeastRequestedPriority",
240241
"BalancedResourceAllocation",
241242
"SelectorSpreadPriority",
@@ -250,7 +251,10 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
250251
{Name: "VolumeRestrictions"},
251252
{Name: "TaintToleration"},
252253
},
253-
"ScorePlugin": {{Name: "TaintToleration", Weight: 2}},
254+
"ScorePlugin": {
255+
{Name: "ImageLocality", Weight: 2},
256+
{Name: "TaintToleration", Weight: 2},
257+
},
254258
},
255259
},
256260

@@ -305,7 +309,6 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
305309
),
306310
wantPrioritizers: sets.NewString(
307311
"EqualPriority",
308-
"ImageLocalityPriority",
309312
"LeastRequestedPriority",
310313
"BalancedResourceAllocation",
311314
"SelectorSpreadPriority",
@@ -322,7 +325,10 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
322325
{Name: "VolumeRestrictions"},
323326
{Name: "TaintToleration"},
324327
},
325-
"ScorePlugin": {{Name: "TaintToleration", Weight: 2}},
328+
"ScorePlugin": {
329+
{Name: "ImageLocality", Weight: 2},
330+
{Name: "TaintToleration", Weight: 2},
331+
},
326332
},
327333
},
328334
// Do not change this JSON after the corresponding release has been tagged.
@@ -386,7 +392,6 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
386392
),
387393
wantPrioritizers: sets.NewString(
388394
"EqualPriority",
389-
"ImageLocalityPriority",
390395
"LeastRequestedPriority",
391396
"BalancedResourceAllocation",
392397
"SelectorSpreadPriority",
@@ -403,7 +408,10 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
403408
{Name: "VolumeRestrictions"},
404409
{Name: "TaintToleration"},
405410
},
406-
"ScorePlugin": {{Name: "TaintToleration", Weight: 2}},
411+
"ScorePlugin": {
412+
{Name: "ImageLocality", Weight: 2},
413+
{Name: "TaintToleration", Weight: 2},
414+
},
407415
},
408416
wantExtenders: []schedulerapi.ExtenderConfig{{
409417
URLPrefix: "/prefix",
@@ -480,7 +488,6 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
480488
),
481489
wantPrioritizers: sets.NewString(
482490
"EqualPriority",
483-
"ImageLocalityPriority",
484491
"LeastRequestedPriority",
485492
"BalancedResourceAllocation",
486493
"SelectorSpreadPriority",
@@ -497,7 +504,10 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
497504
{Name: "VolumeRestrictions"},
498505
{Name: "TaintToleration"},
499506
},
500-
"ScorePlugin": {{Name: "TaintToleration", Weight: 2}},
507+
"ScorePlugin": {
508+
{Name: "ImageLocality", Weight: 2},
509+
{Name: "TaintToleration", Weight: 2},
510+
},
501511
},
502512
wantExtenders: []schedulerapi.ExtenderConfig{{
503513
URLPrefix: "/prefix",
@@ -575,7 +585,6 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
575585
),
576586
wantPrioritizers: sets.NewString(
577587
"EqualPriority",
578-
"ImageLocalityPriority",
579588
"LeastRequestedPriority",
580589
"BalancedResourceAllocation",
581590
"SelectorSpreadPriority",
@@ -593,7 +602,10 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
593602
{Name: "TaintToleration"},
594603
{Name: "VolumeBinding"},
595604
},
596-
"ScorePlugin": {{Name: "TaintToleration", Weight: 2}},
605+
"ScorePlugin": {
606+
{Name: "ImageLocality", Weight: 2},
607+
{Name: "TaintToleration", Weight: 2},
608+
},
597609
},
598610
wantExtenders: []schedulerapi.ExtenderConfig{{
599611
URLPrefix: "/prefix",
@@ -676,7 +688,6 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
676688
),
677689
wantPrioritizers: sets.NewString(
678690
"EqualPriority",
679-
"ImageLocalityPriority",
680691
"LeastRequestedPriority",
681692
"BalancedResourceAllocation",
682693
"SelectorSpreadPriority",
@@ -694,7 +705,10 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
694705
{Name: "TaintToleration"},
695706
{Name: "VolumeBinding"},
696707
},
697-
"ScorePlugin": {{Name: "TaintToleration", Weight: 2}},
708+
"ScorePlugin": {
709+
{Name: "ImageLocality", Weight: 2},
710+
{Name: "TaintToleration", Weight: 2},
711+
},
698712
},
699713
wantExtenders: []schedulerapi.ExtenderConfig{{
700714
URLPrefix: "/prefix",
@@ -789,7 +803,6 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
789803
),
790804
wantPrioritizers: sets.NewString(
791805
"EqualPriority",
792-
"ImageLocalityPriority",
793806
"LeastRequestedPriority",
794807
"BalancedResourceAllocation",
795808
"SelectorSpreadPriority",
@@ -808,7 +821,10 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
808821
{Name: "TaintToleration"},
809822
{Name: "VolumeBinding"},
810823
},
811-
"ScorePlugin": {{Name: "TaintToleration", Weight: 2}},
824+
"ScorePlugin": {
825+
{Name: "ImageLocality", Weight: 2},
826+
{Name: "TaintToleration", Weight: 2},
827+
},
812828
},
813829
wantExtenders: []schedulerapi.ExtenderConfig{{
814830
URLPrefix: "/prefix",
@@ -905,7 +921,6 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
905921
),
906922
wantPrioritizers: sets.NewString(
907923
"EqualPriority",
908-
"ImageLocalityPriority",
909924
"LeastRequestedPriority",
910925
"BalancedResourceAllocation",
911926
"SelectorSpreadPriority",
@@ -924,7 +939,10 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
924939
{Name: "TaintToleration"},
925940
{Name: "VolumeBinding"},
926941
},
927-
"ScorePlugin": {{Name: "TaintToleration", Weight: 2}},
942+
"ScorePlugin": {
943+
{Name: "ImageLocality", Weight: 2},
944+
{Name: "TaintToleration", Weight: 2},
945+
},
928946
},
929947
wantExtenders: []schedulerapi.ExtenderConfig{{
930948
URLPrefix: "/prefix",
@@ -1021,7 +1039,6 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
10211039
),
10221040
wantPrioritizers: sets.NewString(
10231041
"EqualPriority",
1024-
"ImageLocalityPriority",
10251042
"LeastRequestedPriority",
10261043
"BalancedResourceAllocation",
10271044
"SelectorSpreadPriority",
@@ -1040,7 +1057,10 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
10401057
{Name: "TaintToleration"},
10411058
{Name: "VolumeBinding"},
10421059
},
1043-
"ScorePlugin": {{Name: "TaintToleration", Weight: 2}},
1060+
"ScorePlugin": {
1061+
{Name: "ImageLocality", Weight: 2},
1062+
{Name: "TaintToleration", Weight: 2},
1063+
},
10441064
},
10451065
wantExtenders: []schedulerapi.ExtenderConfig{{
10461066
URLPrefix: "/prefix",
@@ -1141,7 +1161,6 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
11411161
),
11421162
wantPrioritizers: sets.NewString(
11431163
"EqualPriority",
1144-
"ImageLocalityPriority",
11451164
"LeastRequestedPriority",
11461165
"BalancedResourceAllocation",
11471166
"SelectorSpreadPriority",
@@ -1160,7 +1179,10 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
11601179
{Name: "TaintToleration"},
11611180
{Name: "VolumeBinding"},
11621181
},
1163-
"ScorePlugin": {{Name: "TaintToleration", Weight: 2}},
1182+
"ScorePlugin": {
1183+
{Name: "ImageLocality", Weight: 2},
1184+
{Name: "TaintToleration", Weight: 2},
1185+
},
11641186
},
11651187
wantExtenders: []schedulerapi.ExtenderConfig{{
11661188
URLPrefix: "/prefix",
@@ -1192,6 +1214,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
11921214
}
11931215
scoreToPriorityMap := map[string]string{
11941216
"TaintToleration": "TaintTolerationPriority",
1217+
"ImageLocality": "ImageLocalityPriority",
11951218
}
11961219

11971220
for v, tc := range schedulerFiles {
@@ -1245,7 +1268,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
12451268
seenPredicates.Insert(filterToPredicateMap[p.Name])
12461269

12471270
}
1248-
for _, p := range gotPlugins["FilterPlugin"] {
1271+
for _, p := range gotPlugins["ScorePlugin"] {
12491272
seenPriorities.Insert(scoreToPriorityMap[p.Name])
12501273

12511274
}

pkg/scheduler/framework/plugins/BUILD

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ go_library(
1010
"//pkg/scheduler/algorithm/predicates:go_default_library",
1111
"//pkg/scheduler/algorithm/priorities:go_default_library",
1212
"//pkg/scheduler/apis/config:go_default_library",
13+
"//pkg/scheduler/framework/plugins/imagelocality:go_default_library",
1314
"//pkg/scheduler/framework/plugins/nodeaffinity:go_default_library",
1415
"//pkg/scheduler/framework/plugins/nodename:go_default_library",
1516
"//pkg/scheduler/framework/plugins/noderesources:go_default_library",
@@ -37,6 +38,7 @@ filegroup(
3738
srcs = [
3839
":package-srcs",
3940
"//pkg/scheduler/framework/plugins/examples:all-srcs",
41+
"//pkg/scheduler/framework/plugins/imagelocality:all-srcs",
4042
"//pkg/scheduler/framework/plugins/migration:all-srcs",
4143
"//pkg/scheduler/framework/plugins/nodeaffinity:all-srcs",
4244
"//pkg/scheduler/framework/plugins/nodename:all-srcs",

pkg/scheduler/framework/plugins/default_registry.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import (
2626
"k8s.io/kubernetes/pkg/scheduler/algorithm/predicates"
2727
"k8s.io/kubernetes/pkg/scheduler/algorithm/priorities"
2828
"k8s.io/kubernetes/pkg/scheduler/apis/config"
29+
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/imagelocality"
2930
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeaffinity"
3031
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodename"
3132
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources"
@@ -56,6 +57,7 @@ type RegistryArgs struct {
5657
// runs custom plugins, can pass a different Registry when initializing the scheduler.
5758
func NewDefaultRegistry(args *RegistryArgs) framework.Registry {
5859
return framework.Registry{
60+
imagelocality.Name: imagelocality.New,
5961
tainttoleration.Name: tainttoleration.New,
6062
noderesources.Name: noderesources.New,
6163
nodename.Name: nodename.New,
@@ -128,6 +130,12 @@ func NewDefaultConfigProducerRegistry() *ConfigProducerRegistry {
128130
return
129131
})
130132

133+
registry.RegisterPriority(priorities.ImageLocalityPriority,
134+
func(args ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
135+
plugins.Score = appendToPluginSet(plugins.Score, imagelocality.Name, &args.Weight)
136+
return
137+
})
138+
131139
return registry
132140
}
133141

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
load("@io_bazel_rules_go//go:def.bzl", "go_library", "go_test")
2+
3+
go_library(
4+
name = "go_default_library",
5+
srcs = ["image_locality.go"],
6+
importpath = "k8s.io/kubernetes/pkg/scheduler/framework/plugins/imagelocality",
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 = ["image_locality_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/nodeinfo:go_default_library",
26+
"//pkg/scheduler/testing:go_default_library",
27+
"//pkg/util/parsers:go_default_library",
28+
"//staging/src/k8s.io/api/apps/v1:go_default_library",
29+
"//staging/src/k8s.io/api/core/v1:go_default_library",
30+
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
31+
],
32+
)
33+
34+
filegroup(
35+
name = "package-srcs",
36+
srcs = glob(["**"]),
37+
tags = ["automanaged"],
38+
visibility = ["//visibility:private"],
39+
)
40+
41+
filegroup(
42+
name = "all-srcs",
43+
srcs = [":package-srcs"],
44+
tags = ["automanaged"],
45+
visibility = ["//visibility:public"],
46+
)
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
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 imagelocality
18+
19+
import (
20+
"fmt"
21+
22+
v1 "k8s.io/api/core/v1"
23+
"k8s.io/apimachinery/pkg/runtime"
24+
"k8s.io/kubernetes/pkg/scheduler/algorithm/priorities"
25+
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/migration"
26+
framework "k8s.io/kubernetes/pkg/scheduler/framework/v1alpha1"
27+
)
28+
29+
var mb int64 = 1024 * 1024
30+
31+
// ImageLocality is a plugin that checks if a pod tolerates a node's taints.
32+
type ImageLocality struct {
33+
handle framework.FrameworkHandle
34+
}
35+
36+
var _ = framework.ScorePlugin(&ImageLocality{})
37+
38+
// Name is the name of the plugin used in the plugin registry and configurations.
39+
const Name = "ImageLocality"
40+
41+
// Name returns name of the plugin. It is used in logs, etc.
42+
func (pl *ImageLocality) Name() string {
43+
return Name
44+
}
45+
46+
// Score invoked at the score extension point.
47+
func (pl *ImageLocality) Score(state *framework.CycleState, pod *v1.Pod, nodeName string) (int64, *framework.Status) {
48+
nodeInfo, exist := pl.handle.NodeInfoSnapshot().NodeInfoMap[nodeName]
49+
if !exist {
50+
return 0, framework.NewStatus(framework.Error, fmt.Sprintf("node %q does not exist in NodeInfoSnapshot", nodeName))
51+
}
52+
53+
meta := migration.PriorityMetadata(state)
54+
s, err := priorities.ImageLocalityPriorityMap(pod, meta, nodeInfo)
55+
return s.Score, migration.ErrorToFrameworkStatus(err)
56+
}
57+
58+
// ScoreExtensions of the Score plugin.
59+
func (pl *ImageLocality) ScoreExtensions() framework.ScoreExtensions {
60+
return nil
61+
}
62+
63+
// New initializes a new plugin and returns it.
64+
func New(_ *runtime.Unknown, h framework.FrameworkHandle) (framework.Plugin, error) {
65+
return &ImageLocality{handle: h}, nil
66+
}

0 commit comments

Comments
 (0)