Skip to content

Commit 7150683

Browse files
author
draveness
committed
feat(scheduler): convert InterPodAffinity to score plugin
1 parent 7b7aa58 commit 7150683

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
@@ -261,10 +261,8 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
261261
{"name": "InterPodAffinityPriority", "weight": 2}
262262
]
263263
}`,
264-
wantPredicates: sets.NewString(),
265-
wantPrioritizers: sets.NewString(
266-
"InterPodAffinityPriority",
267-
),
264+
wantPredicates: sets.NewString(),
265+
wantPrioritizers: sets.NewString(),
268266
wantPlugins: map[string][]config.Plugin{
269267
"FilterPlugin": {
270268
{Name: "NodeUnschedulable"},
@@ -285,6 +283,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
285283
"ScorePlugin": {
286284
{Name: "NodeResourcesBalancedAllocation", Weight: 2},
287285
{Name: "ImageLocality", Weight: 2},
286+
{Name: "InterPodAffinity", Weight: 2},
288287
{Name: "NodeResourcesLeastAllocated", Weight: 2},
289288
{Name: "NodeAffinity", Weight: 2},
290289
{Name: "DefaultPodTopologySpread", Weight: 2},
@@ -327,10 +326,8 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
327326
{"name": "MostRequestedPriority", "weight": 2}
328327
]
329328
}`,
330-
wantPredicates: sets.NewString(),
331-
wantPrioritizers: sets.NewString(
332-
"InterPodAffinityPriority",
333-
),
329+
wantPredicates: sets.NewString(),
330+
wantPrioritizers: sets.NewString(),
334331
wantPlugins: map[string][]config.Plugin{
335332
"FilterPlugin": {
336333
{Name: "NodeUnschedulable"},
@@ -351,6 +348,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
351348
"ScorePlugin": {
352349
{Name: "NodeResourcesBalancedAllocation", Weight: 2},
353350
{Name: "ImageLocality", Weight: 2},
351+
{Name: "InterPodAffinity", Weight: 2},
354352
{Name: "NodeResourcesLeastAllocated", Weight: 2},
355353
{Name: "NodeResourcesMostAllocated", Weight: 2},
356354
{Name: "NodeAffinity", Weight: 2},
@@ -404,10 +402,8 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
404402
"nodeCacheCapable": true
405403
}]
406404
}`,
407-
wantPredicates: sets.NewString(),
408-
wantPrioritizers: sets.NewString(
409-
"InterPodAffinityPriority",
410-
),
405+
wantPredicates: sets.NewString(),
406+
wantPrioritizers: sets.NewString(),
411407
wantPlugins: map[string][]config.Plugin{
412408
"FilterPlugin": {
413409
{Name: "NodeUnschedulable"},
@@ -428,6 +424,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
428424
"ScorePlugin": {
429425
{Name: "NodeResourcesBalancedAllocation", Weight: 2},
430426
{Name: "ImageLocality", Weight: 2},
427+
{Name: "InterPodAffinity", Weight: 2},
431428
{Name: "NodeResourcesLeastAllocated", Weight: 2},
432429
{Name: "NodeResourcesMostAllocated", Weight: 2},
433430
{Name: "NodeAffinity", Weight: 2},
@@ -492,10 +489,8 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
492489
"nodeCacheCapable": true
493490
}]
494491
}`,
495-
wantPredicates: sets.NewString(),
496-
wantPrioritizers: sets.NewString(
497-
"InterPodAffinityPriority",
498-
),
492+
wantPredicates: sets.NewString(),
493+
wantPrioritizers: sets.NewString(),
499494
wantPlugins: map[string][]config.Plugin{
500495
"FilterPlugin": {
501496
{Name: "NodeUnschedulable"},
@@ -516,6 +511,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
516511
"ScorePlugin": {
517512
{Name: "NodeResourcesBalancedAllocation", Weight: 2},
518513
{Name: "ImageLocality", Weight: 2},
514+
{Name: "InterPodAffinity", Weight: 2},
519515
{Name: "NodeResourcesLeastAllocated", Weight: 2},
520516
{Name: "NodeResourcesMostAllocated", Weight: 2},
521517
{Name: "NodeAffinity", Weight: 2},
@@ -581,10 +577,8 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
581577
"nodeCacheCapable": true
582578
}]
583579
}`,
584-
wantPredicates: sets.NewString(),
585-
wantPrioritizers: sets.NewString(
586-
"InterPodAffinityPriority",
587-
),
580+
wantPredicates: sets.NewString(),
581+
wantPrioritizers: sets.NewString(),
588582
wantPlugins: map[string][]config.Plugin{
589583
"FilterPlugin": {
590584
{Name: "NodeUnschedulable"},
@@ -606,6 +600,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
606600
"ScorePlugin": {
607601
{Name: "NodeResourcesBalancedAllocation", Weight: 2},
608602
{Name: "ImageLocality", Weight: 2},
603+
{Name: "InterPodAffinity", Weight: 2},
609604
{Name: "NodeResourcesLeastAllocated", Weight: 2},
610605
{Name: "NodeResourcesMostAllocated", Weight: 2},
611606
{Name: "NodeAffinity", Weight: 2},
@@ -674,10 +669,8 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
674669
"ignorable":true
675670
}]
676671
}`,
677-
wantPredicates: sets.NewString(),
678-
wantPrioritizers: sets.NewString(
679-
"InterPodAffinityPriority",
680-
),
672+
wantPredicates: sets.NewString(),
673+
wantPrioritizers: sets.NewString(),
681674
wantPlugins: map[string][]config.Plugin{
682675
"FilterPlugin": {
683676
{Name: "NodeUnschedulable"},
@@ -699,6 +692,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
699692
"ScorePlugin": {
700693
{Name: "NodeResourcesBalancedAllocation", Weight: 2},
701694
{Name: "ImageLocality", Weight: 2},
695+
{Name: "InterPodAffinity", Weight: 2},
702696
{Name: "NodeResourcesLeastAllocated", Weight: 2},
703697
{Name: "NodeResourcesMostAllocated", Weight: 2},
704698
{Name: "NodeAffinity", Weight: 2},
@@ -779,10 +773,8 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
779773
"ignorable":true
780774
}]
781775
}`,
782-
wantPredicates: sets.NewString(),
783-
wantPrioritizers: sets.NewString(
784-
"InterPodAffinityPriority",
785-
),
776+
wantPredicates: sets.NewString(),
777+
wantPrioritizers: sets.NewString(),
786778
wantPlugins: map[string][]config.Plugin{
787779
"FilterPlugin": {
788780
{Name: "NodeUnschedulable"},
@@ -804,6 +796,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
804796
"ScorePlugin": {
805797
{Name: "NodeResourcesBalancedAllocation", Weight: 2},
806798
{Name: "ImageLocality", Weight: 2},
799+
{Name: "InterPodAffinity", Weight: 2},
807800
{Name: "NodeResourcesLeastAllocated", Weight: 2},
808801
{Name: "NodeResourcesMostAllocated", Weight: 2},
809802
{Name: "NodeAffinity", Weight: 2},
@@ -886,10 +879,8 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
886879
"ignorable":true
887880
}]
888881
}`,
889-
wantPredicates: sets.NewString(),
890-
wantPrioritizers: sets.NewString(
891-
"InterPodAffinityPriority",
892-
),
882+
wantPredicates: sets.NewString(),
883+
wantPrioritizers: sets.NewString(),
893884
wantPlugins: map[string][]config.Plugin{
894885
"FilterPlugin": {
895886
{Name: "NodeUnschedulable"},
@@ -912,6 +903,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
912903
"ScorePlugin": {
913904
{Name: "NodeResourcesBalancedAllocation", Weight: 2},
914905
{Name: "ImageLocality", Weight: 2},
906+
{Name: "InterPodAffinity", Weight: 2},
915907
{Name: "NodeResourcesLeastAllocated", Weight: 2},
916908
{Name: "NodeResourcesMostAllocated", Weight: 2},
917909
{Name: "NodeAffinity", Weight: 2},
@@ -993,10 +985,8 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
993985
"ignorable":true
994986
}]
995987
}`,
996-
wantPredicates: sets.NewString(),
997-
wantPrioritizers: sets.NewString(
998-
"InterPodAffinityPriority",
999-
),
988+
wantPredicates: sets.NewString(),
989+
wantPrioritizers: sets.NewString(),
1000990
wantPlugins: map[string][]config.Plugin{
1001991
"FilterPlugin": {
1002992
{Name: "NodeUnschedulable"},
@@ -1020,6 +1010,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
10201010
"ScorePlugin": {
10211011
{Name: "NodeResourcesBalancedAllocation", Weight: 2},
10221012
{Name: "ImageLocality", Weight: 2},
1013+
{Name: "InterPodAffinity", Weight: 2},
10231014
{Name: "NodeResourcesLeastAllocated", Weight: 2},
10241015
{Name: "NodeResourcesMostAllocated", Weight: 2},
10251016
{Name: "NodeAffinity", Weight: 2},
@@ -1105,10 +1096,8 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
11051096
"ignorable":true
11061097
}]
11071098
}`,
1108-
wantPredicates: sets.NewString(),
1109-
wantPrioritizers: sets.NewString(
1110-
"InterPodAffinityPriority",
1111-
),
1099+
wantPredicates: sets.NewString(),
1100+
wantPrioritizers: sets.NewString(),
11121101
wantPlugins: map[string][]config.Plugin{
11131102
"FilterPlugin": {
11141103
{Name: "NodeUnschedulable"},
@@ -1132,6 +1121,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
11321121
"ScorePlugin": {
11331122
{Name: "NodeResourcesBalancedAllocation", Weight: 2},
11341123
{Name: "ImageLocality", Weight: 2},
1124+
{Name: "InterPodAffinity", Weight: 2},
11351125
{Name: "NodeResourcesLeastAllocated", Weight: 2},
11361126
{Name: "NodeResourcesMostAllocated", Weight: 2},
11371127
{Name: "NodeAffinity", Weight: 2},
@@ -1233,6 +1223,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) {
12331223
scoreToPriorityMap := map[string]string{
12341224
"DefaultPodTopologySpread": "SelectorSpreadPriority",
12351225
"ImageLocality": "ImageLocalityPriority",
1226+
"InterPodAffinity": "InterPodAffinityPriority",
12361227
"NodeAffinity": "NodeAffinityPriority",
12371228
"NodePreferAvoidPods": "NodePreferAvoidPodsPriority",
12381229
"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)