Merge pull request #95448 from alculquicondor/policy-spread

Map SelectorSpreadPriority to PodTopologySpread plugin
This commit is contained in:
Kubernetes Prow Robot
2020-10-15 12:55:25 -07:00
committed by GitHub
3 changed files with 224 additions and 4 deletions

View File

@@ -9,6 +9,7 @@ go_library(
importpath = "k8s.io/kubernetes/pkg/scheduler/framework/plugins", importpath = "k8s.io/kubernetes/pkg/scheduler/framework/plugins",
visibility = ["//visibility:public"], visibility = ["//visibility:public"],
deps = [ deps = [
"//pkg/features:go_default_library",
"//pkg/scheduler/apis/config:go_default_library", "//pkg/scheduler/apis/config:go_default_library",
"//pkg/scheduler/framework/plugins/defaultbinder:go_default_library", "//pkg/scheduler/framework/plugins/defaultbinder:go_default_library",
"//pkg/scheduler/framework/plugins/defaultpreemption:go_default_library", "//pkg/scheduler/framework/plugins/defaultpreemption:go_default_library",
@@ -32,6 +33,7 @@ go_library(
"//pkg/scheduler/framework/plugins/volumezone:go_default_library", "//pkg/scheduler/framework/plugins/volumezone:go_default_library",
"//pkg/scheduler/framework/runtime:go_default_library", "//pkg/scheduler/framework/runtime:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//vendor/k8s.io/klog/v2:go_default_library", "//vendor/k8s.io/klog/v2:go_default_library",
], ],
) )
@@ -79,10 +81,21 @@ go_test(
srcs = ["legacy_registry_test.go"], srcs = ["legacy_registry_test.go"],
embed = [":go_default_library"], embed = [":go_default_library"],
deps = [ deps = [
"//pkg/features:go_default_library",
"//pkg/scheduler/apis/config:go_default_library", "//pkg/scheduler/apis/config:go_default_library",
"//pkg/scheduler/framework/plugins/imagelocality:go_default_library",
"//pkg/scheduler/framework/plugins/interpodaffinity:go_default_library",
"//pkg/scheduler/framework/plugins/nodeaffinity:go_default_library",
"//pkg/scheduler/framework/plugins/nodepreferavoidpods:go_default_library",
"//pkg/scheduler/framework/plugins/noderesources:go_default_library",
"//pkg/scheduler/framework/plugins/nodeunschedulable:go_default_library", "//pkg/scheduler/framework/plugins/nodeunschedulable:go_default_library",
"//pkg/scheduler/framework/plugins/podtopologyspread:go_default_library",
"//pkg/scheduler/framework/plugins/selectorspread:go_default_library",
"//pkg/scheduler/framework/plugins/tainttoleration:go_default_library", "//pkg/scheduler/framework/plugins/tainttoleration:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/sets:go_default_library",
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//staging/src/k8s.io/component-base/featuregate:go_default_library",
"//staging/src/k8s.io/component-base/featuregate/testing:go_default_library",
"//vendor/github.com/google/go-cmp/cmp:go_default_library", "//vendor/github.com/google/go-cmp/cmp:go_default_library",
], ],
) )

View File

@@ -21,7 +21,9 @@ import (
"sort" "sort"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/util/feature"
"k8s.io/klog/v2" "k8s.io/klog/v2"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/scheduler/apis/config" "k8s.io/kubernetes/pkg/scheduler/apis/config"
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/imagelocality" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/imagelocality"
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/interpodaffinity" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/interpodaffinity"
@@ -327,9 +329,29 @@ func NewLegacyRegistry() *LegacyRegistry {
// Register Priorities. // Register Priorities.
registry.registerPriorityConfigProducer(SelectorSpreadPriority, registry.registerPriorityConfigProducer(SelectorSpreadPriority,
func(args ConfigProducerArgs, plugins *config.Plugins, _ *[]config.PluginConfig) { func(args ConfigProducerArgs, plugins *config.Plugins, pluginConfig *[]config.PluginConfig) {
if !feature.DefaultFeatureGate.Enabled(features.DefaultPodTopologySpread) {
plugins.Score = appendToPluginSet(plugins.Score, selectorspread.Name, &args.Weight) plugins.Score = appendToPluginSet(plugins.Score, selectorspread.Name, &args.Weight)
plugins.PreScore = appendToPluginSet(plugins.PreScore, selectorspread.Name, nil) plugins.PreScore = appendToPluginSet(plugins.PreScore, selectorspread.Name, nil)
return
}
plugins.Score = appendToPluginSet(plugins.Score, podtopologyspread.Name, &args.Weight)
plugins.PreScore = appendToPluginSet(plugins.PreScore, podtopologyspread.Name, nil)
plArgs := config.PodTopologySpreadArgs{
DefaultingType: config.SystemDefaulting,
}
// The order in which SelectorSpreadPriority or EvenPodsSpreadPriority producers
// are called is not guaranteed. Override or append configuration.
for i, e := range *pluginConfig {
if e.Name == podtopologyspread.Name {
(*pluginConfig)[i].Args = &plArgs
return
}
}
*pluginConfig = append(*pluginConfig, config.PluginConfig{
Name: podtopologyspread.Name,
Args: &plArgs,
})
}) })
registry.registerPriorityConfigProducer(TaintTolerationPriority, registry.registerPriorityConfigProducer(TaintTolerationPriority,
func(args ConfigProducerArgs, plugins *config.Plugins, _ *[]config.PluginConfig) { func(args ConfigProducerArgs, plugins *config.Plugins, _ *[]config.PluginConfig) {
@@ -402,9 +424,25 @@ func NewLegacyRegistry() *LegacyRegistry {
} }
}) })
registry.registerPriorityConfigProducer(EvenPodsSpreadPriority, registry.registerPriorityConfigProducer(EvenPodsSpreadPriority,
func(args ConfigProducerArgs, plugins *config.Plugins, _ *[]config.PluginConfig) { func(args ConfigProducerArgs, plugins *config.Plugins, pluginConfig *[]config.PluginConfig) {
plugins.PreScore = appendToPluginSet(plugins.PreScore, podtopologyspread.Name, nil) plugins.PreScore = appendToPluginSet(plugins.PreScore, podtopologyspread.Name, nil)
plugins.Score = appendToPluginSet(plugins.Score, podtopologyspread.Name, &args.Weight) plugins.Score = appendToPluginSet(plugins.Score, podtopologyspread.Name, &args.Weight)
if feature.DefaultFeatureGate.Enabled(features.DefaultPodTopologySpread) {
// The order in which SelectorSpreadPriority or EvenPodsSpreadPriority producers
// are called is not guaranteed. If plugin was not configured yet, append
// configuration where system default constraints are disabled.
for _, e := range *pluginConfig {
if e.Name == podtopologyspread.Name {
return
}
}
*pluginConfig = append(*pluginConfig, config.PluginConfig{
Name: podtopologyspread.Name,
Args: &config.PodTopologySpreadArgs{
DefaultingType: config.ListDefaulting,
},
})
}
}) })
return registry return registry
@@ -489,6 +527,15 @@ func appendToPluginSet(set *config.PluginSet, name string, weight *int32) *confi
if set == nil { if set == nil {
set = &config.PluginSet{} set = &config.PluginSet{}
} }
for _, e := range set.Enabled {
if e.Name == name {
// Keep the max weight.
if weight != nil && *weight > e.Weight {
e.Weight = *weight
}
return set
}
}
cfg := config.Plugin{Name: name} cfg := config.Plugin{Name: name}
if weight != nil { if weight != nil {
cfg.Weight = *weight cfg.Weight = *weight

View File

@@ -21,8 +21,19 @@ import (
"github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp"
"k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/sets"
"k8s.io/apiserver/pkg/util/feature"
"k8s.io/component-base/featuregate"
featuregatetesting "k8s.io/component-base/featuregate/testing"
"k8s.io/kubernetes/pkg/features"
"k8s.io/kubernetes/pkg/scheduler/apis/config" "k8s.io/kubernetes/pkg/scheduler/apis/config"
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/imagelocality"
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/interpodaffinity"
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeaffinity"
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodepreferavoidpods"
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/noderesources"
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeunschedulable" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/nodeunschedulable"
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/podtopologyspread"
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/selectorspread"
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/tainttoleration" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/tainttoleration"
) )
@@ -93,3 +104,152 @@ func TestRegisterConfigProducers(t *testing.T) {
t.Errorf("unexpected plugin configuration (-want, +got): %s", diff) t.Errorf("unexpected plugin configuration (-want, +got): %s", diff)
} }
} }
func TestAppendPriorityConfigs(t *testing.T) {
cases := []struct {
name string
features map[featuregate.Feature]bool
keys map[string]int64
args ConfigProducerArgs
wantPlugins config.Plugins
wantPluginConfig []config.PluginConfig
}{
{
name: "default priorities",
wantPlugins: config.Plugins{
PreScore: &config.PluginSet{
Enabled: []config.Plugin{
{Name: podtopologyspread.Name},
{Name: interpodaffinity.Name},
{Name: selectorspread.Name},
{Name: tainttoleration.Name},
},
},
Score: &config.PluginSet{
Enabled: []config.Plugin{
{Name: noderesources.BalancedAllocationName, Weight: 1},
{Name: podtopologyspread.Name, Weight: 2},
{Name: imagelocality.Name, Weight: 1},
{Name: interpodaffinity.Name, Weight: 1},
{Name: noderesources.LeastAllocatedName, Weight: 1},
{Name: nodeaffinity.Name, Weight: 1},
{Name: nodepreferavoidpods.Name, Weight: 10000},
{Name: selectorspread.Name, Weight: 1},
{Name: tainttoleration.Name, Weight: 1},
},
},
},
},
{
name: "DefaultPodTopologySpread enabled, SelectorSpreadPriority only",
features: map[featuregate.Feature]bool{
features.DefaultPodTopologySpread: true,
},
keys: map[string]int64{
SelectorSpreadPriority: 3,
},
wantPlugins: config.Plugins{
PreScore: &config.PluginSet{
Enabled: []config.Plugin{
{Name: podtopologyspread.Name},
},
},
Score: &config.PluginSet{
Enabled: []config.Plugin{
{Name: podtopologyspread.Name, Weight: 3},
},
},
},
wantPluginConfig: []config.PluginConfig{
{
Name: podtopologyspread.Name,
Args: &config.PodTopologySpreadArgs{
DefaultingType: config.SystemDefaulting,
},
},
},
},
{
name: "DefaultPodTopologySpread enabled, EvenPodsSpreadPriority only",
features: map[featuregate.Feature]bool{
features.DefaultPodTopologySpread: true,
},
keys: map[string]int64{
EvenPodsSpreadPriority: 4,
},
wantPlugins: config.Plugins{
PreScore: &config.PluginSet{
Enabled: []config.Plugin{
{Name: podtopologyspread.Name},
},
},
Score: &config.PluginSet{
Enabled: []config.Plugin{
{Name: podtopologyspread.Name, Weight: 4},
},
},
},
wantPluginConfig: []config.PluginConfig{
{
Name: podtopologyspread.Name,
Args: &config.PodTopologySpreadArgs{
DefaultingType: config.ListDefaulting,
},
},
},
},
{
name: "DefaultPodTopologySpread enabled, SelectorSpreadPriority+EvenPodsSpreadPriority",
features: map[featuregate.Feature]bool{
features.DefaultPodTopologySpread: true,
},
keys: map[string]int64{
SelectorSpreadPriority: 1,
EvenPodsSpreadPriority: 2,
},
wantPlugins: config.Plugins{
PreScore: &config.PluginSet{
Enabled: []config.Plugin{
{Name: podtopologyspread.Name},
},
},
Score: &config.PluginSet{
Enabled: []config.Plugin{
{Name: podtopologyspread.Name, Weight: 2},
},
},
},
wantPluginConfig: []config.PluginConfig{
{
Name: podtopologyspread.Name,
Args: &config.PodTopologySpreadArgs{
DefaultingType: config.SystemDefaulting,
},
},
},
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
for k, v := range tc.features {
defer featuregatetesting.SetFeatureGateDuringTest(t, feature.DefaultFeatureGate, k, v)()
}
r := NewLegacyRegistry()
keys := tc.keys
if keys == nil {
keys = r.DefaultPriorities
}
plugins, pluginConfig, err := r.AppendPriorityConfigs(keys, &tc.args, config.Plugins{}, nil)
if err != nil {
t.Fatalf("Appending Priority Configs: %v", err)
}
if diff := cmp.Diff(tc.wantPlugins, plugins); diff != "" {
t.Errorf("Unexpected Plugin (-want,+got):\n%s", diff)
}
if diff := cmp.Diff(tc.wantPluginConfig, pluginConfig); diff != "" {
t.Errorf("Unexpected PluginConfig (-want,+got):\n%s", diff)
}
})
}
}