diff --git a/pkg/features/kube_features.go b/pkg/features/kube_features.go index 314b08868c3..46d7ed0dd9d 100644 --- a/pkg/features/kube_features.go +++ b/pkg/features/kube_features.go @@ -700,6 +700,14 @@ const ( // equals to spec.parallelism before and after the update. ElasticIndexedJob featuregate.Feature = "ElasticIndexedJob" + // owner: @sanposhiho + // kep: http://kep.k8s.io/3063 + // beta: v1.28 + // + // Enables the scheduler's enhancement called QueueingHints, + // which benefits to reduce the useless requeueing. + SchedulerQueueingHints featuregate.Feature = "SchedulerQueueingHints" + // owner: @saschagrunert // kep: https://kep.k8s.io/2413 // alpha: v1.22 @@ -1051,6 +1059,8 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS ElasticIndexedJob: {Default: true, PreRelease: featuregate.Beta}, + SchedulerQueueingHints: {Default: true, PreRelease: featuregate.Beta}, + SeccompDefault: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29 SecurityContextDeny: {Default: false, PreRelease: featuregate.Alpha}, diff --git a/pkg/scheduler/scheduler.go b/pkg/scheduler/scheduler.go index 9a6327e89e0..3b0d761a89d 100644 --- a/pkg/scheduler/scheduler.go +++ b/pkg/scheduler/scheduler.go @@ -25,6 +25,7 @@ import ( v1 "k8s.io/api/core/v1" 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/dynamic/dynamicinformer" "k8s.io/client-go/informers" coreinformers "k8s.io/client-go/informers/core/v1" @@ -33,6 +34,7 @@ import ( "k8s.io/client-go/tools/cache" "k8s.io/klog/v2" configv1 "k8s.io/kube-scheduler/config/v1" + "k8s.io/kubernetes/pkg/features" schedulerapi "k8s.io/kubernetes/pkg/scheduler/apis/config" "k8s.io/kubernetes/pkg/scheduler/apis/config/scheme" "k8s.io/kubernetes/pkg/scheduler/framework" @@ -377,7 +379,7 @@ func buildQueueingHintMap(es []framework.EnqueueExtensions) internalqueue.Queuei for _, event := range events { fn := event.QueueingHintFn - if fn == nil { + if fn == nil || !utilfeature.DefaultFeatureGate.Enabled(features.SchedulerQueueingHints) { fn = defaultQueueingHintFn } diff --git a/pkg/scheduler/scheduler_test.go b/pkg/scheduler/scheduler_test.go index 6d06b1a88b8..a85f04261e1 100644 --- a/pkg/scheduler/scheduler_test.go +++ b/pkg/scheduler/scheduler_test.go @@ -30,14 +30,17 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/util/sets" + utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/informers" "k8s.io/client-go/kubernetes" "k8s.io/client-go/kubernetes/fake" "k8s.io/client-go/kubernetes/scheme" "k8s.io/client-go/tools/cache" "k8s.io/client-go/tools/events" + featuregatetesting "k8s.io/component-base/featuregate/testing" "k8s.io/klog/v2" "k8s.io/klog/v2/ktesting" + "k8s.io/kubernetes/pkg/features" schedulerapi "k8s.io/kubernetes/pkg/scheduler/apis/config" "k8s.io/kubernetes/pkg/scheduler/apis/config/testing/defaults" "k8s.io/kubernetes/pkg/scheduler/framework" @@ -657,9 +660,10 @@ const ( func Test_buildQueueingHintMap(t *testing.T) { tests := []struct { - name string - plugins []framework.Plugin - want map[framework.ClusterEvent][]*internalqueue.QueueingHintFunction + name string + plugins []framework.Plugin + want map[framework.ClusterEvent][]*internalqueue.QueueingHintFunction + featuregateDisabled bool }{ { name: "no-op plugin", @@ -760,10 +764,60 @@ func Test_buildQueueingHintMap(t *testing.T) { }, }, }, + { + name: "node and pod plugin (featuregate is disabled)", + plugins: []framework.Plugin{&fakeNodePlugin{}, &fakePodPlugin{}}, + featuregateDisabled: true, + want: map[framework.ClusterEvent][]*internalqueue.QueueingHintFunction{ + {Resource: framework.Pod, ActionType: framework.All}: { + {PluginName: fakeBind, QueueingHintFn: defaultQueueingHintFn}, + {PluginName: queueSort, QueueingHintFn: defaultQueueingHintFn}, + }, + {Resource: framework.Pod, ActionType: framework.Add}: { + {PluginName: fakePod, QueueingHintFn: defaultQueueingHintFn}, // default queueing hint due to disabled feature gate. + }, + {Resource: framework.Node, ActionType: framework.All}: { + {PluginName: fakeBind, QueueingHintFn: defaultQueueingHintFn}, + {PluginName: queueSort, QueueingHintFn: defaultQueueingHintFn}, + }, + {Resource: framework.Node, ActionType: framework.Add}: { + {PluginName: fakeNode, QueueingHintFn: defaultQueueingHintFn}, // default queueing hint due to disabled feature gate. + }, + {Resource: framework.CSINode, ActionType: framework.All}: { + {PluginName: fakeBind, QueueingHintFn: defaultQueueingHintFn}, + {PluginName: queueSort, QueueingHintFn: defaultQueueingHintFn}, + }, + {Resource: framework.CSIDriver, ActionType: framework.All}: { + {PluginName: fakeBind, QueueingHintFn: defaultQueueingHintFn}, + {PluginName: queueSort, QueueingHintFn: defaultQueueingHintFn}, + }, + {Resource: framework.CSIStorageCapacity, ActionType: framework.All}: { + {PluginName: fakeBind, QueueingHintFn: defaultQueueingHintFn}, + {PluginName: queueSort, QueueingHintFn: defaultQueueingHintFn}, + }, + {Resource: framework.PersistentVolume, ActionType: framework.All}: { + {PluginName: fakeBind, QueueingHintFn: defaultQueueingHintFn}, + {PluginName: queueSort, QueueingHintFn: defaultQueueingHintFn}, + }, + {Resource: framework.StorageClass, ActionType: framework.All}: { + {PluginName: fakeBind, QueueingHintFn: defaultQueueingHintFn}, + {PluginName: queueSort, QueueingHintFn: defaultQueueingHintFn}, + }, + {Resource: framework.PersistentVolumeClaim, ActionType: framework.All}: { + {PluginName: fakeBind, QueueingHintFn: defaultQueueingHintFn}, + {PluginName: queueSort, QueueingHintFn: defaultQueueingHintFn}, + }, + {Resource: framework.PodSchedulingContext, ActionType: framework.All}: { + {PluginName: fakeBind, QueueingHintFn: defaultQueueingHintFn}, + {PluginName: queueSort, QueueingHintFn: defaultQueueingHintFn}, + }, + }, + }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { + defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SchedulerQueueingHints, !tt.featuregateDisabled)() logger, _ := ktesting.NewTestContext(t) registry := frameworkruntime.Registry{} cfgPls := &schedulerapi.Plugins{}