diff --git a/pkg/features/kube_features.go b/pkg/features/kube_features.go index b28974801a5..af2a4ec9a4a 100644 --- a/pkg/features/kube_features.go +++ b/pkg/features/kube_features.go @@ -602,6 +602,8 @@ const ( // owner: @derekwaynecarr // // Enables kubelet support to size memory backed volumes + // This is a kubelet only feature gate. + // Code can be removed in 1.35 without any consideration for emulated versions. SizeMemoryBackedVolumes featuregate.Feature = "SizeMemoryBackedVolumes" // owner: @mattcary diff --git a/pkg/features/versioned_kube_features.go b/pkg/features/versioned_kube_features.go index e34c75c2ab9..5d1572c902f 100644 --- a/pkg/features/versioned_kube_features.go +++ b/pkg/features/versioned_kube_features.go @@ -683,6 +683,7 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate SizeMemoryBackedVolumes: { {Version: version.MustParse("1.20"), Default: false, PreRelease: featuregate.Alpha}, {Version: version.MustParse("1.22"), Default: true, PreRelease: featuregate.Beta}, + {Version: version.MustParse("1.32"), Default: true, LockToDefault: true, PreRelease: featuregate.GA}, }, StatefulSetAutoDeletePVC: { diff --git a/pkg/volume/emptydir/empty_dir_test.go b/pkg/volume/emptydir/empty_dir_test.go index 89766f64cbc..5dcf9c0f7b5 100644 --- a/pkg/volume/emptydir/empty_dir_test.go +++ b/pkg/volume/emptydir/empty_dir_test.go @@ -21,20 +21,18 @@ package emptydir import ( "fmt" - "k8s.io/kubernetes/pkg/kubelet/util/swap" "os" "path/filepath" "strings" "testing" + "k8s.io/kubernetes/pkg/kubelet/util/swap" + v1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/types" - utilfeature "k8s.io/apiserver/pkg/util/feature" utiltesting "k8s.io/client-go/util/testing" - featuregatetesting "k8s.io/component-base/featuregate/testing" - "k8s.io/kubernetes/pkg/features" "k8s.io/kubernetes/pkg/volume" volumetest "k8s.io/kubernetes/pkg/volume/testing" volumeutil "k8s.io/kubernetes/pkg/volume/util" @@ -963,27 +961,7 @@ func TestCalculateEmptyDirMemorySize(t *testing.T) { nodeAllocatableMemory resource.Quantity emptyDirSizeLimit resource.Quantity expectedResult resource.Quantity - featureGateEnabled bool }{ - "SizeMemoryBackedVolumesDisabled": { - pod: &v1.Pod{ - Spec: v1.PodSpec{ - Containers: []v1.Container{ - { - Resources: v1.ResourceRequirements{ - Requests: v1.ResourceList{ - v1.ResourceName("memory"): resource.MustParse("10Gi"), - }, - }, - }, - }, - }, - }, - nodeAllocatableMemory: resource.MustParse("16Gi"), - emptyDirSizeLimit: resource.MustParse("1Gi"), - expectedResult: resource.MustParse("0"), - featureGateEnabled: false, - }, "EmptyDirLocalLimit": { pod: &v1.Pod{ Spec: v1.PodSpec{ @@ -1001,7 +979,6 @@ func TestCalculateEmptyDirMemorySize(t *testing.T) { nodeAllocatableMemory: resource.MustParse("16Gi"), emptyDirSizeLimit: resource.MustParse("1Gi"), expectedResult: resource.MustParse("1Gi"), - featureGateEnabled: true, }, "PodLocalLimit": { pod: &v1.Pod{ @@ -1020,7 +997,6 @@ func TestCalculateEmptyDirMemorySize(t *testing.T) { nodeAllocatableMemory: resource.MustParse("16Gi"), emptyDirSizeLimit: resource.MustParse("0"), expectedResult: resource.MustParse("10Gi"), - featureGateEnabled: true, }, "NodeAllocatableLimit": { pod: &v1.Pod{ @@ -1039,13 +1015,11 @@ func TestCalculateEmptyDirMemorySize(t *testing.T) { nodeAllocatableMemory: resource.MustParse("16Gi"), emptyDirSizeLimit: resource.MustParse("0"), expectedResult: resource.MustParse("16Gi"), - featureGateEnabled: true, }, } for testCaseName, testCase := range testCases { t.Run(testCaseName, func(t *testing.T) { - featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SizeMemoryBackedVolumes, testCase.featureGateEnabled) spec := &volume.Spec{ Volume: &v1.Volume{ VolumeSource: v1.VolumeSource{ diff --git a/test/e2e_node/eviction_test.go b/test/e2e_node/eviction_test.go index 484130ce6c8..cc31d6e54fc 100644 --- a/test/e2e_node/eviction_test.go +++ b/test/e2e_node/eviction_test.go @@ -288,51 +288,6 @@ var _ = SIGDescribe("LocalStorageSoftEvictionNotOverwriteTerminationGracePeriodS }) }) -// This test validates that in-memory EmptyDir's are evicted when the Kubelet does -// not have Sized Memory Volumes enabled. When Sized volumes are enabled, it's -// not possible to exhaust the quota. -var _ = SIGDescribe("LocalStorageCapacityIsolationMemoryBackedVolumeEviction", framework.WithSlow(), framework.WithSerial(), framework.WithDisruptive(), feature.LocalStorageCapacityIsolation, nodefeature.Eviction, func() { - f := framework.NewDefaultFramework("localstorage-eviction-test") - f.NamespacePodSecurityLevel = admissionapi.LevelPrivileged - evictionTestTimeout := 7 * time.Minute - ginkgo.Context(fmt.Sprintf(testContextFmt, "evictions due to pod local storage violations"), func() { - tempSetCurrentKubeletConfig(f, func(ctx context.Context, initialConfig *kubeletconfig.KubeletConfiguration) { - // setting a threshold to 0% disables; non-empty map overrides default value (necessary due to omitempty) - initialConfig.EvictionHard = map[string]string{string(evictionapi.SignalMemoryAvailable): "0%"} - if initialConfig.FeatureGates == nil { - initialConfig.FeatureGates = make(map[string]bool) - } - initialConfig.FeatureGates["SizeMemoryBackedVolumes"] = false - }) - - sizeLimit := resource.MustParse("100Mi") - useOverLimit := 200 /* Mb */ - useUnderLimit := 80 /* Mb */ - containerLimit := v1.ResourceList{v1.ResourceEphemeralStorage: sizeLimit} - - runEvictionTest(f, evictionTestTimeout, noPressure, noStarvedResource, logDiskMetrics, []podEvictSpec{ - { - evictionPriority: 1, // Should be evicted due to disk limit - pod: diskConsumingPod("emptydir-memory-over-volume-sizelimit", useOverLimit, &v1.VolumeSource{ - EmptyDir: &v1.EmptyDirVolumeSource{Medium: "Memory", SizeLimit: &sizeLimit}, - }, v1.ResourceRequirements{}), - }, - { - evictionPriority: 0, // Should not be evicted, as container limits do not account for memory backed volumes - pod: diskConsumingPod("emptydir-memory-over-container-sizelimit", useOverLimit, &v1.VolumeSource{ - EmptyDir: &v1.EmptyDirVolumeSource{Medium: "Memory"}, - }, v1.ResourceRequirements{Limits: containerLimit}), - }, - { - evictionPriority: 0, - pod: diskConsumingPod("emptydir-memory-innocent", useUnderLimit, &v1.VolumeSource{ - EmptyDir: &v1.EmptyDirVolumeSource{Medium: "Memory", SizeLimit: &sizeLimit}, - }, v1.ResourceRequirements{}), - }, - }) - }) -}) - // LocalStorageCapacityIsolationEviction tests that container and volume local storage limits are enforced through evictions var _ = SIGDescribe("LocalStorageCapacityIsolationEviction", framework.WithSlow(), framework.WithSerial(), framework.WithDisruptive(), feature.LocalStorageCapacityIsolation, nodefeature.Eviction, func() { f := framework.NewDefaultFramework("localstorage-eviction-test") diff --git a/test/featuregates_linter/test_data/versioned_feature_list.yaml b/test/featuregates_linter/test_data/versioned_feature_list.yaml index d4c0b0fef87..04f70a2450f 100644 --- a/test/featuregates_linter/test_data/versioned_feature_list.yaml +++ b/test/featuregates_linter/test_data/versioned_feature_list.yaml @@ -1148,6 +1148,10 @@ lockToDefault: false preRelease: Beta version: "1.22" + - default: true + lockToDefault: true + preRelease: GA + version: "1.32" - name: StatefulSetAutoDeletePVC versionedSpecs: - default: false