diff --git a/pkg/kubelet/apis/config/types.go b/pkg/kubelet/apis/config/types.go index fd8b63bfb81..761de7c04ed 100644 --- a/pkg/kubelet/apis/config/types.go +++ b/pkg/kubelet/apis/config/types.go @@ -326,7 +326,7 @@ type KubeletConfiguration struct { FeatureGates map[string]bool // Tells the Kubelet to fail to start if swap is enabled on the node. FailSwapOn bool - // Configure swap memory available to container workloads. + // memorySwap configures swap memory available to container workloads. // +featureGate=NodeSwapEnabled // +optional MemorySwap MemorySwapConfiguration @@ -574,8 +574,10 @@ type MemoryReservation struct { } type MemorySwapConfiguration struct { - // Configure swap memory available to container workloads. May be one of - // "", "NoSwap": workloads cannot use swap + // swapBehavior configures swap memory available to container workloads. May be one of + // "", "LimitedSwap": workload combined memory and swap usage cannot exceed pod memory limit // "UnlimitedSwap": workloads can use unlimited swap, up to the allocatable limit. + // +featureGate=NodeSwapEnabled + // +optional SwapBehavior string } diff --git a/pkg/kubelet/apis/config/validation/validation.go b/pkg/kubelet/apis/config/validation/validation.go index 40c2a16de7d..9d2fc0915b2 100644 --- a/pkg/kubelet/apis/config/validation/validation.go +++ b/pkg/kubelet/apis/config/validation/validation.go @@ -156,8 +156,8 @@ func ValidateKubeletConfiguration(kc *kubeletconfig.KubeletConfiguration) error allErrors = append(allErrors, fmt.Errorf("invalid configuration: Specifying ShutdownGracePeriod or ShutdownGracePeriodCriticalPods requires feature gate GracefulNodeShutdown")) } if localFeatureGate.Enabled(features.NodeSwapEnabled) { - if kc.MemorySwap.SwapBehavior != "" && kc.MemorySwap.SwapBehavior != "NoSwap" && kc.MemorySwap.SwapBehavior != "UnlimitedSwap" { - allErrors = append(allErrors, fmt.Errorf("invalid configuration: MemorySwap.SwapBehavior %v must be one of: NoSwap, UnlimitedSwap", kc.MemorySwap.SwapBehavior)) + if kc.MemorySwap.SwapBehavior != "" && kc.MemorySwap.SwapBehavior != kubetypes.LimitedSwap && kc.MemorySwap.SwapBehavior != kubetypes.UnlimitedSwap { + allErrors = append(allErrors, fmt.Errorf("invalid configuration: MemorySwap.SwapBehavior %v must be one of: LimitedSwap, UnlimitedSwap", kc.MemorySwap.SwapBehavior)) } } diff --git a/pkg/kubelet/apis/config/validation/validation_test.go b/pkg/kubelet/apis/config/validation/validation_test.go index 87c7924d541..3a4b057bdfc 100644 --- a/pkg/kubelet/apis/config/validation/validation_test.go +++ b/pkg/kubelet/apis/config/validation/validation_test.go @@ -24,6 +24,7 @@ import ( utilerrors "k8s.io/apimachinery/pkg/util/errors" componentbaseconfig "k8s.io/component-base/config" kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config" + kubetypes "k8s.io/kubernetes/pkg/kubelet/types" ) func TestValidateKubeletConfiguration(t *testing.T) { @@ -145,7 +146,7 @@ func TestValidateKubeletConfiguration(t *testing.T) { TopologyManagerPolicy: kubeletconfig.NoneTopologyManagerPolicy, ShutdownGracePeriod: metav1.Duration{Duration: 10 * time.Minute}, ShutdownGracePeriodCriticalPods: metav1.Duration{Duration: 0}, - MemorySwap: kubeletconfig.MemorySwapConfiguration{SwapBehavior: "UnlimitedSwap"}, + MemorySwap: kubeletconfig.MemorySwapConfiguration{SwapBehavior: kubetypes.UnlimitedSwap}, FeatureGates: map[string]bool{ "CustomCPUCFSQuotaPeriod": true, "GracefulNodeShutdown": true, diff --git a/pkg/kubelet/kuberuntime/kuberuntime_container_linux.go b/pkg/kubelet/kuberuntime/kuberuntime_container_linux.go index c65d6b22946..b9a0ed004bc 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_container_linux.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_container_linux.go @@ -30,6 +30,7 @@ import ( kubefeatures "k8s.io/kubernetes/pkg/features" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" "k8s.io/kubernetes/pkg/kubelet/qos" + kubelettypes "k8s.io/kubernetes/pkg/kubelet/types" ) // applyPlatformSpecificContainerConfig applies platform specific configurations to runtimeapi.ContainerConfig. @@ -93,11 +94,12 @@ func (m *kubeGenericRuntimeManager) generateLinuxContainerConfig(container *v1.C // NOTE(ehashman): Behaviour is defined in the opencontainers runtime spec: // https://github.com/opencontainers/runtime-spec/blob/1c3f411f041711bbeecf35ff7e93461ea6789220/config-linux.md#memory switch m.memorySwapBehavior { - case "UnlimitedSwap": + case kubelettypes.UnlimitedSwap: // -1 = unlimited swap lc.Resources.MemorySwapLimitInBytes = -1 default: - // memorySwapLimit = total permitted memory+swap; if equal to memory limit, => 0 swap + // memorySwapLimit = total permitted memory+swap; if equal to memory limit, => 0 swap above memory limit + // Some swapping is still possible. // Note that if memory limit is 0, memory swap limit is ignored. lc.Resources.MemorySwapLimitInBytes = lc.Resources.MemoryLimitInBytes } diff --git a/pkg/kubelet/kuberuntime/kuberuntime_container_linux_test.go b/pkg/kubelet/kuberuntime/kuberuntime_container_linux_test.go index 2028c951453..4650c6de788 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_container_linux_test.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_container_linux_test.go @@ -33,6 +33,7 @@ import ( runtimeapi "k8s.io/cri-api/pkg/apis/runtime/v1alpha2" "k8s.io/kubernetes/pkg/features" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" + kubelettypes "k8s.io/kubernetes/pkg/kubelet/types" ) func makeExpectedConfig(m *kubeGenericRuntimeManager, pod *v1.Pod, containerIndex int) *runtimeapi.ContainerConfig { @@ -417,8 +418,8 @@ func TestGenerateLinuxContainerConfigSwap(t *testing.T) { }, { // Note: behaviour will be the same as previous two cases - name: "config set to NoSwap, memory limit set", - swapSetting: "NoSwap", + name: "config set to LimitedSwap, memory limit set", + swapSetting: kubelettypes.LimitedSwap, pod: &v1.Pod{ Spec: v1.PodSpec{ Containers: []v1.Container{{ @@ -438,7 +439,7 @@ func TestGenerateLinuxContainerConfigSwap(t *testing.T) { }, { name: "UnlimitedSwap enabled", - swapSetting: "UnlimitedSwap", + swapSetting: kubelettypes.UnlimitedSwap, pod: &v1.Pod{ Spec: v1.PodSpec{ Containers: []v1.Container{ diff --git a/pkg/kubelet/types/constants.go b/pkg/kubelet/types/constants.go index 80707645d06..913a526b06a 100644 --- a/pkg/kubelet/types/constants.go +++ b/pkg/kubelet/types/constants.go @@ -38,3 +38,9 @@ const ( KubeReservedEnforcementKey = "kube-reserved" NodeAllocatableNoneKey = "none" ) + +// SwapBehavior types +const ( + LimitedSwap = "LimitedSwap" + UnlimitedSwap = "UnlimitedSwap" +) diff --git a/staging/src/k8s.io/kubelet/config/v1beta1/types.go b/staging/src/k8s.io/kubelet/config/v1beta1/types.go index 651148cf337..3e8b945b9ee 100644 --- a/staging/src/k8s.io/kubelet/config/v1beta1/types.go +++ b/staging/src/k8s.io/kubelet/config/v1beta1/types.go @@ -752,7 +752,7 @@ type KubeletConfiguration struct { // Default: true // +optional FailSwapOn *bool `json:"failSwapOn,omitempty"` - // Configure swap memory available to container workloads. + // memorySwap configures swap memory available to container workloads. // +featureGate=NodeSwapEnabled // +optional MemorySwap MemorySwapConfiguration `json:"memorySwap,omitempty"` @@ -1040,9 +1040,11 @@ type MemoryReservation struct { Limits v1.ResourceList `json:"limits"` } -// Configure swap memory available to container workloads. May be one of -// "", "NoSwap": workloads cannot use swap -// "UnlimitedSwap": workloads can use unlimited swap, up to the allocatable limit. type MemorySwapConfiguration struct { + // swapBehavior configures swap memory available to container workloads. May be one of + // "", "LimitedSwap": workload combined memory and swap usage cannot exceed pod memory limit + // "UnlimitedSwap": workloads can use unlimited swap, up to the allocatable limit. + // +featureGate=NodeSwapEnabled + // +optional SwapBehavior string `json:"swapBehavior,omitempty"` }