mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-23 19:56:01 +00:00
Merge pull request #91793 from alculquicondor/new-default-spread
Use PodTopologySpread for default spreading
This commit is contained in:
commit
17630c34cf
@ -177,8 +177,8 @@ profiles:
|
||||
"PreScorePlugin": {
|
||||
{Name: "InterPodAffinity"},
|
||||
{Name: "PodTopologySpread"},
|
||||
{Name: "DefaultPodTopologySpread"},
|
||||
{Name: "TaintToleration"},
|
||||
{Name: "DefaultPodTopologySpread"},
|
||||
},
|
||||
"ScorePlugin": {
|
||||
{Name: "NodeResourcesBalancedAllocation", Weight: 1},
|
||||
@ -188,8 +188,8 @@ profiles:
|
||||
{Name: "NodeAffinity", Weight: 1},
|
||||
{Name: "NodePreferAvoidPods", Weight: 10000},
|
||||
{Name: "PodTopologySpread", Weight: 2},
|
||||
{Name: "DefaultPodTopologySpread", Weight: 1},
|
||||
{Name: "TaintToleration", Weight: 1},
|
||||
{Name: "DefaultPodTopologySpread", Weight: 1},
|
||||
},
|
||||
"BindPlugin": {{Name: "DefaultBinder"}},
|
||||
"ReservePlugin": {{Name: "VolumeBinding"}},
|
||||
@ -308,8 +308,8 @@ profiles:
|
||||
"PreScorePlugin": {
|
||||
{Name: "InterPodAffinity"},
|
||||
{Name: "PodTopologySpread"},
|
||||
{Name: "DefaultPodTopologySpread"},
|
||||
{Name: "TaintToleration"},
|
||||
{Name: "DefaultPodTopologySpread"},
|
||||
},
|
||||
"ScorePlugin": {
|
||||
{Name: "NodeResourcesBalancedAllocation", Weight: 1},
|
||||
@ -319,8 +319,8 @@ profiles:
|
||||
{Name: "NodeAffinity", Weight: 1},
|
||||
{Name: "NodePreferAvoidPods", Weight: 10000},
|
||||
{Name: "PodTopologySpread", Weight: 2},
|
||||
{Name: "DefaultPodTopologySpread", Weight: 1},
|
||||
{Name: "TaintToleration", Weight: 1},
|
||||
{Name: "DefaultPodTopologySpread", Weight: 1},
|
||||
},
|
||||
"BindPlugin": {{Name: "DefaultBinder"}},
|
||||
"ReservePlugin": {{Name: "VolumeBinding"}},
|
||||
|
@ -293,6 +293,13 @@ const (
|
||||
// Enables CSI Inline volumes support for pods
|
||||
CSIInlineVolume featuregate.Feature = "CSIInlineVolume"
|
||||
|
||||
// owner: @alculquicondor
|
||||
// alpha: v1.19
|
||||
//
|
||||
// Enables the use of PodTopologySpread scheduling plugin to do default
|
||||
// spreading and disables legacy DefaultPodTopologySpread plugin.
|
||||
DefaultPodTopologySpread featuregate.Feature = "DefaultPodTopologySpread"
|
||||
|
||||
// owner: @tallclair
|
||||
// alpha: v1.12
|
||||
// beta: v1.14
|
||||
@ -660,6 +667,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
||||
HugePageStorageMediumSize: {Default: false, PreRelease: featuregate.Alpha},
|
||||
ExternalPolicyForExternalIP: {Default: true, PreRelease: featuregate.GA}, // remove in 1.20
|
||||
AnyVolumeDataSource: {Default: false, PreRelease: featuregate.Alpha},
|
||||
DefaultPodTopologySpread: {Default: false, PreRelease: featuregate.Alpha},
|
||||
|
||||
// inherited features from generic apiserver, relisted here to get a conflict if it is changed
|
||||
// unintentionally on either side:
|
||||
|
@ -11,6 +11,7 @@ go_library(
|
||||
srcs = ["registry.go"],
|
||||
importpath = "k8s.io/kubernetes/pkg/scheduler/algorithmprovider",
|
||||
deps = [
|
||||
"//pkg/features:go_default_library",
|
||||
"//pkg/scheduler/apis/config:go_default_library",
|
||||
"//pkg/scheduler/framework/plugins/defaultbinder:go_default_library",
|
||||
"//pkg/scheduler/framework/plugins/defaultpodtopologyspread:go_default_library",
|
||||
@ -29,6 +30,8 @@ go_library(
|
||||
"//pkg/scheduler/framework/plugins/volumebinding:go_default_library",
|
||||
"//pkg/scheduler/framework/plugins/volumerestrictions:go_default_library",
|
||||
"//pkg/scheduler/framework/plugins/volumezone:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//vendor/k8s.io/klog/v2:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
@ -37,6 +40,7 @@ go_test(
|
||||
srcs = ["registry_test.go"],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/features:go_default_library",
|
||||
"//pkg/scheduler/apis/config:go_default_library",
|
||||
"//pkg/scheduler/framework/plugins/defaultbinder:go_default_library",
|
||||
"//pkg/scheduler/framework/plugins/defaultpodtopologyspread:go_default_library",
|
||||
@ -55,6 +59,9 @@ go_test(
|
||||
"//pkg/scheduler/framework/plugins/volumebinding:go_default_library",
|
||||
"//pkg/scheduler/framework/plugins/volumerestrictions:go_default_library",
|
||||
"//pkg/scheduler/framework/plugins/volumezone: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",
|
||||
],
|
||||
)
|
||||
|
@ -20,6 +20,9 @@ import (
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
"k8s.io/klog/v2"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
schedulerapi "k8s.io/kubernetes/pkg/scheduler/apis/config"
|
||||
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultbinder"
|
||||
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultpodtopologyspread"
|
||||
@ -49,7 +52,10 @@ type Registry map[string]*schedulerapi.Plugins
|
||||
// NewRegistry returns an algorithm provider registry instance.
|
||||
func NewRegistry() Registry {
|
||||
defaultConfig := getDefaultConfig()
|
||||
applyFeatureGates(defaultConfig)
|
||||
|
||||
caConfig := getClusterAutoscalerConfig()
|
||||
applyFeatureGates(caConfig)
|
||||
|
||||
return Registry{
|
||||
schedulerapi.SchedulerDefaultProviderName: defaultConfig,
|
||||
@ -106,7 +112,6 @@ func getDefaultConfig() *schedulerapi.Plugins {
|
||||
Enabled: []schedulerapi.Plugin{
|
||||
{Name: interpodaffinity.Name},
|
||||
{Name: podtopologyspread.Name},
|
||||
{Name: defaultpodtopologyspread.Name},
|
||||
{Name: tainttoleration.Name},
|
||||
},
|
||||
},
|
||||
@ -122,7 +127,6 @@ func getDefaultConfig() *schedulerapi.Plugins {
|
||||
// - 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},
|
||||
},
|
||||
},
|
||||
@ -164,3 +168,15 @@ func getClusterAutoscalerConfig() *schedulerapi.Plugins {
|
||||
}
|
||||
return caConfig
|
||||
}
|
||||
|
||||
func applyFeatureGates(config *schedulerapi.Plugins) {
|
||||
if !utilfeature.DefaultFeatureGate.Enabled(features.DefaultPodTopologySpread) {
|
||||
// When feature is enabled, the default spreading is done by
|
||||
// PodTopologySpread plugin, which is enabled by default.
|
||||
klog.Infof("Registering DefaultPodTopologySpread plugin")
|
||||
s := schedulerapi.Plugin{Name: defaultpodtopologyspread.Name}
|
||||
config.PreScore.Enabled = append(config.PreScore.Enabled, s)
|
||||
s.Weight = 1
|
||||
config.Score.Enabled = append(config.Score.Enabled, s)
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,11 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"k8s.io/component-base/featuregate"
|
||||
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
schedulerapi "k8s.io/kubernetes/pkg/scheduler/apis/config"
|
||||
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultbinder"
|
||||
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultpodtopologyspread"
|
||||
@ -79,8 +83,8 @@ func TestClusterAutoscalerProvider(t *testing.T) {
|
||||
Enabled: []schedulerapi.Plugin{
|
||||
{Name: interpodaffinity.Name},
|
||||
{Name: podtopologyspread.Name},
|
||||
{Name: defaultpodtopologyspread.Name},
|
||||
{Name: tainttoleration.Name},
|
||||
{Name: defaultpodtopologyspread.Name},
|
||||
},
|
||||
},
|
||||
Score: &schedulerapi.PluginSet{
|
||||
@ -92,8 +96,8 @@ func TestClusterAutoscalerProvider(t *testing.T) {
|
||||
{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: defaultpodtopologyspread.Name, Weight: 1},
|
||||
},
|
||||
},
|
||||
Reserve: &schedulerapi.PluginSet{
|
||||
@ -129,3 +133,191 @@ func TestClusterAutoscalerProvider(t *testing.T) {
|
||||
t.Errorf("unexpected config diff (-want, +got): %s", diff)
|
||||
}
|
||||
}
|
||||
|
||||
func TestApplyFeatureGates(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
feature featuregate.Feature
|
||||
wantConfig *schedulerapi.Plugins
|
||||
}{
|
||||
{
|
||||
name: "Feature gates disabled",
|
||||
wantConfig: &schedulerapi.Plugins{
|
||||
QueueSort: &schedulerapi.PluginSet{
|
||||
Enabled: []schedulerapi.Plugin{
|
||||
{Name: queuesort.Name},
|
||||
},
|
||||
},
|
||||
PreFilter: &schedulerapi.PluginSet{
|
||||
Enabled: []schedulerapi.Plugin{
|
||||
{Name: noderesources.FitName},
|
||||
{Name: nodeports.Name},
|
||||
{Name: podtopologyspread.Name},
|
||||
{Name: interpodaffinity.Name},
|
||||
},
|
||||
},
|
||||
Filter: &schedulerapi.PluginSet{
|
||||
Enabled: []schedulerapi.Plugin{
|
||||
{Name: nodeunschedulable.Name},
|
||||
{Name: noderesources.FitName},
|
||||
{Name: nodename.Name},
|
||||
{Name: nodeports.Name},
|
||||
{Name: nodeaffinity.Name},
|
||||
{Name: volumerestrictions.Name},
|
||||
{Name: tainttoleration.Name},
|
||||
{Name: nodevolumelimits.EBSName},
|
||||
{Name: nodevolumelimits.GCEPDName},
|
||||
{Name: nodevolumelimits.CSIName},
|
||||
{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: tainttoleration.Name},
|
||||
{Name: defaultpodtopologyspread.Name},
|
||||
},
|
||||
},
|
||||
Score: &schedulerapi.PluginSet{
|
||||
Enabled: []schedulerapi.Plugin{
|
||||
{Name: noderesources.BalancedAllocationName, Weight: 1},
|
||||
{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: podtopologyspread.Name, Weight: 2},
|
||||
{Name: tainttoleration.Name, Weight: 1},
|
||||
{Name: defaultpodtopologyspread.Name, Weight: 1},
|
||||
},
|
||||
},
|
||||
Reserve: &schedulerapi.PluginSet{
|
||||
Enabled: []schedulerapi.Plugin{
|
||||
{Name: volumebinding.Name},
|
||||
},
|
||||
},
|
||||
Unreserve: &schedulerapi.PluginSet{
|
||||
Enabled: []schedulerapi.Plugin{
|
||||
{Name: volumebinding.Name},
|
||||
},
|
||||
},
|
||||
PreBind: &schedulerapi.PluginSet{
|
||||
Enabled: []schedulerapi.Plugin{
|
||||
{Name: volumebinding.Name},
|
||||
},
|
||||
},
|
||||
Bind: &schedulerapi.PluginSet{
|
||||
Enabled: []schedulerapi.Plugin{
|
||||
{Name: defaultbinder.Name},
|
||||
},
|
||||
},
|
||||
PostBind: &schedulerapi.PluginSet{
|
||||
Enabled: []schedulerapi.Plugin{
|
||||
{Name: volumebinding.Name},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "NewDefaultPodTopologySpread enabled",
|
||||
feature: features.DefaultPodTopologySpread,
|
||||
wantConfig: &schedulerapi.Plugins{
|
||||
QueueSort: &schedulerapi.PluginSet{
|
||||
Enabled: []schedulerapi.Plugin{
|
||||
{Name: queuesort.Name},
|
||||
},
|
||||
},
|
||||
PreFilter: &schedulerapi.PluginSet{
|
||||
Enabled: []schedulerapi.Plugin{
|
||||
{Name: noderesources.FitName},
|
||||
{Name: nodeports.Name},
|
||||
{Name: podtopologyspread.Name},
|
||||
{Name: interpodaffinity.Name},
|
||||
},
|
||||
},
|
||||
Filter: &schedulerapi.PluginSet{
|
||||
Enabled: []schedulerapi.Plugin{
|
||||
{Name: nodeunschedulable.Name},
|
||||
{Name: noderesources.FitName},
|
||||
{Name: nodename.Name},
|
||||
{Name: nodeports.Name},
|
||||
{Name: nodeaffinity.Name},
|
||||
{Name: volumerestrictions.Name},
|
||||
{Name: tainttoleration.Name},
|
||||
{Name: nodevolumelimits.EBSName},
|
||||
{Name: nodevolumelimits.GCEPDName},
|
||||
{Name: nodevolumelimits.CSIName},
|
||||
{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: tainttoleration.Name},
|
||||
},
|
||||
},
|
||||
Score: &schedulerapi.PluginSet{
|
||||
Enabled: []schedulerapi.Plugin{
|
||||
{Name: noderesources.BalancedAllocationName, Weight: 1},
|
||||
{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: podtopologyspread.Name, Weight: 2},
|
||||
{Name: tainttoleration.Name, Weight: 1},
|
||||
},
|
||||
},
|
||||
Reserve: &schedulerapi.PluginSet{
|
||||
Enabled: []schedulerapi.Plugin{
|
||||
{Name: volumebinding.Name},
|
||||
},
|
||||
},
|
||||
Unreserve: &schedulerapi.PluginSet{
|
||||
Enabled: []schedulerapi.Plugin{
|
||||
{Name: volumebinding.Name},
|
||||
},
|
||||
},
|
||||
PreBind: &schedulerapi.PluginSet{
|
||||
Enabled: []schedulerapi.Plugin{
|
||||
{Name: volumebinding.Name},
|
||||
},
|
||||
},
|
||||
Bind: &schedulerapi.PluginSet{
|
||||
Enabled: []schedulerapi.Plugin{
|
||||
{Name: defaultbinder.Name},
|
||||
},
|
||||
},
|
||||
PostBind: &schedulerapi.PluginSet{
|
||||
Enabled: []schedulerapi.Plugin{
|
||||
{Name: volumebinding.Name},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
if test.feature != "" {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, test.feature, true)()
|
||||
}
|
||||
|
||||
r := NewRegistry()
|
||||
gotConfig := r[schedulerapi.SchedulerDefaultProviderName]
|
||||
if diff := cmp.Diff(test.wantConfig, gotConfig); diff != "" {
|
||||
t.Errorf("unexpected config diff (-want, +got): %s", diff)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -1410,8 +1410,8 @@ func TestAlgorithmProviderCompatibility(t *testing.T) {
|
||||
"PreScorePlugin": {
|
||||
{Name: "InterPodAffinity"},
|
||||
{Name: "PodTopologySpread"},
|
||||
{Name: "DefaultPodTopologySpread"},
|
||||
{Name: "TaintToleration"},
|
||||
{Name: "DefaultPodTopologySpread"},
|
||||
},
|
||||
"ScorePlugin": {
|
||||
{Name: "NodeResourcesBalancedAllocation", Weight: 1},
|
||||
@ -1421,8 +1421,8 @@ func TestAlgorithmProviderCompatibility(t *testing.T) {
|
||||
{Name: "NodeAffinity", Weight: 1},
|
||||
{Name: "NodePreferAvoidPods", Weight: 10000},
|
||||
{Name: "PodTopologySpread", Weight: 2},
|
||||
{Name: "DefaultPodTopologySpread", Weight: 1},
|
||||
{Name: "TaintToleration", Weight: 1},
|
||||
{Name: "DefaultPodTopologySpread", Weight: 1},
|
||||
},
|
||||
"BindPlugin": {{Name: "DefaultBinder"}},
|
||||
"ReservePlugin": {{Name: "VolumeBinding"}},
|
||||
@ -1478,8 +1478,8 @@ func TestAlgorithmProviderCompatibility(t *testing.T) {
|
||||
"PreScorePlugin": {
|
||||
{Name: "InterPodAffinity"},
|
||||
{Name: "PodTopologySpread"},
|
||||
{Name: "DefaultPodTopologySpread"},
|
||||
{Name: "TaintToleration"},
|
||||
{Name: "DefaultPodTopologySpread"},
|
||||
},
|
||||
"ScorePlugin": {
|
||||
{Name: "NodeResourcesBalancedAllocation", Weight: 1},
|
||||
@ -1489,8 +1489,8 @@ func TestAlgorithmProviderCompatibility(t *testing.T) {
|
||||
{Name: "NodeAffinity", Weight: 1},
|
||||
{Name: "NodePreferAvoidPods", Weight: 10000},
|
||||
{Name: "PodTopologySpread", Weight: 2},
|
||||
{Name: "DefaultPodTopologySpread", Weight: 1},
|
||||
{Name: "TaintToleration", Weight: 1},
|
||||
{Name: "DefaultPodTopologySpread", Weight: 1},
|
||||
},
|
||||
"ReservePlugin": {{Name: "VolumeBinding"}},
|
||||
"UnreservePlugin": {{Name: "VolumeBinding"}},
|
||||
@ -1566,8 +1566,8 @@ func TestPluginsConfigurationCompatibility(t *testing.T) {
|
||||
"PreScorePlugin": {
|
||||
{Name: "InterPodAffinity"},
|
||||
{Name: "PodTopologySpread"},
|
||||
{Name: "DefaultPodTopologySpread"},
|
||||
{Name: "TaintToleration"},
|
||||
{Name: "DefaultPodTopologySpread"},
|
||||
},
|
||||
"ScorePlugin": {
|
||||
{Name: "NodeResourcesBalancedAllocation", Weight: 1},
|
||||
@ -1577,8 +1577,8 @@ func TestPluginsConfigurationCompatibility(t *testing.T) {
|
||||
{Name: "NodeAffinity", Weight: 1},
|
||||
{Name: "NodePreferAvoidPods", Weight: 10000},
|
||||
{Name: "PodTopologySpread", Weight: 2},
|
||||
{Name: "DefaultPodTopologySpread", Weight: 1},
|
||||
{Name: "TaintToleration", Weight: 1},
|
||||
{Name: "DefaultPodTopologySpread", Weight: 1},
|
||||
},
|
||||
"ReservePlugin": {{Name: "VolumeBinding"}},
|
||||
"UnreservePlugin": {{Name: "VolumeBinding"}},
|
||||
|
@ -15,12 +15,14 @@ go_library(
|
||||
visibility = ["//visibility:public"],
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/features:go_default_library",
|
||||
"//pkg/scheduler/apis/config:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/conversion:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//staging/src/k8s.io/component-base/config/v1alpha1:go_default_library",
|
||||
"//staging/src/k8s.io/kube-scheduler/config/v1:go_default_library",
|
||||
"//staging/src/k8s.io/kube-scheduler/config/v1beta1:go_default_library",
|
||||
@ -36,11 +38,16 @@ go_test(
|
||||
],
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/features:go_default_library",
|
||||
"//pkg/scheduler/apis/config:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apimachinery/pkg/util/runtime:go_default_library",
|
||||
"//staging/src/k8s.io/apiserver/pkg/util/feature:go_default_library",
|
||||
"//staging/src/k8s.io/component-base/config/v1alpha1:go_default_library",
|
||||
"//staging/src/k8s.io/component-base/featuregate:go_default_library",
|
||||
"//staging/src/k8s.io/component-base/featuregate/testing:go_default_library",
|
||||
"//staging/src/k8s.io/kube-scheduler/config/v1beta1:go_default_library",
|
||||
"//vendor/github.com/google/go-cmp/cmp:go_default_library",
|
||||
"//vendor/k8s.io/utils/pointer:go_default_library",
|
||||
|
@ -22,8 +22,10 @@ import (
|
||||
|
||||
v1 "k8s.io/api/core/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/apiserver/pkg/util/feature"
|
||||
componentbaseconfigv1alpha1 "k8s.io/component-base/config/v1alpha1"
|
||||
"k8s.io/kube-scheduler/config/v1beta1"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/kubernetes/pkg/scheduler/apis/config"
|
||||
"k8s.io/utils/pointer"
|
||||
|
||||
@ -193,3 +195,25 @@ func SetDefaults_VolumeBindingArgs(obj *v1beta1.VolumeBindingArgs) {
|
||||
obj.BindTimeoutSeconds = pointer.Int64Ptr(600)
|
||||
}
|
||||
}
|
||||
|
||||
func SetDefaults_PodTopologySpreadArgs(obj *v1beta1.PodTopologySpreadArgs) {
|
||||
if !feature.DefaultFeatureGate.Enabled(features.DefaultPodTopologySpread) {
|
||||
// When feature is disabled, the default spreading is done by legacy
|
||||
// DefaultPodTopologySpread plugin.
|
||||
return
|
||||
}
|
||||
if obj.DefaultConstraints == nil {
|
||||
obj.DefaultConstraints = []v1.TopologySpreadConstraint{
|
||||
{
|
||||
TopologyKey: v1.LabelHostname,
|
||||
WhenUnsatisfiable: v1.ScheduleAnyway,
|
||||
MaxSkew: 3,
|
||||
},
|
||||
{
|
||||
TopologyKey: v1.LabelZoneFailureDomainStable,
|
||||
WhenUnsatisfiable: v1.ScheduleAnyway,
|
||||
MaxSkew: 5,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,11 +21,16 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
v1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||
componentbaseconfig "k8s.io/component-base/config/v1alpha1"
|
||||
"k8s.io/component-base/featuregate"
|
||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
||||
"k8s.io/kube-scheduler/config/v1beta1"
|
||||
"k8s.io/kubernetes/pkg/features"
|
||||
"k8s.io/utils/pointer"
|
||||
)
|
||||
|
||||
@ -265,9 +270,10 @@ func TestSchedulerDefaults(t *testing.T) {
|
||||
|
||||
func TestPluginArgsDefaults(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
in runtime.Object
|
||||
want runtime.Object
|
||||
name string
|
||||
feature featuregate.Feature
|
||||
in runtime.Object
|
||||
want runtime.Object
|
||||
}{
|
||||
{
|
||||
name: "InterPodAffinityArgs empty",
|
||||
@ -363,11 +369,59 @@ func TestPluginArgsDefaults(t *testing.T) {
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "PodTopologySpreadArgs resources empty",
|
||||
in: &v1beta1.PodTopologySpreadArgs{},
|
||||
want: &v1beta1.PodTopologySpreadArgs{},
|
||||
},
|
||||
{
|
||||
name: "PodTopologySpreadArgs resources with value",
|
||||
in: &v1beta1.PodTopologySpreadArgs{
|
||||
DefaultConstraints: []v1.TopologySpreadConstraint{
|
||||
{
|
||||
TopologyKey: "planet",
|
||||
WhenUnsatisfiable: v1.DoNotSchedule,
|
||||
MaxSkew: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
want: &v1beta1.PodTopologySpreadArgs{
|
||||
DefaultConstraints: []v1.TopologySpreadConstraint{
|
||||
{
|
||||
TopologyKey: "planet",
|
||||
WhenUnsatisfiable: v1.DoNotSchedule,
|
||||
MaxSkew: 2,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "PodTopologySpreadArgs resources empty, NewPodTopologySpread feature enabled",
|
||||
feature: features.DefaultPodTopologySpread,
|
||||
in: &v1beta1.PodTopologySpreadArgs{},
|
||||
want: &v1beta1.PodTopologySpreadArgs{
|
||||
DefaultConstraints: []v1.TopologySpreadConstraint{
|
||||
{
|
||||
TopologyKey: v1.LabelHostname,
|
||||
WhenUnsatisfiable: v1.ScheduleAnyway,
|
||||
MaxSkew: 3,
|
||||
},
|
||||
{
|
||||
TopologyKey: v1.LabelZoneFailureDomainStable,
|
||||
WhenUnsatisfiable: v1.ScheduleAnyway,
|
||||
MaxSkew: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, tc := range tests {
|
||||
scheme := runtime.NewScheme()
|
||||
utilruntime.Must(AddToScheme(scheme))
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
if tc.feature != "" {
|
||||
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, tc.feature, true)()
|
||||
}
|
||||
scheme.Default(tc.in)
|
||||
if diff := cmp.Diff(tc.in, tc.want); diff != "" {
|
||||
t.Errorf("Got unexpected defaults (-want, +got):\n%s", diff)
|
||||
|
@ -39,6 +39,7 @@ func RegisterDefaults(scheme *runtime.Scheme) error {
|
||||
scheme.AddTypeDefaultingFunc(&v1beta1.NodeResourcesMostAllocatedArgs{}, func(obj interface{}) {
|
||||
SetObjectDefaults_NodeResourcesMostAllocatedArgs(obj.(*v1beta1.NodeResourcesMostAllocatedArgs))
|
||||
})
|
||||
scheme.AddTypeDefaultingFunc(&v1beta1.PodTopologySpreadArgs{}, func(obj interface{}) { SetObjectDefaults_PodTopologySpreadArgs(obj.(*v1beta1.PodTopologySpreadArgs)) })
|
||||
scheme.AddTypeDefaultingFunc(&v1beta1.RequestedToCapacityRatioArgs{}, func(obj interface{}) {
|
||||
SetObjectDefaults_RequestedToCapacityRatioArgs(obj.(*v1beta1.RequestedToCapacityRatioArgs))
|
||||
})
|
||||
@ -62,6 +63,10 @@ func SetObjectDefaults_NodeResourcesMostAllocatedArgs(in *v1beta1.NodeResourcesM
|
||||
SetDefaults_NodeResourcesMostAllocatedArgs(in)
|
||||
}
|
||||
|
||||
func SetObjectDefaults_PodTopologySpreadArgs(in *v1beta1.PodTopologySpreadArgs) {
|
||||
SetDefaults_PodTopologySpreadArgs(in)
|
||||
}
|
||||
|
||||
func SetObjectDefaults_RequestedToCapacityRatioArgs(in *v1beta1.RequestedToCapacityRatioArgs) {
|
||||
SetDefaults_RequestedToCapacityRatioArgs(in)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user