mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-25 20:53:33 +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": {
|
"PreScorePlugin": {
|
||||||
{Name: "InterPodAffinity"},
|
{Name: "InterPodAffinity"},
|
||||||
{Name: "PodTopologySpread"},
|
{Name: "PodTopologySpread"},
|
||||||
{Name: "DefaultPodTopologySpread"},
|
|
||||||
{Name: "TaintToleration"},
|
{Name: "TaintToleration"},
|
||||||
|
{Name: "DefaultPodTopologySpread"},
|
||||||
},
|
},
|
||||||
"ScorePlugin": {
|
"ScorePlugin": {
|
||||||
{Name: "NodeResourcesBalancedAllocation", Weight: 1},
|
{Name: "NodeResourcesBalancedAllocation", Weight: 1},
|
||||||
@ -188,8 +188,8 @@ profiles:
|
|||||||
{Name: "NodeAffinity", Weight: 1},
|
{Name: "NodeAffinity", Weight: 1},
|
||||||
{Name: "NodePreferAvoidPods", Weight: 10000},
|
{Name: "NodePreferAvoidPods", Weight: 10000},
|
||||||
{Name: "PodTopologySpread", Weight: 2},
|
{Name: "PodTopologySpread", Weight: 2},
|
||||||
{Name: "DefaultPodTopologySpread", Weight: 1},
|
|
||||||
{Name: "TaintToleration", Weight: 1},
|
{Name: "TaintToleration", Weight: 1},
|
||||||
|
{Name: "DefaultPodTopologySpread", Weight: 1},
|
||||||
},
|
},
|
||||||
"BindPlugin": {{Name: "DefaultBinder"}},
|
"BindPlugin": {{Name: "DefaultBinder"}},
|
||||||
"ReservePlugin": {{Name: "VolumeBinding"}},
|
"ReservePlugin": {{Name: "VolumeBinding"}},
|
||||||
@ -308,8 +308,8 @@ profiles:
|
|||||||
"PreScorePlugin": {
|
"PreScorePlugin": {
|
||||||
{Name: "InterPodAffinity"},
|
{Name: "InterPodAffinity"},
|
||||||
{Name: "PodTopologySpread"},
|
{Name: "PodTopologySpread"},
|
||||||
{Name: "DefaultPodTopologySpread"},
|
|
||||||
{Name: "TaintToleration"},
|
{Name: "TaintToleration"},
|
||||||
|
{Name: "DefaultPodTopologySpread"},
|
||||||
},
|
},
|
||||||
"ScorePlugin": {
|
"ScorePlugin": {
|
||||||
{Name: "NodeResourcesBalancedAllocation", Weight: 1},
|
{Name: "NodeResourcesBalancedAllocation", Weight: 1},
|
||||||
@ -319,8 +319,8 @@ profiles:
|
|||||||
{Name: "NodeAffinity", Weight: 1},
|
{Name: "NodeAffinity", Weight: 1},
|
||||||
{Name: "NodePreferAvoidPods", Weight: 10000},
|
{Name: "NodePreferAvoidPods", Weight: 10000},
|
||||||
{Name: "PodTopologySpread", Weight: 2},
|
{Name: "PodTopologySpread", Weight: 2},
|
||||||
{Name: "DefaultPodTopologySpread", Weight: 1},
|
|
||||||
{Name: "TaintToleration", Weight: 1},
|
{Name: "TaintToleration", Weight: 1},
|
||||||
|
{Name: "DefaultPodTopologySpread", Weight: 1},
|
||||||
},
|
},
|
||||||
"BindPlugin": {{Name: "DefaultBinder"}},
|
"BindPlugin": {{Name: "DefaultBinder"}},
|
||||||
"ReservePlugin": {{Name: "VolumeBinding"}},
|
"ReservePlugin": {{Name: "VolumeBinding"}},
|
||||||
|
@ -293,6 +293,13 @@ const (
|
|||||||
// Enables CSI Inline volumes support for pods
|
// Enables CSI Inline volumes support for pods
|
||||||
CSIInlineVolume featuregate.Feature = "CSIInlineVolume"
|
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
|
// owner: @tallclair
|
||||||
// alpha: v1.12
|
// alpha: v1.12
|
||||||
// beta: v1.14
|
// beta: v1.14
|
||||||
@ -660,6 +667,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
|
|||||||
HugePageStorageMediumSize: {Default: false, PreRelease: featuregate.Alpha},
|
HugePageStorageMediumSize: {Default: false, PreRelease: featuregate.Alpha},
|
||||||
ExternalPolicyForExternalIP: {Default: true, PreRelease: featuregate.GA}, // remove in 1.20
|
ExternalPolicyForExternalIP: {Default: true, PreRelease: featuregate.GA}, // remove in 1.20
|
||||||
AnyVolumeDataSource: {Default: false, PreRelease: featuregate.Alpha},
|
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
|
// inherited features from generic apiserver, relisted here to get a conflict if it is changed
|
||||||
// unintentionally on either side:
|
// unintentionally on either side:
|
||||||
|
@ -11,6 +11,7 @@ go_library(
|
|||||||
srcs = ["registry.go"],
|
srcs = ["registry.go"],
|
||||||
importpath = "k8s.io/kubernetes/pkg/scheduler/algorithmprovider",
|
importpath = "k8s.io/kubernetes/pkg/scheduler/algorithmprovider",
|
||||||
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/defaultpodtopologyspread: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/volumebinding:go_default_library",
|
||||||
"//pkg/scheduler/framework/plugins/volumerestrictions:go_default_library",
|
"//pkg/scheduler/framework/plugins/volumerestrictions:go_default_library",
|
||||||
"//pkg/scheduler/framework/plugins/volumezone: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"],
|
srcs = ["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/defaultbinder:go_default_library",
|
"//pkg/scheduler/framework/plugins/defaultbinder:go_default_library",
|
||||||
"//pkg/scheduler/framework/plugins/defaultpodtopologyspread: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/volumebinding:go_default_library",
|
||||||
"//pkg/scheduler/framework/plugins/volumerestrictions:go_default_library",
|
"//pkg/scheduler/framework/plugins/volumerestrictions:go_default_library",
|
||||||
"//pkg/scheduler/framework/plugins/volumezone: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",
|
"//vendor/github.com/google/go-cmp/cmp:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -20,6 +20,9 @@ import (
|
|||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"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"
|
schedulerapi "k8s.io/kubernetes/pkg/scheduler/apis/config"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultbinder"
|
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultbinder"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultpodtopologyspread"
|
"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.
|
// NewRegistry returns an algorithm provider registry instance.
|
||||||
func NewRegistry() Registry {
|
func NewRegistry() Registry {
|
||||||
defaultConfig := getDefaultConfig()
|
defaultConfig := getDefaultConfig()
|
||||||
|
applyFeatureGates(defaultConfig)
|
||||||
|
|
||||||
caConfig := getClusterAutoscalerConfig()
|
caConfig := getClusterAutoscalerConfig()
|
||||||
|
applyFeatureGates(caConfig)
|
||||||
|
|
||||||
return Registry{
|
return Registry{
|
||||||
schedulerapi.SchedulerDefaultProviderName: defaultConfig,
|
schedulerapi.SchedulerDefaultProviderName: defaultConfig,
|
||||||
@ -106,7 +112,6 @@ func getDefaultConfig() *schedulerapi.Plugins {
|
|||||||
Enabled: []schedulerapi.Plugin{
|
Enabled: []schedulerapi.Plugin{
|
||||||
{Name: interpodaffinity.Name},
|
{Name: interpodaffinity.Name},
|
||||||
{Name: podtopologyspread.Name},
|
{Name: podtopologyspread.Name},
|
||||||
{Name: defaultpodtopologyspread.Name},
|
|
||||||
{Name: tainttoleration.Name},
|
{Name: tainttoleration.Name},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -122,7 +127,6 @@ func getDefaultConfig() *schedulerapi.Plugins {
|
|||||||
// - This is a score coming from user preference.
|
// - This is a score coming from user preference.
|
||||||
// - It makes its signal comparable to NodeResourcesLeastAllocated.
|
// - It makes its signal comparable to NodeResourcesLeastAllocated.
|
||||||
{Name: podtopologyspread.Name, Weight: 2},
|
{Name: podtopologyspread.Name, Weight: 2},
|
||||||
{Name: defaultpodtopologyspread.Name, Weight: 1},
|
|
||||||
{Name: tainttoleration.Name, Weight: 1},
|
{Name: tainttoleration.Name, Weight: 1},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -164,3 +168,15 @@ func getClusterAutoscalerConfig() *schedulerapi.Plugins {
|
|||||||
}
|
}
|
||||||
return caConfig
|
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"
|
"testing"
|
||||||
|
|
||||||
"github.com/google/go-cmp/cmp"
|
"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"
|
schedulerapi "k8s.io/kubernetes/pkg/scheduler/apis/config"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultbinder"
|
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultbinder"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultpodtopologyspread"
|
"k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultpodtopologyspread"
|
||||||
@ -79,8 +83,8 @@ func TestClusterAutoscalerProvider(t *testing.T) {
|
|||||||
Enabled: []schedulerapi.Plugin{
|
Enabled: []schedulerapi.Plugin{
|
||||||
{Name: interpodaffinity.Name},
|
{Name: interpodaffinity.Name},
|
||||||
{Name: podtopologyspread.Name},
|
{Name: podtopologyspread.Name},
|
||||||
{Name: defaultpodtopologyspread.Name},
|
|
||||||
{Name: tainttoleration.Name},
|
{Name: tainttoleration.Name},
|
||||||
|
{Name: defaultpodtopologyspread.Name},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Score: &schedulerapi.PluginSet{
|
Score: &schedulerapi.PluginSet{
|
||||||
@ -92,8 +96,8 @@ func TestClusterAutoscalerProvider(t *testing.T) {
|
|||||||
{Name: nodeaffinity.Name, Weight: 1},
|
{Name: nodeaffinity.Name, Weight: 1},
|
||||||
{Name: nodepreferavoidpods.Name, Weight: 10000},
|
{Name: nodepreferavoidpods.Name, Weight: 10000},
|
||||||
{Name: podtopologyspread.Name, Weight: 2},
|
{Name: podtopologyspread.Name, Weight: 2},
|
||||||
{Name: defaultpodtopologyspread.Name, Weight: 1},
|
|
||||||
{Name: tainttoleration.Name, Weight: 1},
|
{Name: tainttoleration.Name, Weight: 1},
|
||||||
|
{Name: defaultpodtopologyspread.Name, Weight: 1},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Reserve: &schedulerapi.PluginSet{
|
Reserve: &schedulerapi.PluginSet{
|
||||||
@ -129,3 +133,191 @@ func TestClusterAutoscalerProvider(t *testing.T) {
|
|||||||
t.Errorf("unexpected config diff (-want, +got): %s", diff)
|
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": {
|
"PreScorePlugin": {
|
||||||
{Name: "InterPodAffinity"},
|
{Name: "InterPodAffinity"},
|
||||||
{Name: "PodTopologySpread"},
|
{Name: "PodTopologySpread"},
|
||||||
{Name: "DefaultPodTopologySpread"},
|
|
||||||
{Name: "TaintToleration"},
|
{Name: "TaintToleration"},
|
||||||
|
{Name: "DefaultPodTopologySpread"},
|
||||||
},
|
},
|
||||||
"ScorePlugin": {
|
"ScorePlugin": {
|
||||||
{Name: "NodeResourcesBalancedAllocation", Weight: 1},
|
{Name: "NodeResourcesBalancedAllocation", Weight: 1},
|
||||||
@ -1421,8 +1421,8 @@ func TestAlgorithmProviderCompatibility(t *testing.T) {
|
|||||||
{Name: "NodeAffinity", Weight: 1},
|
{Name: "NodeAffinity", Weight: 1},
|
||||||
{Name: "NodePreferAvoidPods", Weight: 10000},
|
{Name: "NodePreferAvoidPods", Weight: 10000},
|
||||||
{Name: "PodTopologySpread", Weight: 2},
|
{Name: "PodTopologySpread", Weight: 2},
|
||||||
{Name: "DefaultPodTopologySpread", Weight: 1},
|
|
||||||
{Name: "TaintToleration", Weight: 1},
|
{Name: "TaintToleration", Weight: 1},
|
||||||
|
{Name: "DefaultPodTopologySpread", Weight: 1},
|
||||||
},
|
},
|
||||||
"BindPlugin": {{Name: "DefaultBinder"}},
|
"BindPlugin": {{Name: "DefaultBinder"}},
|
||||||
"ReservePlugin": {{Name: "VolumeBinding"}},
|
"ReservePlugin": {{Name: "VolumeBinding"}},
|
||||||
@ -1478,8 +1478,8 @@ func TestAlgorithmProviderCompatibility(t *testing.T) {
|
|||||||
"PreScorePlugin": {
|
"PreScorePlugin": {
|
||||||
{Name: "InterPodAffinity"},
|
{Name: "InterPodAffinity"},
|
||||||
{Name: "PodTopologySpread"},
|
{Name: "PodTopologySpread"},
|
||||||
{Name: "DefaultPodTopologySpread"},
|
|
||||||
{Name: "TaintToleration"},
|
{Name: "TaintToleration"},
|
||||||
|
{Name: "DefaultPodTopologySpread"},
|
||||||
},
|
},
|
||||||
"ScorePlugin": {
|
"ScorePlugin": {
|
||||||
{Name: "NodeResourcesBalancedAllocation", Weight: 1},
|
{Name: "NodeResourcesBalancedAllocation", Weight: 1},
|
||||||
@ -1489,8 +1489,8 @@ func TestAlgorithmProviderCompatibility(t *testing.T) {
|
|||||||
{Name: "NodeAffinity", Weight: 1},
|
{Name: "NodeAffinity", Weight: 1},
|
||||||
{Name: "NodePreferAvoidPods", Weight: 10000},
|
{Name: "NodePreferAvoidPods", Weight: 10000},
|
||||||
{Name: "PodTopologySpread", Weight: 2},
|
{Name: "PodTopologySpread", Weight: 2},
|
||||||
{Name: "DefaultPodTopologySpread", Weight: 1},
|
|
||||||
{Name: "TaintToleration", Weight: 1},
|
{Name: "TaintToleration", Weight: 1},
|
||||||
|
{Name: "DefaultPodTopologySpread", Weight: 1},
|
||||||
},
|
},
|
||||||
"ReservePlugin": {{Name: "VolumeBinding"}},
|
"ReservePlugin": {{Name: "VolumeBinding"}},
|
||||||
"UnreservePlugin": {{Name: "VolumeBinding"}},
|
"UnreservePlugin": {{Name: "VolumeBinding"}},
|
||||||
@ -1566,8 +1566,8 @@ func TestPluginsConfigurationCompatibility(t *testing.T) {
|
|||||||
"PreScorePlugin": {
|
"PreScorePlugin": {
|
||||||
{Name: "InterPodAffinity"},
|
{Name: "InterPodAffinity"},
|
||||||
{Name: "PodTopologySpread"},
|
{Name: "PodTopologySpread"},
|
||||||
{Name: "DefaultPodTopologySpread"},
|
|
||||||
{Name: "TaintToleration"},
|
{Name: "TaintToleration"},
|
||||||
|
{Name: "DefaultPodTopologySpread"},
|
||||||
},
|
},
|
||||||
"ScorePlugin": {
|
"ScorePlugin": {
|
||||||
{Name: "NodeResourcesBalancedAllocation", Weight: 1},
|
{Name: "NodeResourcesBalancedAllocation", Weight: 1},
|
||||||
@ -1577,8 +1577,8 @@ func TestPluginsConfigurationCompatibility(t *testing.T) {
|
|||||||
{Name: "NodeAffinity", Weight: 1},
|
{Name: "NodeAffinity", Weight: 1},
|
||||||
{Name: "NodePreferAvoidPods", Weight: 10000},
|
{Name: "NodePreferAvoidPods", Weight: 10000},
|
||||||
{Name: "PodTopologySpread", Weight: 2},
|
{Name: "PodTopologySpread", Weight: 2},
|
||||||
{Name: "DefaultPodTopologySpread", Weight: 1},
|
|
||||||
{Name: "TaintToleration", Weight: 1},
|
{Name: "TaintToleration", Weight: 1},
|
||||||
|
{Name: "DefaultPodTopologySpread", Weight: 1},
|
||||||
},
|
},
|
||||||
"ReservePlugin": {{Name: "VolumeBinding"}},
|
"ReservePlugin": {{Name: "VolumeBinding"}},
|
||||||
"UnreservePlugin": {{Name: "VolumeBinding"}},
|
"UnreservePlugin": {{Name: "VolumeBinding"}},
|
||||||
|
@ -15,12 +15,14 @@ go_library(
|
|||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
"//pkg/apis/core:go_default_library",
|
"//pkg/apis/core:go_default_library",
|
||||||
|
"//pkg/features:go_default_library",
|
||||||
"//pkg/scheduler/apis/config:go_default_library",
|
"//pkg/scheduler/apis/config:go_default_library",
|
||||||
"//staging/src/k8s.io/api/core/v1: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/apis/meta/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/conversion: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/runtime:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/util/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/config/v1alpha1:go_default_library",
|
||||||
"//staging/src/k8s.io/kube-scheduler/config/v1: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",
|
"//staging/src/k8s.io/kube-scheduler/config/v1beta1:go_default_library",
|
||||||
@ -36,11 +38,16 @@ go_test(
|
|||||||
],
|
],
|
||||||
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",
|
||||||
|
"//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/apis/meta/v1:go_default_library",
|
||||||
"//staging/src/k8s.io/apimachinery/pkg/runtime: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/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/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",
|
"//staging/src/k8s.io/kube-scheduler/config/v1beta1:go_default_library",
|
||||||
"//vendor/github.com/google/go-cmp/cmp:go_default_library",
|
"//vendor/github.com/google/go-cmp/cmp:go_default_library",
|
||||||
"//vendor/k8s.io/utils/pointer:go_default_library",
|
"//vendor/k8s.io/utils/pointer:go_default_library",
|
||||||
|
@ -22,8 +22,10 @@ import (
|
|||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
|
"k8s.io/apiserver/pkg/util/feature"
|
||||||
componentbaseconfigv1alpha1 "k8s.io/component-base/config/v1alpha1"
|
componentbaseconfigv1alpha1 "k8s.io/component-base/config/v1alpha1"
|
||||||
"k8s.io/kube-scheduler/config/v1beta1"
|
"k8s.io/kube-scheduler/config/v1beta1"
|
||||||
|
"k8s.io/kubernetes/pkg/features"
|
||||||
"k8s.io/kubernetes/pkg/scheduler/apis/config"
|
"k8s.io/kubernetes/pkg/scheduler/apis/config"
|
||||||
"k8s.io/utils/pointer"
|
"k8s.io/utils/pointer"
|
||||||
|
|
||||||
@ -193,3 +195,25 @@ func SetDefaults_VolumeBindingArgs(obj *v1beta1.VolumeBindingArgs) {
|
|||||||
obj.BindTimeoutSeconds = pointer.Int64Ptr(600)
|
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"
|
"time"
|
||||||
|
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
|
v1 "k8s.io/api/core/v1"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/runtime"
|
"k8s.io/apimachinery/pkg/runtime"
|
||||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||||
|
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
||||||
componentbaseconfig "k8s.io/component-base/config/v1alpha1"
|
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/kube-scheduler/config/v1beta1"
|
||||||
|
"k8s.io/kubernetes/pkg/features"
|
||||||
"k8s.io/utils/pointer"
|
"k8s.io/utils/pointer"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -265,9 +270,10 @@ func TestSchedulerDefaults(t *testing.T) {
|
|||||||
|
|
||||||
func TestPluginArgsDefaults(t *testing.T) {
|
func TestPluginArgsDefaults(t *testing.T) {
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
name string
|
name string
|
||||||
in runtime.Object
|
feature featuregate.Feature
|
||||||
want runtime.Object
|
in runtime.Object
|
||||||
|
want runtime.Object
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "InterPodAffinityArgs empty",
|
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 {
|
for _, tc := range tests {
|
||||||
scheme := runtime.NewScheme()
|
scheme := runtime.NewScheme()
|
||||||
utilruntime.Must(AddToScheme(scheme))
|
utilruntime.Must(AddToScheme(scheme))
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
if tc.feature != "" {
|
||||||
|
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, tc.feature, true)()
|
||||||
|
}
|
||||||
scheme.Default(tc.in)
|
scheme.Default(tc.in)
|
||||||
if diff := cmp.Diff(tc.in, tc.want); diff != "" {
|
if diff := cmp.Diff(tc.in, tc.want); diff != "" {
|
||||||
t.Errorf("Got unexpected defaults (-want, +got):\n%s", 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{}) {
|
scheme.AddTypeDefaultingFunc(&v1beta1.NodeResourcesMostAllocatedArgs{}, func(obj interface{}) {
|
||||||
SetObjectDefaults_NodeResourcesMostAllocatedArgs(obj.(*v1beta1.NodeResourcesMostAllocatedArgs))
|
SetObjectDefaults_NodeResourcesMostAllocatedArgs(obj.(*v1beta1.NodeResourcesMostAllocatedArgs))
|
||||||
})
|
})
|
||||||
|
scheme.AddTypeDefaultingFunc(&v1beta1.PodTopologySpreadArgs{}, func(obj interface{}) { SetObjectDefaults_PodTopologySpreadArgs(obj.(*v1beta1.PodTopologySpreadArgs)) })
|
||||||
scheme.AddTypeDefaultingFunc(&v1beta1.RequestedToCapacityRatioArgs{}, func(obj interface{}) {
|
scheme.AddTypeDefaultingFunc(&v1beta1.RequestedToCapacityRatioArgs{}, func(obj interface{}) {
|
||||||
SetObjectDefaults_RequestedToCapacityRatioArgs(obj.(*v1beta1.RequestedToCapacityRatioArgs))
|
SetObjectDefaults_RequestedToCapacityRatioArgs(obj.(*v1beta1.RequestedToCapacityRatioArgs))
|
||||||
})
|
})
|
||||||
@ -62,6 +63,10 @@ func SetObjectDefaults_NodeResourcesMostAllocatedArgs(in *v1beta1.NodeResourcesM
|
|||||||
SetDefaults_NodeResourcesMostAllocatedArgs(in)
|
SetDefaults_NodeResourcesMostAllocatedArgs(in)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func SetObjectDefaults_PodTopologySpreadArgs(in *v1beta1.PodTopologySpreadArgs) {
|
||||||
|
SetDefaults_PodTopologySpreadArgs(in)
|
||||||
|
}
|
||||||
|
|
||||||
func SetObjectDefaults_RequestedToCapacityRatioArgs(in *v1beta1.RequestedToCapacityRatioArgs) {
|
func SetObjectDefaults_RequestedToCapacityRatioArgs(in *v1beta1.RequestedToCapacityRatioArgs) {
|
||||||
SetDefaults_RequestedToCapacityRatioArgs(in)
|
SetDefaults_RequestedToCapacityRatioArgs(in)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user