diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index ccc13d55206..2672e7039e8 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -8390,7 +8390,7 @@ "type": "array" }, "topologySpreadConstraints": { - "description": "TopologySpreadConstraints describes how a group of pods ought to spread across topology domains. Scheduler will schedule pods in a way which abides by the constraints. This field is only honored by clusters that enable the EvenPodsSpread feature. All topologySpreadConstraints are ANDed.", + "description": "TopologySpreadConstraints describes how a group of pods ought to spread across topology domains. Scheduler will schedule pods in a way which abides by the constraints. All topologySpreadConstraints are ANDed.", "items": { "$ref": "#/definitions/io.k8s.api.core.v1.TopologySpreadConstraint" }, diff --git a/cmd/kube-scheduler/app/server_test.go b/cmd/kube-scheduler/app/server_test.go index 729e8d28afc..6689309582d 100644 --- a/cmd/kube-scheduler/app/server_test.go +++ b/cmd/kube-scheduler/app/server_test.go @@ -154,8 +154,8 @@ profiles: "PreFilterPlugin": { {Name: "NodeResourcesFit"}, {Name: "NodePorts"}, - {Name: "InterPodAffinity"}, {Name: "PodTopologySpread"}, + {Name: "InterPodAffinity"}, }, "FilterPlugin": { {Name: "NodeUnschedulable"}, @@ -171,14 +171,14 @@ profiles: {Name: "AzureDiskLimits"}, {Name: "VolumeBinding"}, {Name: "VolumeZone"}, - {Name: "InterPodAffinity"}, {Name: "PodTopologySpread"}, + {Name: "InterPodAffinity"}, }, "PreScorePlugin": { {Name: "InterPodAffinity"}, + {Name: "PodTopologySpread"}, {Name: "DefaultPodTopologySpread"}, {Name: "TaintToleration"}, - {Name: "PodTopologySpread"}, }, "ScorePlugin": { {Name: "NodeResourcesBalancedAllocation", Weight: 1}, @@ -187,9 +187,9 @@ profiles: {Name: "NodeResourcesLeastAllocated", Weight: 1}, {Name: "NodeAffinity", Weight: 1}, {Name: "NodePreferAvoidPods", Weight: 10000}, + {Name: "PodTopologySpread", Weight: 2}, {Name: "DefaultPodTopologySpread", Weight: 1}, {Name: "TaintToleration", Weight: 1}, - {Name: "PodTopologySpread", Weight: 2}, }, "BindPlugin": {{Name: "DefaultBinder"}}, "ReservePlugin": {{Name: "VolumeBinding"}}, @@ -285,8 +285,8 @@ profiles: "PreFilterPlugin": { {Name: "NodeResourcesFit"}, {Name: "NodePorts"}, - {Name: "InterPodAffinity"}, {Name: "PodTopologySpread"}, + {Name: "InterPodAffinity"}, }, "FilterPlugin": { {Name: "NodeUnschedulable"}, @@ -302,14 +302,14 @@ profiles: {Name: "AzureDiskLimits"}, {Name: "VolumeBinding"}, {Name: "VolumeZone"}, - {Name: "InterPodAffinity"}, {Name: "PodTopologySpread"}, + {Name: "InterPodAffinity"}, }, "PreScorePlugin": { {Name: "InterPodAffinity"}, + {Name: "PodTopologySpread"}, {Name: "DefaultPodTopologySpread"}, {Name: "TaintToleration"}, - {Name: "PodTopologySpread"}, }, "ScorePlugin": { {Name: "NodeResourcesBalancedAllocation", Weight: 1}, @@ -318,9 +318,9 @@ profiles: {Name: "NodeResourcesMostAllocated", Weight: 1}, {Name: "NodeAffinity", Weight: 1}, {Name: "NodePreferAvoidPods", Weight: 10000}, + {Name: "PodTopologySpread", Weight: 2}, {Name: "DefaultPodTopologySpread", Weight: 1}, {Name: "TaintToleration", Weight: 1}, - {Name: "PodTopologySpread", Weight: 2}, }, "BindPlugin": {{Name: "DefaultBinder"}}, "ReservePlugin": {{Name: "VolumeBinding"}}, diff --git a/pkg/api/pod/util.go b/pkg/api/pod/util.go index 98ef8145001..30a8c21a560 100644 --- a/pkg/api/pod/util.go +++ b/pkg/api/pod/util.go @@ -438,11 +438,6 @@ func dropDisabledFields( // does not specify any values for these fields. podSpec.PreemptionPolicy = nil } - - if !utilfeature.DefaultFeatureGate.Enabled(features.EvenPodsSpread) && !topologySpreadConstraintsInUse(oldPodSpec) { - // Set TopologySpreadConstraints to nil only if feature is disabled and it is not used - podSpec.TopologySpreadConstraints = nil - } } // dropDisabledRunAsGroupField removes disabled fields from PodSpec related @@ -558,14 +553,6 @@ func overheadInUse(podSpec *api.PodSpec) bool { return false } -// topologySpreadConstraintsInUse returns true if the pod spec is non-nil and has a TopologySpreadConstraints slice -func topologySpreadConstraintsInUse(podSpec *api.PodSpec) bool { - if podSpec == nil { - return false - } - return len(podSpec.TopologySpreadConstraints) > 0 -} - // procMountInUse returns true if the pod spec is non-nil and has a SecurityContext's ProcMount field set to a non-default value func procMountInUse(podSpec *api.PodSpec) bool { if podSpec == nil { diff --git a/pkg/apis/core/types.go b/pkg/apis/core/types.go index 4ec44c0db10..6e1d9e6a91c 100644 --- a/pkg/apis/core/types.go +++ b/pkg/apis/core/types.go @@ -2764,7 +2764,6 @@ type PodSpec struct { EnableServiceLinks *bool // TopologySpreadConstraints describes how a group of pods ought to spread across topology // domains. Scheduler will schedule pods in a way which abides by the constraints. - // This field is only honored by clusters that enable the EvenPodsSpread feature. // All topologySpreadConstraints are ANDed. // +optional TopologySpreadConstraints []TopologySpreadConstraint diff --git a/pkg/apis/core/validation/validation_test.go b/pkg/apis/core/validation/validation_test.go index ce4ffa345a7..d3c0a75cdf8 100644 --- a/pkg/apis/core/validation/validation_test.go +++ b/pkg/apis/core/validation/validation_test.go @@ -14866,7 +14866,6 @@ func TestAlphaVolumePVCDataSource(t *testing.T) { } func TestValidateTopologySpreadConstraints(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EvenPodsSpread, true)() testCases := []struct { name string constraints []core.TopologySpreadConstraint diff --git a/pkg/features/kube_features.go b/pkg/features/kube_features.go index ba4f4e3382c..eb909645dfe 100644 --- a/pkg/features/kube_features.go +++ b/pkg/features/kube_features.go @@ -504,7 +504,9 @@ const ( EndpointSliceProxying featuregate.Feature = "EndpointSliceProxying" // owner: @Huang-Wei + // alpha: v1.16 // beta: v1.18 + // GA: v1.19 // // Schedule pods evenly across available topology domains. EvenPodsSpread featuregate.Feature = "EvenPodsSpread" @@ -653,7 +655,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS IPv6DualStack: {Default: false, PreRelease: featuregate.Alpha}, EndpointSlice: {Default: true, PreRelease: featuregate.Beta}, EndpointSliceProxying: {Default: false, PreRelease: featuregate.Alpha}, - EvenPodsSpread: {Default: true, PreRelease: featuregate.Beta}, + EvenPodsSpread: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.21 StartupProbe: {Default: true, PreRelease: featuregate.Beta}, AllowInsecureBackendProxy: {Default: true, PreRelease: featuregate.Beta}, PodDisruptionBudget: {Default: true, PreRelease: featuregate.Beta}, diff --git a/pkg/scheduler/algorithmprovider/registry.go b/pkg/scheduler/algorithmprovider/registry.go index e8898632f8c..76cd3bac8c3 100644 --- a/pkg/scheduler/algorithmprovider/registry.go +++ b/pkg/scheduler/algorithmprovider/registry.go @@ -85,6 +85,7 @@ func getDefaultConfig() *schedulerapi.Plugins { Enabled: []schedulerapi.Plugin{ {Name: noderesources.FitName}, {Name: nodeports.Name}, + {Name: podtopologyspread.Name}, {Name: interpodaffinity.Name}, }, }, @@ -103,12 +104,14 @@ func getDefaultConfig() *schedulerapi.Plugins { {Name: nodevolumelimits.AzureDiskName}, {Name: volumebinding.Name}, {Name: volumezone.Name}, + {Name: podtopologyspread.Name}, {Name: interpodaffinity.Name}, }, }, PreScore: &schedulerapi.PluginSet{ Enabled: []schedulerapi.Plugin{ {Name: interpodaffinity.Name}, + {Name: podtopologyspread.Name}, {Name: defaultpodtopologyspread.Name}, {Name: tainttoleration.Name}, }, @@ -121,6 +124,10 @@ func getDefaultConfig() *schedulerapi.Plugins { {Name: noderesources.LeastAllocatedName, Weight: 1}, {Name: nodeaffinity.Name, Weight: 1}, {Name: nodepreferavoidpods.Name, Weight: 10000}, + // Weight is doubled because: + // - This is a score coming from user preference. + // - It makes its signal comparable to NodeResourcesLeastAllocated. + {Name: podtopologyspread.Name, Weight: 2}, {Name: defaultpodtopologyspread.Name, Weight: 1}, {Name: tainttoleration.Name, Weight: 1}, }, @@ -165,20 +172,6 @@ func getClusterAutoscalerConfig() *schedulerapi.Plugins { } func applyFeatureGates(config *schedulerapi.Plugins) { - // Only add EvenPodsSpread if the feature is enabled. - if utilfeature.DefaultFeatureGate.Enabled(features.EvenPodsSpread) { - klog.Infof("Registering EvenPodsSpread predicate and priority function") - f := schedulerapi.Plugin{Name: podtopologyspread.Name} - config.PreFilter.Enabled = append(config.PreFilter.Enabled, f) - config.Filter.Enabled = append(config.Filter.Enabled, f) - config.PreScore.Enabled = append(config.PreScore.Enabled, f) - // Weight is doubled because: - // - This is a score coming from user preference. - // - It makes its signal comparable to NodeResourcesLeastAllocated. - s := schedulerapi.Plugin{Name: podtopologyspread.Name, Weight: 2} - config.Score.Enabled = append(config.Score.Enabled, s) - } - // Prioritizes nodes that satisfy pod's resource limits if utilfeature.DefaultFeatureGate.Enabled(features.ResourceLimitsPriorityFunction) { klog.Infof("Registering resourcelimits priority function") diff --git a/pkg/scheduler/algorithmprovider/registry_test.go b/pkg/scheduler/algorithmprovider/registry_test.go index 6e9a57abe42..dd5c5c29288 100644 --- a/pkg/scheduler/algorithmprovider/registry_test.go +++ b/pkg/scheduler/algorithmprovider/registry_test.go @@ -55,8 +55,8 @@ func TestClusterAutoscalerProvider(t *testing.T) { Enabled: []schedulerapi.Plugin{ {Name: noderesources.FitName}, {Name: nodeports.Name}, - {Name: interpodaffinity.Name}, {Name: podtopologyspread.Name}, + {Name: interpodaffinity.Name}, }, }, Filter: &schedulerapi.PluginSet{ @@ -74,16 +74,16 @@ func TestClusterAutoscalerProvider(t *testing.T) { {Name: nodevolumelimits.AzureDiskName}, {Name: volumebinding.Name}, {Name: volumezone.Name}, - {Name: interpodaffinity.Name}, {Name: podtopologyspread.Name}, + {Name: interpodaffinity.Name}, }, }, PreScore: &schedulerapi.PluginSet{ Enabled: []schedulerapi.Plugin{ {Name: interpodaffinity.Name}, + {Name: podtopologyspread.Name}, {Name: defaultpodtopologyspread.Name}, {Name: tainttoleration.Name}, - {Name: podtopologyspread.Name}, }, }, Score: &schedulerapi.PluginSet{ @@ -94,9 +94,9 @@ func TestClusterAutoscalerProvider(t *testing.T) { {Name: noderesources.MostAllocatedName, Weight: 1}, {Name: nodeaffinity.Name, Weight: 1}, {Name: nodepreferavoidpods.Name, Weight: 10000}, + {Name: podtopologyspread.Name, Weight: 2}, {Name: defaultpodtopologyspread.Name, Weight: 1}, {Name: tainttoleration.Name, Weight: 1}, - {Name: podtopologyspread.Name, Weight: 2}, }, }, Reserve: &schedulerapi.PluginSet{ @@ -152,6 +152,7 @@ func TestApplyFeatureGates(t *testing.T) { Enabled: []schedulerapi.Plugin{ {Name: noderesources.FitName}, {Name: nodeports.Name}, + {Name: podtopologyspread.Name}, {Name: interpodaffinity.Name}, }, }, @@ -170,12 +171,14 @@ func TestApplyFeatureGates(t *testing.T) { {Name: nodevolumelimits.AzureDiskName}, {Name: volumebinding.Name}, {Name: volumezone.Name}, + {Name: podtopologyspread.Name}, {Name: interpodaffinity.Name}, }, }, PreScore: &schedulerapi.PluginSet{ Enabled: []schedulerapi.Plugin{ {Name: interpodaffinity.Name}, + {Name: podtopologyspread.Name}, {Name: defaultpodtopologyspread.Name}, {Name: tainttoleration.Name}, }, @@ -188,6 +191,7 @@ func TestApplyFeatureGates(t *testing.T) { {Name: noderesources.LeastAllocatedName, Weight: 1}, {Name: nodeaffinity.Name, Weight: 1}, {Name: nodepreferavoidpods.Name, Weight: 10000}, + {Name: podtopologyspread.Name, Weight: 2}, {Name: defaultpodtopologyspread.Name, Weight: 1}, {Name: tainttoleration.Name, Weight: 1}, }, @@ -232,8 +236,8 @@ func TestApplyFeatureGates(t *testing.T) { Enabled: []schedulerapi.Plugin{ {Name: noderesources.FitName}, {Name: nodeports.Name}, - {Name: interpodaffinity.Name}, {Name: podtopologyspread.Name}, + {Name: interpodaffinity.Name}, }, }, Filter: &schedulerapi.PluginSet{ @@ -251,16 +255,16 @@ func TestApplyFeatureGates(t *testing.T) { {Name: nodevolumelimits.AzureDiskName}, {Name: volumebinding.Name}, {Name: volumezone.Name}, - {Name: interpodaffinity.Name}, {Name: podtopologyspread.Name}, + {Name: interpodaffinity.Name}, }, }, PreScore: &schedulerapi.PluginSet{ Enabled: []schedulerapi.Plugin{ {Name: interpodaffinity.Name}, + {Name: podtopologyspread.Name}, {Name: defaultpodtopologyspread.Name}, {Name: tainttoleration.Name}, - {Name: podtopologyspread.Name}, {Name: noderesources.ResourceLimitsName}, }, }, @@ -272,9 +276,9 @@ func TestApplyFeatureGates(t *testing.T) { {Name: noderesources.LeastAllocatedName, Weight: 1}, {Name: nodeaffinity.Name, Weight: 1}, {Name: nodepreferavoidpods.Name, Weight: 10000}, + {Name: podtopologyspread.Name, Weight: 2}, {Name: defaultpodtopologyspread.Name, Weight: 1}, {Name: tainttoleration.Name, Weight: 1}, - {Name: podtopologyspread.Name, Weight: 2}, {Name: noderesources.ResourceLimitsName, Weight: 1}, }, }, @@ -310,7 +314,6 @@ func TestApplyFeatureGates(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.ResourceLimitsPriorityFunction, test.featuresEnabled)() - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EvenPodsSpread, test.featuresEnabled)() r := NewRegistry() gotConfig := r[schedulerapi.SchedulerDefaultProviderName] diff --git a/pkg/scheduler/apis/config/testing/compatibility_test.go b/pkg/scheduler/apis/config/testing/compatibility_test.go index 04a8ba2f994..dfacf8684d8 100644 --- a/pkg/scheduler/apis/config/testing/compatibility_test.go +++ b/pkg/scheduler/apis/config/testing/compatibility_test.go @@ -1320,7 +1320,7 @@ func TestCompatibility_v1_Scheduler(t *testing.T) { }}, }, { - name: "enable alpha feature ResourceLimitsPriorityFunction and disable beta feature EvenPodsSpread", + name: "enable alpha feature ResourceLimitsPriorityFunction", JSON: `{ "kind": "Policy", "apiVersion": "v1", @@ -1330,7 +1330,6 @@ func TestCompatibility_v1_Scheduler(t *testing.T) { ] }`, featureGates: map[featuregate.Feature]bool{ - features.EvenPodsSpread: false, features.ResourceLimitsPriorityFunction: true, }, wantPlugins: map[string][]config.Plugin{ @@ -1417,8 +1416,8 @@ func TestAlgorithmProviderCompatibility(t *testing.T) { "PreFilterPlugin": { {Name: "NodeResourcesFit"}, {Name: "NodePorts"}, - {Name: "InterPodAffinity"}, {Name: "PodTopologySpread"}, + {Name: "InterPodAffinity"}, }, "FilterPlugin": { {Name: "NodeUnschedulable"}, @@ -1434,14 +1433,14 @@ func TestAlgorithmProviderCompatibility(t *testing.T) { {Name: "AzureDiskLimits"}, {Name: "VolumeBinding"}, {Name: "VolumeZone"}, - {Name: "InterPodAffinity"}, {Name: "PodTopologySpread"}, + {Name: "InterPodAffinity"}, }, "PreScorePlugin": { {Name: "InterPodAffinity"}, + {Name: "PodTopologySpread"}, {Name: "DefaultPodTopologySpread"}, {Name: "TaintToleration"}, - {Name: "PodTopologySpread"}, }, "ScorePlugin": { {Name: "NodeResourcesBalancedAllocation", Weight: 1}, @@ -1450,9 +1449,9 @@ func TestAlgorithmProviderCompatibility(t *testing.T) { {Name: "NodeResourcesLeastAllocated", Weight: 1}, {Name: "NodeAffinity", Weight: 1}, {Name: "NodePreferAvoidPods", Weight: 10000}, + {Name: "PodTopologySpread", Weight: 2}, {Name: "DefaultPodTopologySpread", Weight: 1}, {Name: "TaintToleration", Weight: 1}, - {Name: "PodTopologySpread", Weight: 2}, }, "BindPlugin": {{Name: "DefaultBinder"}}, "ReservePlugin": {{Name: "VolumeBinding"}}, @@ -1485,8 +1484,8 @@ func TestAlgorithmProviderCompatibility(t *testing.T) { "PreFilterPlugin": { {Name: "NodeResourcesFit"}, {Name: "NodePorts"}, - {Name: "InterPodAffinity"}, {Name: "PodTopologySpread"}, + {Name: "InterPodAffinity"}, }, "FilterPlugin": { {Name: "NodeUnschedulable"}, @@ -1502,14 +1501,14 @@ func TestAlgorithmProviderCompatibility(t *testing.T) { {Name: "AzureDiskLimits"}, {Name: "VolumeBinding"}, {Name: "VolumeZone"}, - {Name: "InterPodAffinity"}, {Name: "PodTopologySpread"}, + {Name: "InterPodAffinity"}, }, "PreScorePlugin": { {Name: "InterPodAffinity"}, + {Name: "PodTopologySpread"}, {Name: "DefaultPodTopologySpread"}, {Name: "TaintToleration"}, - {Name: "PodTopologySpread"}, }, "ScorePlugin": { {Name: "NodeResourcesBalancedAllocation", Weight: 1}, @@ -1518,9 +1517,9 @@ func TestAlgorithmProviderCompatibility(t *testing.T) { {Name: "NodeResourcesMostAllocated", Weight: 1}, {Name: "NodeAffinity", Weight: 1}, {Name: "NodePreferAvoidPods", Weight: 10000}, + {Name: "PodTopologySpread", Weight: 2}, {Name: "DefaultPodTopologySpread", Weight: 1}, {Name: "TaintToleration", Weight: 1}, - {Name: "PodTopologySpread", Weight: 2}, }, "ReservePlugin": {{Name: "VolumeBinding"}}, "UnreservePlugin": {{Name: "VolumeBinding"}}, @@ -1573,8 +1572,8 @@ func TestPluginsConfigurationCompatibility(t *testing.T) { "PreFilterPlugin": { {Name: "NodeResourcesFit"}, {Name: "NodePorts"}, - {Name: "InterPodAffinity"}, {Name: "PodTopologySpread"}, + {Name: "InterPodAffinity"}, }, "FilterPlugin": { {Name: "NodeUnschedulable"}, @@ -1590,14 +1589,14 @@ func TestPluginsConfigurationCompatibility(t *testing.T) { {Name: "AzureDiskLimits"}, {Name: "VolumeBinding"}, {Name: "VolumeZone"}, - {Name: "InterPodAffinity"}, {Name: "PodTopologySpread"}, + {Name: "InterPodAffinity"}, }, "PreScorePlugin": { {Name: "InterPodAffinity"}, + {Name: "PodTopologySpread"}, {Name: "DefaultPodTopologySpread"}, {Name: "TaintToleration"}, - {Name: "PodTopologySpread"}, }, "ScorePlugin": { {Name: "NodeResourcesBalancedAllocation", Weight: 1}, @@ -1606,9 +1605,9 @@ func TestPluginsConfigurationCompatibility(t *testing.T) { {Name: "NodeResourcesLeastAllocated", Weight: 1}, {Name: "NodeAffinity", Weight: 1}, {Name: "NodePreferAvoidPods", Weight: 10000}, + {Name: "PodTopologySpread", Weight: 2}, {Name: "DefaultPodTopologySpread", Weight: 1}, {Name: "TaintToleration", Weight: 1}, - {Name: "PodTopologySpread", Weight: 2}, }, "ReservePlugin": {{Name: "VolumeBinding"}}, "UnreservePlugin": {{Name: "VolumeBinding"}}, diff --git a/pkg/scheduler/framework/plugins/legacy_registry.go b/pkg/scheduler/framework/plugins/legacy_registry.go index bc65a6f0827..58dd09c1c0d 100644 --- a/pkg/scheduler/framework/plugins/legacy_registry.go +++ b/pkg/scheduler/framework/plugins/legacy_registry.go @@ -200,6 +200,7 @@ func NewLegacyRegistry() *LegacyRegistry { PodToleratesNodeTaintsPred, CheckVolumeBindingPred, CheckNodeUnschedulablePred, + EvenPodsSpreadPred, ), // Used as the default set of predicates if Policy was specified, but priorities was nil. @@ -212,6 +213,7 @@ func NewLegacyRegistry() *LegacyRegistry { NodeAffinityPriority: 1, TaintTolerationPriority: 1, ImageLocalityPriority: 1, + EvenPodsSpreadPriority: 1, }, PredicateToConfigProducer: make(map[string]ConfigProducer), @@ -338,6 +340,12 @@ func NewLegacyRegistry() *LegacyRegistry { plugins.PreFilter = appendToPluginSet(plugins.PreFilter, serviceaffinity.Name, nil) return }) + registry.registerPredicateConfigProducer(EvenPodsSpreadPred, + func(_ ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) { + plugins.PreFilter = appendToPluginSet(plugins.PreFilter, podtopologyspread.Name, nil) + plugins.Filter = appendToPluginSet(plugins.Filter, podtopologyspread.Name, nil) + return + }) // Register Priorities. registry.registerPriorityConfigProducer(SelectorSpreadPriority, @@ -401,7 +409,6 @@ func NewLegacyRegistry() *LegacyRegistry { } return }) - registry.registerPriorityConfigProducer(nodelabel.Name, func(args ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) { // If there are n LabelPreference priorities in the policy, the weight for the corresponding @@ -428,31 +435,16 @@ func NewLegacyRegistry() *LegacyRegistry { } return }) + registry.registerPriorityConfigProducer(EvenPodsSpreadPriority, + func(args ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) { + plugins.PreScore = appendToPluginSet(plugins.PreScore, podtopologyspread.Name, nil) + plugins.Score = appendToPluginSet(plugins.Score, podtopologyspread.Name, &args.Weight) + return + }) - // The following two features are the last ones to be supported as predicate/priority. - // Once they graduate to GA, there will be no more checking for feature gates here. - // Only register EvenPodsSpread predicate & priority if the feature is enabled - if utilfeature.DefaultFeatureGate.Enabled(features.EvenPodsSpread) { - klog.Infof("Registering EvenPodsSpread predicate and priority function") - - registry.registerPredicateConfigProducer(EvenPodsSpreadPred, - func(_ ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) { - plugins.PreFilter = appendToPluginSet(plugins.PreFilter, podtopologyspread.Name, nil) - plugins.Filter = appendToPluginSet(plugins.Filter, podtopologyspread.Name, nil) - return - }) - registry.DefaultPredicates.Insert(EvenPodsSpreadPred) - - registry.registerPriorityConfigProducer(EvenPodsSpreadPriority, - func(args ConfigProducerArgs) (plugins config.Plugins, pluginConfig []config.PluginConfig) { - plugins.PreScore = appendToPluginSet(plugins.PreScore, podtopologyspread.Name, nil) - plugins.Score = appendToPluginSet(plugins.Score, podtopologyspread.Name, &args.Weight) - return - }) - registry.DefaultPriorities[EvenPodsSpreadPriority] = 1 - } - - // Prioritizes nodes that satisfy pod's resource limits + // ResourceLimits is the last feature to be supported as predicate/priority. + // TODO: Remove this check once it graduates to GA. + // Prioritizes nodes that satisfy pod's resource limits. if utilfeature.DefaultFeatureGate.Enabled(features.ResourceLimitsPriorityFunction) { klog.Infof("Registering resourcelimits priority function") diff --git a/pkg/scheduler/framework/plugins/podtopologyspread/filtering.go b/pkg/scheduler/framework/plugins/podtopologyspread/filtering.go index 9882221e71b..98705c5b380 100644 --- a/pkg/scheduler/framework/plugins/podtopologyspread/filtering.go +++ b/pkg/scheduler/framework/plugins/podtopologyspread/filtering.go @@ -52,7 +52,6 @@ type preFilterState struct { // Clone makes a copy of the given state. func (s *preFilterState) Clone() framework.StateData { - // s could be nil when EvenPodsSpread feature is disabled if s == nil { return nil } diff --git a/staging/src/k8s.io/api/core/v1/generated.proto b/staging/src/k8s.io/api/core/v1/generated.proto index 9babe37bb61..5c5339aa71c 100644 --- a/staging/src/k8s.io/api/core/v1/generated.proto +++ b/staging/src/k8s.io/api/core/v1/generated.proto @@ -3543,7 +3543,6 @@ message PodSpec { // TopologySpreadConstraints describes how a group of pods ought to spread across topology // domains. Scheduler will schedule pods in a way which abides by the constraints. - // This field is only honored by clusters that enable the EvenPodsSpread feature. // All topologySpreadConstraints are ANDed. // +optional // +patchMergeKey=topologyKey diff --git a/staging/src/k8s.io/api/core/v1/types.go b/staging/src/k8s.io/api/core/v1/types.go index 197684de76c..ba0b4152b21 100644 --- a/staging/src/k8s.io/api/core/v1/types.go +++ b/staging/src/k8s.io/api/core/v1/types.go @@ -3047,7 +3047,6 @@ type PodSpec struct { Overhead ResourceList `json:"overhead,omitempty" protobuf:"bytes,32,opt,name=overhead"` // TopologySpreadConstraints describes how a group of pods ought to spread across topology // domains. Scheduler will schedule pods in a way which abides by the constraints. - // This field is only honored by clusters that enable the EvenPodsSpread feature. // All topologySpreadConstraints are ANDed. // +optional // +patchMergeKey=topologyKey diff --git a/staging/src/k8s.io/api/core/v1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/core/v1/types_swagger_doc_generated.go index 13325261274..ebba6a55a33 100644 --- a/staging/src/k8s.io/api/core/v1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/core/v1/types_swagger_doc_generated.go @@ -1633,7 +1633,7 @@ var map_PodSpec = map[string]string{ "enableServiceLinks": "EnableServiceLinks indicates whether information about services should be injected into pod's environment variables, matching the syntax of Docker links. Optional: Defaults to true.", "preemptionPolicy": "PreemptionPolicy is the Policy for preempting pods with lower priority. One of Never, PreemptLowerPriority. Defaults to PreemptLowerPriority if unset. This field is alpha-level and is only honored by servers that enable the NonPreemptingPriority feature.", "overhead": "Overhead represents the resource overhead associated with running a pod for a given RuntimeClass. This field will be autopopulated at admission time by the RuntimeClass admission controller. If the RuntimeClass admission controller is enabled, overhead must not be set in Pod create requests. The RuntimeClass admission controller will reject Pod create requests which have the overhead already set. If RuntimeClass is configured and selected in the PodSpec, Overhead will be set to the value defined in the corresponding RuntimeClass, otherwise it will remain unset and treated as zero. More info: https://git.k8s.io/enhancements/keps/sig-node/20190226-pod-overhead.md This field is alpha-level as of Kubernetes v1.16, and is only honored by servers that enable the PodOverhead feature.", - "topologySpreadConstraints": "TopologySpreadConstraints describes how a group of pods ought to spread across topology domains. Scheduler will schedule pods in a way which abides by the constraints. This field is only honored by clusters that enable the EvenPodsSpread feature. All topologySpreadConstraints are ANDed.", + "topologySpreadConstraints": "TopologySpreadConstraints describes how a group of pods ought to spread across topology domains. Scheduler will schedule pods in a way which abides by the constraints. All topologySpreadConstraints are ANDed.", } func (PodSpec) SwaggerDoc() map[string]string { diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/testdata/swagger.json b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/testdata/swagger.json index 6ed29904ee2..acd6bce74ff 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/testdata/swagger.json +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/handlers/fieldmanager/internal/testdata/swagger.json @@ -2570,7 +2570,7 @@ "type": "array" }, "topologySpreadConstraints": { - "description": "TopologySpreadConstraints describes how a group of pods ought to spread across topology domains. Scheduler will schedule pods in a way which abides by the constraints. This field is alpha-level and is only honored by clusters that enables the EvenPodsSpread feature. All topologySpreadConstraints are ANDed.", + "description": "TopologySpreadConstraints describes how a group of pods ought to spread across topology domains. Scheduler will schedule pods in a way which abides by the constraints. All topologySpreadConstraints are ANDed.", "items": { "$ref": "#/definitions/io.k8s.api.core.v1.TopologySpreadConstraint" }, diff --git a/staging/src/k8s.io/cli-runtime/artifacts/openapi/swagger.json b/staging/src/k8s.io/cli-runtime/artifacts/openapi/swagger.json index 760ad19fccf..96b4b766b26 100644 --- a/staging/src/k8s.io/cli-runtime/artifacts/openapi/swagger.json +++ b/staging/src/k8s.io/cli-runtime/artifacts/openapi/swagger.json @@ -10058,7 +10058,7 @@ "type": "array" }, "topologySpreadConstraints": { - "description": "TopologySpreadConstraints describes how a group of pods ought to spread across topology domains. Scheduler will schedule pods in a way which abides by the constraints. This field is alpha-level and is only honored by clusters that enables the EvenPodsSpread feature. All topologySpreadConstraints are ANDed.", + "description": "TopologySpreadConstraints describes how a group of pods ought to spread across topology domains. Scheduler will schedule pods in a way which abides by the constraints. All topologySpreadConstraints are ANDed.", "items": { "$ref": "#/definitions/io.k8s.api.core.v1.TopologySpreadConstraint" }, diff --git a/staging/src/k8s.io/kubectl/testdata/openapi/swagger.json b/staging/src/k8s.io/kubectl/testdata/openapi/swagger.json index 760ad19fccf..96b4b766b26 100644 --- a/staging/src/k8s.io/kubectl/testdata/openapi/swagger.json +++ b/staging/src/k8s.io/kubectl/testdata/openapi/swagger.json @@ -10058,7 +10058,7 @@ "type": "array" }, "topologySpreadConstraints": { - "description": "TopologySpreadConstraints describes how a group of pods ought to spread across topology domains. Scheduler will schedule pods in a way which abides by the constraints. This field is alpha-level and is only honored by clusters that enables the EvenPodsSpread feature. All topologySpreadConstraints are ANDed.", + "description": "TopologySpreadConstraints describes how a group of pods ought to spread across topology domains. Scheduler will schedule pods in a way which abides by the constraints. All topologySpreadConstraints are ANDed.", "items": { "$ref": "#/definitions/io.k8s.api.core.v1.TopologySpreadConstraint" }, diff --git a/test/integration/scheduler/predicates_test.go b/test/integration/scheduler/predicates_test.go index d61ae1a94ca..bd7ec74378d 100644 --- a/test/integration/scheduler/predicates_test.go +++ b/test/integration/scheduler/predicates_test.go @@ -26,10 +26,7 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" - utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/kubernetes" - featuregatetesting "k8s.io/component-base/featuregate/testing" - "k8s.io/kubernetes/pkg/features" st "k8s.io/kubernetes/pkg/scheduler/testing" testutils "k8s.io/kubernetes/test/integration/util" "k8s.io/kubernetes/test/utils" @@ -880,8 +877,6 @@ func TestInterPodAffinity(t *testing.T) { // TestEvenPodsSpreadPredicate verifies that EvenPodsSpread predicate functions well. func TestEvenPodsSpreadPredicate(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EvenPodsSpread, true)() - testCtx := initTest(t, "eps-predicate") cs := testCtx.ClientSet ns := testCtx.NS.Name diff --git a/test/integration/scheduler/priorities_test.go b/test/integration/scheduler/priorities_test.go index c9d5c5a423f..3776cefc36a 100644 --- a/test/integration/scheduler/priorities_test.go +++ b/test/integration/scheduler/priorities_test.go @@ -26,9 +26,6 @@ import ( apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" - utilfeature "k8s.io/apiserver/pkg/util/feature" - featuregatetesting "k8s.io/component-base/featuregate/testing" - "k8s.io/kubernetes/pkg/features" st "k8s.io/kubernetes/pkg/scheduler/testing" testutils "k8s.io/kubernetes/test/integration/util" "k8s.io/kubernetes/test/utils" @@ -247,8 +244,6 @@ func makeContainersWithImages(images []string) []v1.Container { // TestEvenPodsSpreadPriority verifies that EvenPodsSpread priority functions well. func TestEvenPodsSpreadPriority(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.EvenPodsSpread, true)() - testCtx := initTest(t, "eps-priority") cs := testCtx.ClientSet ns := testCtx.NS.Name