mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-09-02 17:57:33 +00:00
Merge pull request #95448 from alculquicondor/policy-spread
Map SelectorSpreadPriority to PodTopologySpread plugin
This commit is contained in:
@@ -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",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@@ -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
|
||||||
|
@@ -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)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Reference in New Issue
Block a user