mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-03 17:30:00 +00:00
Merge pull request #126981 from kannon92/stable-empty-dir-promotion
KEP-1967: promote size backed memory volumes to stable
This commit is contained in:
commit
685b8b3ba1
@ -602,6 +602,8 @@ const (
|
|||||||
// owner: @derekwaynecarr
|
// owner: @derekwaynecarr
|
||||||
//
|
//
|
||||||
// Enables kubelet support to size memory backed volumes
|
// 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"
|
SizeMemoryBackedVolumes featuregate.Feature = "SizeMemoryBackedVolumes"
|
||||||
|
|
||||||
// owner: @mattcary
|
// owner: @mattcary
|
||||||
|
@ -683,6 +683,7 @@ var defaultVersionedKubernetesFeatureGates = map[featuregate.Feature]featuregate
|
|||||||
SizeMemoryBackedVolumes: {
|
SizeMemoryBackedVolumes: {
|
||||||
{Version: version.MustParse("1.20"), Default: false, PreRelease: featuregate.Alpha},
|
{Version: version.MustParse("1.20"), Default: false, PreRelease: featuregate.Alpha},
|
||||||
{Version: version.MustParse("1.22"), Default: true, PreRelease: featuregate.Beta},
|
{Version: version.MustParse("1.22"), Default: true, PreRelease: featuregate.Beta},
|
||||||
|
{Version: version.MustParse("1.32"), Default: true, LockToDefault: true, PreRelease: featuregate.GA},
|
||||||
},
|
},
|
||||||
|
|
||||||
StatefulSetAutoDeletePVC: {
|
StatefulSetAutoDeletePVC: {
|
||||||
|
@ -21,20 +21,18 @@ package emptydir
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/util/swap"
|
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/pkg/kubelet/util/swap"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
"k8s.io/apimachinery/pkg/api/resource"
|
"k8s.io/apimachinery/pkg/api/resource"
|
||||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||||
"k8s.io/apimachinery/pkg/types"
|
"k8s.io/apimachinery/pkg/types"
|
||||||
utilfeature "k8s.io/apiserver/pkg/util/feature"
|
|
||||||
utiltesting "k8s.io/client-go/util/testing"
|
utiltesting "k8s.io/client-go/util/testing"
|
||||||
featuregatetesting "k8s.io/component-base/featuregate/testing"
|
|
||||||
"k8s.io/kubernetes/pkg/features"
|
|
||||||
"k8s.io/kubernetes/pkg/volume"
|
"k8s.io/kubernetes/pkg/volume"
|
||||||
volumetest "k8s.io/kubernetes/pkg/volume/testing"
|
volumetest "k8s.io/kubernetes/pkg/volume/testing"
|
||||||
volumeutil "k8s.io/kubernetes/pkg/volume/util"
|
volumeutil "k8s.io/kubernetes/pkg/volume/util"
|
||||||
@ -963,27 +961,7 @@ func TestCalculateEmptyDirMemorySize(t *testing.T) {
|
|||||||
nodeAllocatableMemory resource.Quantity
|
nodeAllocatableMemory resource.Quantity
|
||||||
emptyDirSizeLimit resource.Quantity
|
emptyDirSizeLimit resource.Quantity
|
||||||
expectedResult 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": {
|
"EmptyDirLocalLimit": {
|
||||||
pod: &v1.Pod{
|
pod: &v1.Pod{
|
||||||
Spec: v1.PodSpec{
|
Spec: v1.PodSpec{
|
||||||
@ -1001,7 +979,6 @@ func TestCalculateEmptyDirMemorySize(t *testing.T) {
|
|||||||
nodeAllocatableMemory: resource.MustParse("16Gi"),
|
nodeAllocatableMemory: resource.MustParse("16Gi"),
|
||||||
emptyDirSizeLimit: resource.MustParse("1Gi"),
|
emptyDirSizeLimit: resource.MustParse("1Gi"),
|
||||||
expectedResult: resource.MustParse("1Gi"),
|
expectedResult: resource.MustParse("1Gi"),
|
||||||
featureGateEnabled: true,
|
|
||||||
},
|
},
|
||||||
"PodLocalLimit": {
|
"PodLocalLimit": {
|
||||||
pod: &v1.Pod{
|
pod: &v1.Pod{
|
||||||
@ -1020,7 +997,6 @@ func TestCalculateEmptyDirMemorySize(t *testing.T) {
|
|||||||
nodeAllocatableMemory: resource.MustParse("16Gi"),
|
nodeAllocatableMemory: resource.MustParse("16Gi"),
|
||||||
emptyDirSizeLimit: resource.MustParse("0"),
|
emptyDirSizeLimit: resource.MustParse("0"),
|
||||||
expectedResult: resource.MustParse("10Gi"),
|
expectedResult: resource.MustParse("10Gi"),
|
||||||
featureGateEnabled: true,
|
|
||||||
},
|
},
|
||||||
"NodeAllocatableLimit": {
|
"NodeAllocatableLimit": {
|
||||||
pod: &v1.Pod{
|
pod: &v1.Pod{
|
||||||
@ -1039,13 +1015,11 @@ func TestCalculateEmptyDirMemorySize(t *testing.T) {
|
|||||||
nodeAllocatableMemory: resource.MustParse("16Gi"),
|
nodeAllocatableMemory: resource.MustParse("16Gi"),
|
||||||
emptyDirSizeLimit: resource.MustParse("0"),
|
emptyDirSizeLimit: resource.MustParse("0"),
|
||||||
expectedResult: resource.MustParse("16Gi"),
|
expectedResult: resource.MustParse("16Gi"),
|
||||||
featureGateEnabled: true,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for testCaseName, testCase := range testCases {
|
for testCaseName, testCase := range testCases {
|
||||||
t.Run(testCaseName, func(t *testing.T) {
|
t.Run(testCaseName, func(t *testing.T) {
|
||||||
featuregatetesting.SetFeatureGateDuringTest(t, utilfeature.DefaultFeatureGate, features.SizeMemoryBackedVolumes, testCase.featureGateEnabled)
|
|
||||||
spec := &volume.Spec{
|
spec := &volume.Spec{
|
||||||
Volume: &v1.Volume{
|
Volume: &v1.Volume{
|
||||||
VolumeSource: v1.VolumeSource{
|
VolumeSource: v1.VolumeSource{
|
||||||
|
@ -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
|
// 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() {
|
var _ = SIGDescribe("LocalStorageCapacityIsolationEviction", framework.WithSlow(), framework.WithSerial(), framework.WithDisruptive(), feature.LocalStorageCapacityIsolation, nodefeature.Eviction, func() {
|
||||||
f := framework.NewDefaultFramework("localstorage-eviction-test")
|
f := framework.NewDefaultFramework("localstorage-eviction-test")
|
||||||
|
@ -1148,6 +1148,10 @@
|
|||||||
lockToDefault: false
|
lockToDefault: false
|
||||||
preRelease: Beta
|
preRelease: Beta
|
||||||
version: "1.22"
|
version: "1.22"
|
||||||
|
- default: true
|
||||||
|
lockToDefault: true
|
||||||
|
preRelease: GA
|
||||||
|
version: "1.32"
|
||||||
- name: StatefulSetAutoDeletePVC
|
- name: StatefulSetAutoDeletePVC
|
||||||
versionedSpecs:
|
versionedSpecs:
|
||||||
- default: false
|
- default: false
|
||||||
|
Loading…
Reference in New Issue
Block a user