Merge pull request #118228 from carlory/move-non-graceful-node-shutdown-to-GA

move non-graceful node shutdown to GA
This commit is contained in:
Kubernetes Prow Robot 2023-07-13 15:47:37 -07:00 committed by GitHub
commit be2cfc9697
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 8 additions and 22 deletions

View File

@ -127,9 +127,7 @@ func (gcc *PodGCController) gc(ctx context.Context) {
if gcc.terminatedPodThreshold > 0 { if gcc.terminatedPodThreshold > 0 {
gcc.gcTerminated(ctx, pods) gcc.gcTerminated(ctx, pods)
} }
if utilfeature.DefaultFeatureGate.Enabled(features.NodeOutOfServiceVolumeDetach) { gcc.gcTerminating(ctx, pods)
gcc.gcTerminating(ctx, pods)
}
gcc.gcOrphaned(ctx, pods, nodes) gcc.gcOrphaned(ctx, pods, nodes)
gcc.gcUnscheduledTerminating(ctx, pods) gcc.gcUnscheduledTerminating(ctx, pods)
} }

View File

@ -503,7 +503,6 @@ func TestGCUnscheduledTerminating(t *testing.T) {
} }
func TestGCTerminating(t *testing.T) { func TestGCTerminating(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.NodeOutOfServiceVolumeDetach, true)()
type node struct { type node struct {
name string name string
readyCondition v1.ConditionStatus readyCondition v1.ConditionStatus

View File

@ -28,14 +28,12 @@ import (
v1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/types" "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
utilfeature "k8s.io/apiserver/pkg/util/feature"
corelisters "k8s.io/client-go/listers/core/v1" corelisters "k8s.io/client-go/listers/core/v1"
"k8s.io/client-go/tools/record" "k8s.io/client-go/tools/record"
"k8s.io/klog/v2" "k8s.io/klog/v2"
"k8s.io/kubernetes/pkg/controller/volume/attachdetach/cache" "k8s.io/kubernetes/pkg/controller/volume/attachdetach/cache"
"k8s.io/kubernetes/pkg/controller/volume/attachdetach/metrics" "k8s.io/kubernetes/pkg/controller/volume/attachdetach/metrics"
"k8s.io/kubernetes/pkg/controller/volume/attachdetach/statusupdater" "k8s.io/kubernetes/pkg/controller/volume/attachdetach/statusupdater"
"k8s.io/kubernetes/pkg/features"
kevents "k8s.io/kubernetes/pkg/kubelet/events" kevents "k8s.io/kubernetes/pkg/kubelet/events"
"k8s.io/kubernetes/pkg/util/goroutinemap/exponentialbackoff" "k8s.io/kubernetes/pkg/util/goroutinemap/exponentialbackoff"
nodeutil "k8s.io/kubernetes/pkg/util/node" nodeutil "k8s.io/kubernetes/pkg/util/node"
@ -143,17 +141,13 @@ func (rc *reconciler) syncStates() {
rc.attacherDetacher.VerifyVolumesAreAttached(volumesPerNode, rc.actualStateOfWorld) rc.attacherDetacher.VerifyVolumesAreAttached(volumesPerNode, rc.actualStateOfWorld)
} }
// hasOutOfServiceTaint returns true if the node has out-of-service taint present // hasOutOfServiceTaint returns true if the node has out-of-service taint present.
// and `NodeOutOfServiceVolumeDetach` feature gate is enabled.
func (rc *reconciler) hasOutOfServiceTaint(nodeName types.NodeName) (bool, error) { func (rc *reconciler) hasOutOfServiceTaint(nodeName types.NodeName) (bool, error) {
if utilfeature.DefaultFeatureGate.Enabled(features.NodeOutOfServiceVolumeDetach) { node, err := rc.nodeLister.Get(string(nodeName))
node, err := rc.nodeLister.Get(string(nodeName)) if err != nil {
if err != nil { return false, err
return false, err
}
return taints.TaintKeyExists(node.Spec.Taints, v1.TaintNodeOutOfService), nil
} }
return false, nil return taints.TaintKeyExists(node.Spec.Taints, v1.TaintNodeOutOfService), nil
} }
// nodeIsHealthy returns true if the node looks healthy. // nodeIsHealthy returns true if the node looks healthy.

View File

@ -27,10 +27,8 @@ import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
k8stypes "k8s.io/apimachinery/pkg/types" k8stypes "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/wait" "k8s.io/apimachinery/pkg/util/wait"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/client-go/informers" "k8s.io/client-go/informers"
"k8s.io/client-go/tools/record" "k8s.io/client-go/tools/record"
featuregatetesting "k8s.io/component-base/featuregate/testing"
"k8s.io/component-base/metrics/legacyregistry" "k8s.io/component-base/metrics/legacyregistry"
metricstestutil "k8s.io/component-base/metrics/testutil" metricstestutil "k8s.io/component-base/metrics/testutil"
"k8s.io/klog/v2" "k8s.io/klog/v2"
@ -40,7 +38,6 @@ import (
"k8s.io/kubernetes/pkg/controller/volume/attachdetach/metrics" "k8s.io/kubernetes/pkg/controller/volume/attachdetach/metrics"
"k8s.io/kubernetes/pkg/controller/volume/attachdetach/statusupdater" "k8s.io/kubernetes/pkg/controller/volume/attachdetach/statusupdater"
controllervolumetesting "k8s.io/kubernetes/pkg/controller/volume/attachdetach/testing" controllervolumetesting "k8s.io/kubernetes/pkg/controller/volume/attachdetach/testing"
"k8s.io/kubernetes/pkg/features"
volumetesting "k8s.io/kubernetes/pkg/volume/testing" volumetesting "k8s.io/kubernetes/pkg/volume/testing"
"k8s.io/kubernetes/pkg/volume/util/operationexecutor" "k8s.io/kubernetes/pkg/volume/util/operationexecutor"
"k8s.io/kubernetes/pkg/volume/util/types" "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. // 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. // Verifies there is one detach call and no (new) attach calls.
func Test_Run_OneVolumeDetachOnOutOfServiceTaintedNode(t *testing.T) { func Test_Run_OneVolumeDetachOnOutOfServiceTaintedNode(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.NodeOutOfServiceVolumeDetach, true)()
registerMetrics.Do(func() { registerMetrics.Do(func() {
legacyregistry.MustRegister(metrics.ForceDetachMetricCounter) 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. // 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. // Verifies there is no detach call and no (new) attach calls.
func Test_Run_OneVolumeDetachOnNoOutOfServiceTaintedNode(t *testing.T) { func Test_Run_OneVolumeDetachOnNoOutOfServiceTaintedNode(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.NodeOutOfServiceVolumeDetach, true)()
// Arrange // Arrange
volumePluginMgr, fakePlugin := volumetesting.GetTestVolumePluginMgr(t) volumePluginMgr, fakePlugin := volumetesting.GetTestVolumePluginMgr(t)
dsw := cache.NewDesiredStateOfWorld(volumePluginMgr) dsw := cache.NewDesiredStateOfWorld(volumePluginMgr)

View File

@ -561,6 +561,7 @@ const (
// kep: https://kep.k8s.io/2268 // kep: https://kep.k8s.io/2268
// alpha: v1.24 // alpha: v1.24
// beta: v1.26 // beta: v1.26
// GA: v1.28
// //
// Allow pods to failover to a different node in case of non graceful node shutdown // Allow pods to failover to a different node in case of non graceful node shutdown
NodeOutOfServiceVolumeDetach featuregate.Feature = "NodeOutOfServiceVolumeDetach" NodeOutOfServiceVolumeDetach featuregate.Feature = "NodeOutOfServiceVolumeDetach"
@ -1007,7 +1008,7 @@ var defaultKubernetesFeatureGates = map[featuregate.Feature]featuregate.FeatureS
NodeLogQuery: {Default: false, PreRelease: featuregate.Alpha}, 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}, NodeSwap: {Default: false, PreRelease: featuregate.Alpha},

View File

@ -177,7 +177,6 @@ func TestTerminatingOnOutOfServiceNode(t *testing.T) {
for name, test := range tests { for name, test := range tests {
t.Run(name, func(t *testing.T) { t.Run(name, func(t *testing.T) {
defer featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.PodDisruptionConditions, test.enablePodDisruptionConditions)() 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") testCtx := setup(t, "podgc-out-of-service")
cs := testCtx.ClientSet cs := testCtx.ClientSet