diff --git a/pkg/controller/podgc/gc_controller.go b/pkg/controller/podgc/gc_controller.go index 2b16017e5a67..a8c9bc29d1c5 100644 --- a/pkg/controller/podgc/gc_controller.go +++ b/pkg/controller/podgc/gc_controller.go @@ -127,9 +127,7 @@ func (gcc *PodGCController) gc(ctx context.Context) { if gcc.terminatedPodThreshold > 0 { gcc.gcTerminated(ctx, pods) } - if utilfeature.DefaultFeatureGate.Enabled(features.NodeOutOfServiceVolumeDetach) { - gcc.gcTerminating(ctx, pods) - } + gcc.gcTerminating(ctx, pods) gcc.gcOrphaned(ctx, pods, nodes) gcc.gcUnscheduledTerminating(ctx, pods) } diff --git a/pkg/controller/podgc/gc_controller_test.go b/pkg/controller/podgc/gc_controller_test.go index d8802d537324..a73507160a90 100644 --- a/pkg/controller/podgc/gc_controller_test.go +++ b/pkg/controller/podgc/gc_controller_test.go @@ -489,7 +489,6 @@ func TestGCUnscheduledTerminating(t *testing.T) { } func TestGCTerminating(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.NodeOutOfServiceVolumeDetach, true)() type node struct { name string readyCondition v1.ConditionStatus diff --git a/pkg/controller/volume/attachdetach/reconciler/reconciler.go b/pkg/controller/volume/attachdetach/reconciler/reconciler.go index cc3de29db85e..45783e98ccc3 100644 --- a/pkg/controller/volume/attachdetach/reconciler/reconciler.go +++ b/pkg/controller/volume/attachdetach/reconciler/reconciler.go @@ -28,14 +28,12 @@ import ( v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/wait" - utilfeature "k8s.io/apiserver/pkg/util/feature" corelisters "k8s.io/client-go/listers/core/v1" "k8s.io/client-go/tools/record" "k8s.io/klog/v2" "k8s.io/kubernetes/pkg/controller/volume/attachdetach/cache" "k8s.io/kubernetes/pkg/controller/volume/attachdetach/metrics" "k8s.io/kubernetes/pkg/controller/volume/attachdetach/statusupdater" - "k8s.io/kubernetes/pkg/features" kevents "k8s.io/kubernetes/pkg/kubelet/events" "k8s.io/kubernetes/pkg/util/goroutinemap/exponentialbackoff" nodeutil "k8s.io/kubernetes/pkg/util/node" @@ -143,17 +141,13 @@ func (rc *reconciler) syncStates() { rc.attacherDetacher.VerifyVolumesAreAttached(volumesPerNode, rc.actualStateOfWorld) } -// hasOutOfServiceTaint returns true if the node has out-of-service taint present -// and `NodeOutOfServiceVolumeDetach` feature gate is enabled. +// hasOutOfServiceTaint returns true if the node has out-of-service taint present. func (rc *reconciler) hasOutOfServiceTaint(nodeName types.NodeName) (bool, error) { - if utilfeature.DefaultFeatureGate.Enabled(features.NodeOutOfServiceVolumeDetach) { - node, err := rc.nodeLister.Get(string(nodeName)) - if err != nil { - return false, err - } - return taints.TaintKeyExists(node.Spec.Taints, v1.TaintNodeOutOfService), nil + node, err := rc.nodeLister.Get(string(nodeName)) + if err != nil { + return false, err } - return false, nil + return taints.TaintKeyExists(node.Spec.Taints, v1.TaintNodeOutOfService), nil } // nodeIsHealthy returns true if the node looks healthy. diff --git a/pkg/controller/volume/attachdetach/reconciler/reconciler_test.go b/pkg/controller/volume/attachdetach/reconciler/reconciler_test.go index 9ef77a84d813..02995c0d4bdb 100644 --- a/pkg/controller/volume/attachdetach/reconciler/reconciler_test.go +++ b/pkg/controller/volume/attachdetach/reconciler/reconciler_test.go @@ -27,10 +27,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" k8stypes "k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/util/wait" - utilfeature "k8s.io/apiserver/pkg/util/feature" "k8s.io/client-go/informers" "k8s.io/client-go/tools/record" - featuregatetesting "k8s.io/component-base/featuregate/testing" "k8s.io/component-base/metrics/legacyregistry" metricstestutil "k8s.io/component-base/metrics/testutil" "k8s.io/klog/v2" @@ -40,7 +38,6 @@ import ( "k8s.io/kubernetes/pkg/controller/volume/attachdetach/metrics" "k8s.io/kubernetes/pkg/controller/volume/attachdetach/statusupdater" controllervolumetesting "k8s.io/kubernetes/pkg/controller/volume/attachdetach/testing" - "k8s.io/kubernetes/pkg/features" volumetesting "k8s.io/kubernetes/pkg/volume/testing" "k8s.io/kubernetes/pkg/volume/util/operationexecutor" "k8s.io/kubernetes/pkg/volume/util/types" @@ -863,7 +860,6 @@ func Test_Run_OneVolumeAttachAndDetachTimeoutNodesWithReadWriteOnce(t *testing.T // Deletes the pod from desiredStateOfWorld cache without first marking the node/volume as unmounted. // Verifies there is one detach call and no (new) attach calls. func Test_Run_OneVolumeDetachOnOutOfServiceTaintedNode(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.NodeOutOfServiceVolumeDetach, true)() registerMetrics.Do(func() { legacyregistry.MustRegister(metrics.ForceDetachMetricCounter) }) @@ -951,7 +947,6 @@ func Test_Run_OneVolumeDetachOnOutOfServiceTaintedNode(t *testing.T) { // Deletes the pod from desiredStateOfWorld cache without first marking the node/volume as unmounted. // Verifies there is no detach call and no (new) attach calls. func Test_Run_OneVolumeDetachOnNoOutOfServiceTaintedNode(t *testing.T) { - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.NodeOutOfServiceVolumeDetach, true)() // Arrange volumePluginMgr, fakePlugin := volumetesting.GetTestVolumePluginMgr(t) dsw := cache.NewDesiredStateOfWorld(volumePluginMgr) diff --git a/pkg/features/kube_features.go b/pkg/features/kube_features.go index 7bb9cba5b20a..7260dd2ee194 100644 --- a/pkg/features/kube_features.go +++ b/pkg/features/kube_features.go @@ -561,6 +561,7 @@ const ( // kep: https://kep.k8s.io/2268 // alpha: v1.24 // beta: v1.26 + // GA: v1.28 // // Allow pods to failover to a different node in case of non graceful node shutdown NodeOutOfServiceVolumeDetach featuregate.Feature = "NodeOutOfServiceVolumeDetach" @@ -1006,7 +1007,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS NodeLogQuery: {Default: false, PreRelease: featuregate.Alpha}, - NodeOutOfServiceVolumeDetach: {Default: true, PreRelease: featuregate.Beta}, + NodeOutOfServiceVolumeDetach: {Default: true, PreRelease: featuregate.GA, LockToDefault: true}, // remove in 1.31 NodeSwap: {Default: false, PreRelease: featuregate.Alpha}, diff --git a/test/integration/podgc/podgc_test.go b/test/integration/podgc/podgc_test.go index 4957e9fc443e..8356d7533473 100644 --- a/test/integration/podgc/podgc_test.go +++ b/test/integration/podgc/podgc_test.go @@ -177,7 +177,6 @@ func TestTerminatingOnOutOfServiceNode(t *testing.T) { for name, test := range tests { t.Run(name, func(t *testing.T) { defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PodDisruptionConditions, test.enablePodDisruptionConditions)() - defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.NodeOutOfServiceVolumeDetach, true)() testCtx := setup(t, "podgc-out-of-service") cs := testCtx.ClientSet