implement SchedulerQueueingHints feature gate
This commit is contained in:
		@@ -689,6 +689,14 @@ const (
 | 
				
			|||||||
	// equals to spec.parallelism before and after the update.
 | 
						// equals to spec.parallelism before and after the update.
 | 
				
			||||||
	ElasticIndexedJob featuregate.Feature = "ElasticIndexedJob"
 | 
						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
 | 
						// owner: @saschagrunert
 | 
				
			||||||
	// kep: https://kep.k8s.io/2413
 | 
						// kep: https://kep.k8s.io/2413
 | 
				
			||||||
	// alpha: v1.22
 | 
						// alpha: v1.22
 | 
				
			||||||
@@ -1040,6 +1048,8 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	ElasticIndexedJob: {Default: true, PreRelease: featuregate.Beta},
 | 
						ElasticIndexedJob: {Default: true, PreRelease: featuregate.Beta},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						SchedulerQueueingHints: {Default: true, PreRelease: featuregate.Beta},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	SeccompDefault: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29
 | 
						SeccompDefault: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.29
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	SecurityContextDeny: {Default: false, PreRelease: featuregate.Alpha},
 | 
						SecurityContextDeny: {Default: false, PreRelease: featuregate.Alpha},
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -25,6 +25,7 @@ import (
 | 
				
			|||||||
	v1 "k8s.io/api/core/v1"
 | 
						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/util/wait"
 | 
						"k8s.io/apimachinery/pkg/util/wait"
 | 
				
			||||||
 | 
						utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
				
			||||||
	"k8s.io/client-go/dynamic/dynamicinformer"
 | 
						"k8s.io/client-go/dynamic/dynamicinformer"
 | 
				
			||||||
	"k8s.io/client-go/informers"
 | 
						"k8s.io/client-go/informers"
 | 
				
			||||||
	coreinformers "k8s.io/client-go/informers/core/v1"
 | 
						coreinformers "k8s.io/client-go/informers/core/v1"
 | 
				
			||||||
@@ -33,6 +34,7 @@ import (
 | 
				
			|||||||
	"k8s.io/client-go/tools/cache"
 | 
						"k8s.io/client-go/tools/cache"
 | 
				
			||||||
	"k8s.io/klog/v2"
 | 
						"k8s.io/klog/v2"
 | 
				
			||||||
	configv1 "k8s.io/kube-scheduler/config/v1"
 | 
						configv1 "k8s.io/kube-scheduler/config/v1"
 | 
				
			||||||
 | 
						"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/apis/config/scheme"
 | 
						"k8s.io/kubernetes/pkg/scheduler/apis/config/scheme"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/scheduler/framework"
 | 
						"k8s.io/kubernetes/pkg/scheduler/framework"
 | 
				
			||||||
@@ -377,7 +379,7 @@ func buildQueueingHintMap(es []framework.EnqueueExtensions) internalqueue.Queuei
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		for _, event := range events {
 | 
							for _, event := range events {
 | 
				
			||||||
			fn := event.QueueingHintFn
 | 
								fn := event.QueueingHintFn
 | 
				
			||||||
			if fn == nil {
 | 
								if fn == nil || !utilfeature.DefaultFeatureGate.Enabled(features.SchedulerQueueingHints) {
 | 
				
			||||||
				fn = defaultQueueingHintFn
 | 
									fn = defaultQueueingHintFn
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -30,14 +30,17 @@ import (
 | 
				
			|||||||
	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"
 | 
				
			||||||
	"k8s.io/apimachinery/pkg/util/sets"
 | 
						"k8s.io/apimachinery/pkg/util/sets"
 | 
				
			||||||
 | 
						utilfeature "k8s.io/apiserver/pkg/util/feature"
 | 
				
			||||||
	"k8s.io/client-go/informers"
 | 
						"k8s.io/client-go/informers"
 | 
				
			||||||
	"k8s.io/client-go/kubernetes"
 | 
						"k8s.io/client-go/kubernetes"
 | 
				
			||||||
	"k8s.io/client-go/kubernetes/fake"
 | 
						"k8s.io/client-go/kubernetes/fake"
 | 
				
			||||||
	"k8s.io/client-go/kubernetes/scheme"
 | 
						"k8s.io/client-go/kubernetes/scheme"
 | 
				
			||||||
	"k8s.io/client-go/tools/cache"
 | 
						"k8s.io/client-go/tools/cache"
 | 
				
			||||||
	"k8s.io/client-go/tools/events"
 | 
						"k8s.io/client-go/tools/events"
 | 
				
			||||||
 | 
						featuregatetesting "k8s.io/component-base/featuregate/testing"
 | 
				
			||||||
	"k8s.io/klog/v2"
 | 
						"k8s.io/klog/v2"
 | 
				
			||||||
	"k8s.io/klog/v2/ktesting"
 | 
						"k8s.io/klog/v2/ktesting"
 | 
				
			||||||
 | 
						"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/apis/config/testing/defaults"
 | 
						"k8s.io/kubernetes/pkg/scheduler/apis/config/testing/defaults"
 | 
				
			||||||
	"k8s.io/kubernetes/pkg/scheduler/framework"
 | 
						"k8s.io/kubernetes/pkg/scheduler/framework"
 | 
				
			||||||
@@ -657,9 +660,10 @@ const (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func Test_buildQueueingHintMap(t *testing.T) {
 | 
					func Test_buildQueueingHintMap(t *testing.T) {
 | 
				
			||||||
	tests := []struct {
 | 
						tests := []struct {
 | 
				
			||||||
		name    string
 | 
							name                string
 | 
				
			||||||
		plugins []framework.Plugin
 | 
							plugins             []framework.Plugin
 | 
				
			||||||
		want    map[framework.ClusterEvent][]*internalqueue.QueueingHintFunction
 | 
							want                map[framework.ClusterEvent][]*internalqueue.QueueingHintFunction
 | 
				
			||||||
 | 
							featuregateDisabled bool
 | 
				
			||||||
	}{
 | 
						}{
 | 
				
			||||||
		{
 | 
							{
 | 
				
			||||||
			name:    "no-op plugin",
 | 
								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 {
 | 
						for _, tt := range tests {
 | 
				
			||||||
		t.Run(tt.name, func(t *testing.T) {
 | 
							t.Run(tt.name, func(t *testing.T) {
 | 
				
			||||||
 | 
								defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SchedulerQueueingHints, !tt.featuregateDisabled)()
 | 
				
			||||||
			logger, _ := ktesting.NewTestContext(t)
 | 
								logger, _ := ktesting.NewTestContext(t)
 | 
				
			||||||
			registry := frameworkruntime.Registry{}
 | 
								registry := frameworkruntime.Registry{}
 | 
				
			||||||
			cfgPls := &schedulerapi.Plugins{}
 | 
								cfgPls := &schedulerapi.Plugins{}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user