diff --git a/pkg/features/kube_features.go b/pkg/features/kube_features.go index c7dd7621c9a..a4fdb110e77 100644 --- a/pkg/features/kube_features.go +++ b/pkg/features/kube_features.go @@ -179,6 +179,7 @@ const ( // owner: @chendave // alpha: v1.21 // beta: v1.22 + // GA: v1.24 // // PreferNominatedNode tells scheduler whether the nominated node will be checked first before looping // all the rest of nodes in the cluster. @@ -935,8 +936,8 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS ServiceLBNodePortControl: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.26 MixedProtocolLBService: {Default: false, PreRelease: featuregate.Alpha}, VolumeCapacityPriority: {Default: false, PreRelease: featuregate.Alpha}, - PreferNominatedNode: {Default: true, PreRelease: featuregate.Beta}, - ProbeTerminationGracePeriod: {Default: false, PreRelease: featuregate.Beta}, // Default to false in beta 1.22, set to true in 1.24 + PreferNominatedNode: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.25 + ProbeTerminationGracePeriod: {Default: false, PreRelease: featuregate.Beta}, // Default to false in beta 1.22, set to true in 1.24 NodeSwap: {Default: false, PreRelease: featuregate.Alpha}, PodDeletionCost: {Default: true, PreRelease: featuregate.Beta}, StatefulSetAutoDeletePVC: {Default: false, PreRelease: featuregate.Alpha}, diff --git a/pkg/scheduler/generic_scheduler.go b/pkg/scheduler/generic_scheduler.go index 5d7a6c69442..31180c96474 100644 --- a/pkg/scheduler/generic_scheduler.go +++ b/pkg/scheduler/generic_scheduler.go @@ -28,9 +28,7 @@ import ( v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/util/sets" - "k8s.io/apiserver/pkg/util/feature" extenderv1 "k8s.io/kube-scheduler/extender/v1" - "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/scheduler/framework" "k8s.io/kubernetes/pkg/scheduler/framework/parallelize" "k8s.io/kubernetes/pkg/scheduler/framework/runtime" @@ -240,7 +238,7 @@ func (g *genericScheduler) findNodesThatFitPod(ctx context.Context, extenders [] // "NominatedNodeName" can potentially be set in a previous scheduling cycle as a result of preemption. // This node is likely the only candidate that will fit the pod, and hence we try it first before iterating over all nodes. - if len(pod.Status.NominatedNodeName) > 0 && feature.DefaultFeatureGate.Enabled(features.PreferNominatedNode) { + if len(pod.Status.NominatedNodeName) > 0 { feasibleNodes, err := g.evaluateNominatedNode(ctx, extenders, pod, fwk, state, diagnosis) if err != nil { klog.ErrorS(err, "Evaluation failed on nominated node", "pod", klog.KObj(pod), "node", pod.Status.NominatedNodeName) diff --git a/pkg/scheduler/generic_scheduler_test.go b/pkg/scheduler/generic_scheduler_test.go index 7da05563919..c3dbc80b182 100644 --- a/pkg/scheduler/generic_scheduler_test.go +++ b/pkg/scheduler/generic_scheduler_test.go @@ -34,12 +34,9 @@ import ( "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/sets" "k8s.io/apimachinery/pkg/util/wait" - utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/informers" clientsetfake "k8s.io/client-go/kubernetes/fake" - featuregatetesting "k8s.io/component-base/featuregate/testing" pvutil "k8s.io/kubernetes/pkg/controller/volume/persistentvolume/util" - "k8s.io/kubernetes/pkg/features" schedulerapi "k8s.io/kubernetes/pkg/scheduler/apis/config" "k8s.io/kubernetes/pkg/scheduler/framework" "k8s.io/kubernetes/pkg/scheduler/framework/plugins/defaultbinder" @@ -1454,33 +1451,23 @@ func TestFairEvaluationForNodes(t *testing.T) { func TestPreferNominatedNodeFilterCallCounts(t *testing.T) { tests := []struct { name string - feature bool pod *v1.Pod nodeReturnCodeMap map[string]framework.Code expectedCount int32 expectedPatchRequests int }{ { - name: "Enable the feature, pod has the nominated node set, filter is called only once", - feature: true, + name: "pod has the nominated node set, filter is called only once", pod: st.MakePod().Name("p_with_nominated_node").UID("p").Priority(highPriority).NominatedNodeName("node1").Obj(), expectedCount: 1, }, - { - name: "Disable the feature, pod has the nominated node, filter is called for each node", - feature: false, - pod: st.MakePod().Name("p_with_nominated_node").UID("p").Priority(highPriority).NominatedNodeName("node1").Obj(), - expectedCount: 3, - }, { name: "pod without the nominated pod, filter is called for each node", - feature: true, pod: st.MakePod().Name("p_without_nominated_node").UID("p").Priority(highPriority).Obj(), expectedCount: 3, }, { name: "nominated pod cannot pass the filter, filter is called for each node", - feature: true, pod: st.MakePod().Name("p_with_nominated_node").UID("p").Priority(highPriority).NominatedNodeName("node1").Obj(), nodeReturnCodeMap: map[string]framework.Code{"node1": framework.Unschedulable}, expectedCount: 4, @@ -1489,7 +1476,6 @@ func TestPreferNominatedNodeFilterCallCounts(t *testing.T) { for _, test := range tests { t.Run(test.name, func(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PreferNominatedNode, test.feature)() // create three nodes in the cluster. nodes := makeNodeList([]string{"node1", "node2", "node3"}) client := clientsetfake.NewSimpleClientset(test.pod) diff --git a/test/integration/scheduler/preemption_test.go b/test/integration/scheduler/preemption_test.go index 44f040909d5..c42308ace77 100644 --- a/test/integration/scheduler/preemption_test.go +++ b/test/integration/scheduler/preemption_test.go @@ -1436,14 +1436,9 @@ func initTestPreferNominatedNode(t *testing.T, nsPrefix string, opts ...schedule return testCtx } -// TestPreferNominatedNode test when the feature of "PreferNominatedNode" is enabled, the overall scheduling logic is not changed. -// If the nominated node pass all the filters, then preemptor pod will run on the nominated node, otherwise, it will be scheduled -// to another node in the cluster that ables to pass all the filters. -// NOTE: This integration test is not intending to check the logic of preemption, but rather a sanity check when the feature is -// enabled. +// TestPreferNominatedNode test that if the nominated node pass all the filters, then preemptor pod will run on the nominated node, +// otherwise, it will be scheduled to another node in the cluster that ables to pass all the filters. func TestPreferNominatedNode(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PreferNominatedNode, true)() - defaultNodeRes := map[v1.ResourceName]string{ v1.ResourcePods: "32", v1.ResourceCPU: "500m",