Skip to content

Commit 36acfec

Browse files
authored
Merge pull request kubernetes#84973 from draveness/feature/inter-pod-affinity-score
feat(scheduler): convert InterPodAffinity to score plugin
2 parents 36362cc + 7150683 commit 36acfec

File tree

6 files changed

+723
-48
lines changed

6 files changed

+723
-48
lines changed

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

Lines changed: 31 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -259,10 +259,8 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
259259
{"name": "InterPodAffinityPriority", "weight": 2}
260260
]
261261
}`,
262-
wantPredicates: sets.NewString(),
263-
wantPrioritizers: sets.NewString(
264-
"InterPodAffinityPriority",
265-
),
262+
wantPredicates: sets.NewString(),
263+
wantPrioritizers: sets.NewString(),
266264
wantPlugins: map[string][]config.Plugin{
267265
"FilterPlugin": {
268266
{Name: "NodeUnschedulable"},
@@ -283,6 +281,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
283281
"ScorePlugin": {
284282
{Name: "NodeResourcesBalancedAllocation", Weight: 2},
285283
{Name: "ImageLocality", Weight: 2},
284+
{Name: "InterPodAffinity", Weight: 2},
286285
{Name: "NodeResourcesLeastAllocated", Weight: 2},
287286
{Name: "NodeAffinity", Weight: 2},
288287
{Name: "DefaultPodTopologySpread", Weight: 2},
@@ -325,10 +324,8 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
325324
{"name": "MostRequestedPriority", "weight": 2}
326325
]
327326
}`,
328-
wantPredicates: sets.NewString(),
329-
wantPrioritizers: sets.NewString(
330-
"InterPodAffinityPriority",
331-
),
327+
wantPredicates: sets.NewString(),
328+
wantPrioritizers: sets.NewString(),
332329
wantPlugins: map[string][]config.Plugin{
333330
"FilterPlugin": {
334331
{Name: "NodeUnschedulable"},
@@ -349,6 +346,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
349346
"ScorePlugin": {
350347
{Name: "NodeResourcesBalancedAllocation", Weight: 2},
351348
{Name: "ImageLocality", Weight: 2},
349+
{Name: "InterPodAffinity", Weight: 2},
352350
{Name: "NodeResourcesLeastAllocated", Weight: 2},
353351
{Name: "NodeResourcesMostAllocated", Weight: 2},
354352
{Name: "NodeAffinity", Weight: 2},
@@ -402,10 +400,8 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
402400
"nodeCacheCapable": true
403401
}]
404402
}`,
405-
wantPredicates: sets.NewString(),
406-
wantPrioritizers: sets.NewString(
407-
"InterPodAffinityPriority",
408-
),
403+
wantPredicates: sets.NewString(),
404+
wantPrioritizers: sets.NewString(),
409405
wantPlugins: map[string][]config.Plugin{
410406
"FilterPlugin": {
411407
{Name: "NodeUnschedulable"},
@@ -426,6 +422,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
426422
"ScorePlugin": {
427423
{Name: "NodeResourcesBalancedAllocation", Weight: 2},
428424
{Name: "ImageLocality", Weight: 2},
425+
{Name: "InterPodAffinity", Weight: 2},
429426
{Name: "NodeResourcesLeastAllocated", Weight: 2},
430427
{Name: "NodeResourcesMostAllocated", Weight: 2},
431428
{Name: "NodeAffinity", Weight: 2},
@@ -490,10 +487,8 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
490487
"nodeCacheCapable": true
491488
}]
492489
}`,
493-
wantPredicates: sets.NewString(),
494-
wantPrioritizers: sets.NewString(
495-
"InterPodAffinityPriority",
496-
),
490+
wantPredicates: sets.NewString(),
491+
wantPrioritizers: sets.NewString(),
497492
wantPlugins: map[string][]config.Plugin{
498493
"FilterPlugin": {
499494
{Name: "NodeUnschedulable"},
@@ -514,6 +509,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
514509
"ScorePlugin": {
515510
{Name: "NodeResourcesBalancedAllocation", Weight: 2},
516511
{Name: "ImageLocality", Weight: 2},
512+
{Name: "InterPodAffinity", Weight: 2},
517513
{Name: "NodeResourcesLeastAllocated", Weight: 2},
518514
{Name: "NodeResourcesMostAllocated", Weight: 2},
519515
{Name: "NodeAffinity", Weight: 2},
@@ -579,10 +575,8 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
579575
"nodeCacheCapable": true
580576
}]
581577
}`,
582-
wantPredicates: sets.NewString(),
583-
wantPrioritizers: sets.NewString(
584-
"InterPodAffinityPriority",
585-
),
578+
wantPredicates: sets.NewString(),
579+
wantPrioritizers: sets.NewString(),
586580
wantPlugins: map[string][]config.Plugin{
587581
"FilterPlugin": {
588582
{Name: "NodeUnschedulable"},
@@ -604,6 +598,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
604598
"ScorePlugin": {
605599
{Name: "NodeResourcesBalancedAllocation", Weight: 2},
606600
{Name: "ImageLocality", Weight: 2},
601+
{Name: "InterPodAffinity", Weight: 2},
607602
{Name: "NodeResourcesLeastAllocated", Weight: 2},
608603
{Name: "NodeResourcesMostAllocated", Weight: 2},
609604
{Name: "NodeAffinity", Weight: 2},
@@ -672,10 +667,8 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
672667
"ignorable":true
673668
}]
674669
}`,
675-
wantPredicates: sets.NewString(),
676-
wantPrioritizers: sets.NewString(
677-
"InterPodAffinityPriority",
678-
),
670+
wantPredicates: sets.NewString(),
671+
wantPrioritizers: sets.NewString(),
679672
wantPlugins: map[string][]config.Plugin{
680673
"FilterPlugin": {
681674
{Name: "NodeUnschedulable"},
@@ -697,6 +690,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
697690
"ScorePlugin": {
698691
{Name: "NodeResourcesBalancedAllocation", Weight: 2},
699692
{Name: "ImageLocality", Weight: 2},
693+
{Name: "InterPodAffinity", Weight: 2},
700694
{Name: "NodeResourcesLeastAllocated", Weight: 2},
701695
{Name: "NodeResourcesMostAllocated", Weight: 2},
702696
{Name: "NodeAffinity", Weight: 2},
@@ -777,10 +771,8 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
777771
"ignorable":true
778772
}]
779773
}`,
780-
wantPredicates: sets.NewString(),
781-
wantPrioritizers: sets.NewString(
782-
"InterPodAffinityPriority",
783-
),
774+
wantPredicates: sets.NewString(),
775+
wantPrioritizers: sets.NewString(),
784776
wantPlugins: map[string][]config.Plugin{
785777
"FilterPlugin": {
786778
{Name: "NodeUnschedulable"},
@@ -802,6 +794,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
802794
"ScorePlugin": {
803795
{Name: "NodeResourcesBalancedAllocation", Weight: 2},
804796
{Name: "ImageLocality", Weight: 2},
797+
{Name: "InterPodAffinity", Weight: 2},
805798
{Name: "NodeResourcesLeastAllocated", Weight: 2},
806799
{Name: "NodeResourcesMostAllocated", Weight: 2},
807800
{Name: "NodeAffinity", Weight: 2},
@@ -884,10 +877,8 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
884877
"ignorable":true
885878
}]
886879
}`,
887-
wantPredicates: sets.NewString(),
888-
wantPrioritizers: sets.NewString(
889-
"InterPodAffinityPriority",
890-
),
880+
wantPredicates: sets.NewString(),
881+
wantPrioritizers: sets.NewString(),
891882
wantPlugins: map[string][]config.Plugin{
892883
"FilterPlugin": {
893884
{Name: "NodeUnschedulable"},
@@ -910,6 +901,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
910901
"ScorePlugin": {
911902
{Name: "NodeResourcesBalancedAllocation", Weight: 2},
912903
{Name: "ImageLocality", Weight: 2},
904+
{Name: "InterPodAffinity", Weight: 2},
913905
{Name: "NodeResourcesLeastAllocated", Weight: 2},
914906
{Name: "NodeResourcesMostAllocated", Weight: 2},
915907
{Name: "NodeAffinity", Weight: 2},
@@ -991,10 +983,8 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
991983
"ignorable":true
992984
}]
993985
}`,
994-
wantPredicates: sets.NewString(),
995-
wantPrioritizers: sets.NewString(
996-
"InterPodAffinityPriority",
997-
),
986+
wantPredicates: sets.NewString(),
987+
wantPrioritizers: sets.NewString(),
998988
wantPlugins: map[string][]config.Plugin{
999989
"FilterPlugin": {
1000990
{Name: "NodeUnschedulable"},
@@ -1018,6 +1008,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
10181008
"ScorePlugin": {
10191009
{Name: "NodeResourcesBalancedAllocation", Weight: 2},
10201010
{Name: "ImageLocality", Weight: 2},
1011+
{Name: "InterPodAffinity", Weight: 2},
10211012
{Name: "NodeResourcesLeastAllocated", Weight: 2},
10221013
{Name: "NodeResourcesMostAllocated", Weight: 2},
10231014
{Name: "NodeAffinity", Weight: 2},
@@ -1103,10 +1094,8 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
11031094
"ignorable":true
11041095
}]
11051096
}`,
1106-
wantPredicates: sets.NewString(),
1107-
wantPrioritizers: sets.NewString(
1108-
"InterPodAffinityPriority",
1109-
),
1097+
wantPredicates: sets.NewString(),
1098+
wantPrioritizers: sets.NewString(),
11101099
wantPlugins: map[string][]config.Plugin{
11111100
"FilterPlugin": {
11121101
{Name: "NodeUnschedulable"},
@@ -1130,6 +1119,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
11301119
"ScorePlugin": {
11311120
{Name: "NodeResourcesBalancedAllocation", Weight: 2},
11321121
{Name: "ImageLocality", Weight: 2},
1122+
{Name: "InterPodAffinity", Weight: 2},
11331123
{Name: "NodeResourcesLeastAllocated", Weight: 2},
11341124
{Name: "NodeResourcesMostAllocated", Weight: 2},
11351125
{Name: "NodeAffinity", Weight: 2},
@@ -1231,6 +1221,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
12311221
scoreToPriorityMap := map[string]string{
12321222
"DefaultPodTopologySpread": "SelectorSpreadPriority",
12331223
"ImageLocality": "ImageLocalityPriority",
1224+
"InterPodAffinity": "InterPodAffinityPriority",
12341225
"NodeAffinity": "NodeAffinityPriority",
12351226
"NodePreferAvoidPods": "NodePreferAvoidPodsPriority",
12361227
"TaintToleration": "TaintTolerationPriority",

pkg/scheduler/framework/plugins/default_registry.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,11 @@ func NewDefaultConfigProducerRegistry() *ConfigProducerRegistry {
241241
plugins.Score = appendToPluginSet(plugins.Score, imagelocality.Name, &args.Weight)
242242
return
243243
})
244+
registry.RegisterPriority(priorities.InterPodAffinityPriority,
245+
func(args ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
246+
plugins.Score = appendToPluginSet(plugins.Score, interpodaffinity.Name, &args.Weight)
247+
return
248+
})
244249
registry.RegisterPriority(priorities.NodePreferAvoidPodsPriority,
245250
func(args ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) {
246251
plugins.Score = appendToPluginSet(plugins.Score, nodepreferavoidpods.Name, &args.Weight)

pkg/scheduler/framework/plugins/interpodaffinity/BUILD

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ go_library(
77
visibility = ["//visibility:public"],
88
deps = [
99
"//pkg/scheduler/algorithm/predicates:go_default_library",
10+
"//pkg/scheduler/algorithm/priorities:go_default_library",
1011
"//pkg/scheduler/framework/plugins/migration:go_default_library",
1112
"//pkg/scheduler/framework/v1alpha1:go_default_library",
1213
"//pkg/scheduler/nodeinfo:go_default_library",
@@ -21,11 +22,14 @@ go_test(
2122
embed = [":go_default_library"],
2223
deps = [
2324
"//pkg/scheduler/algorithm/predicates:go_default_library",
25+
"//pkg/scheduler/algorithm/priorities:go_default_library",
2426
"//pkg/scheduler/framework/plugins/migration:go_default_library",
2527
"//pkg/scheduler/framework/v1alpha1:go_default_library",
2628
"//pkg/scheduler/nodeinfo/snapshot:go_default_library",
2729
"//staging/src/k8s.io/api/core/v1:go_default_library",
2830
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
31+
"//staging/src/k8s.io/client-go/informers:go_default_library",
32+
"//staging/src/k8s.io/client-go/kubernetes/fake:go_default_library",
2933
],
3034
)
3135

pkg/scheduler/framework/plugins/interpodaffinity/interpod_affinity.go

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,20 +20,23 @@ import (
2020
"context"
2121
"fmt"
2222

23-
"k8s.io/api/core/v1"
23+
v1 "k8s.io/api/core/v1"
2424
"k8s.io/apimachinery/pkg/runtime"
2525
"k8s.io/kubernetes/pkg/scheduler/algorithm/predicates"
26+
"k8s.io/kubernetes/pkg/scheduler/algorithm/priorities"
2627
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/migration"
2728
framework "k8s.io/kubernetes/pkg/scheduler/framework/v1alpha1"
2829
"k8s.io/kubernetes/pkg/scheduler/nodeinfo"
2930
)
3031

3132
// InterPodAffinity is a plugin that checks inter pod affinity
3233
type InterPodAffinity struct {
34+
handle framework.FrameworkHandle
3335
predicate predicates.FitPredicate
3436
}
3537

3638
var _ framework.FilterPlugin = &InterPodAffinity{}
39+
var _ framework.ScorePlugin = &InterPodAffinity{}
3740

3841
// Name is the name of the plugin used in the plugin registry and configurations.
3942
const Name = "InterPodAffinity"
@@ -53,9 +56,36 @@ func (pl *InterPodAffinity) Filter(ctx context.Context, cycleState *framework.Cy
5356
return migration.PredicateResultToFrameworkStatus(reasons, err)
5457
}
5558

59+
// Score invoked at the Score extension point.
60+
// The "score" returned in this function is the matching number of pods on the `nodeName`,
61+
// it is normalized later.
62+
func (pl *InterPodAffinity) Score(ctx context.Context, state *framework.CycleState, pod *v1.Pod, nodeName string) (int64, *framework.Status) {
63+
nodeInfo, err := pl.handle.SnapshotSharedLister().NodeInfos().Get(nodeName)
64+
if err != nil {
65+
return 0, framework.NewStatus(framework.Error, fmt.Sprintf("getting node %q from Snapshot: %v", nodeName, err))
66+
}
67+
68+
meta := migration.PriorityMetadata(state)
69+
s, err := priorities.CalculateInterPodAffinityPriorityMap(pod, meta, nodeInfo)
70+
return s.Score, migration.ErrorToFrameworkStatus(err)
71+
}
72+
73+
// NormalizeScore invoked after scoring all nodes.
74+
func (pl *InterPodAffinity) NormalizeScore(ctx context.Context, state *framework.CycleState, pod *v1.Pod, scores framework.NodeScoreList) *framework.Status {
75+
meta := migration.PriorityMetadata(state)
76+
err := priorities.CalculateInterPodAffinityPriorityReduce(pod, meta, pl.handle.SnapshotSharedLister(), scores)
77+
return migration.ErrorToFrameworkStatus(err)
78+
}
79+
80+
// ScoreExtensions of the Score plugin.
81+
func (pl *InterPodAffinity) ScoreExtensions() framework.ScoreExtensions {
82+
return pl
83+
}
84+
5685
// New initializes a new plugin and returns it.
5786
func New(_ *runtime.Unknown, h framework.FrameworkHandle) (framework.Plugin, error) {
5887
return &InterPodAffinity{
88+
handle: h,
5989
predicate: predicates.NewPodAffinityPredicate(h.SnapshotSharedLister().NodeInfos(), h.SnapshotSharedLister().Pods()),
6090
}, nil
6191
}

0 commit comments

Comments
 (0)