From 7a6f792ff39959d1c00d57dbf969901a7d323df9 Mon Sep 17 00:00:00 2001 From: Shiming Zhang Date: Thu, 11 Nov 2021 14:19:02 +0800 Subject: [PATCH] Add validation for GracefulNodeShutdownBasedOnPodPriority Co-authored-by: Elana Hashman --- .../apis/config/validation/validation.go | 10 ++++++ .../apis/config/validation/validation_test.go | 34 +++++++++++++------ 2 files changed, 34 insertions(+), 10 deletions(-) diff --git a/pkg/kubelet/apis/config/validation/validation.go b/pkg/kubelet/apis/config/validation/validation.go index 585e6639af5..7a89f87ddd7 100644 --- a/pkg/kubelet/apis/config/validation/validation.go +++ b/pkg/kubelet/apis/config/validation/validation.go @@ -166,6 +166,16 @@ func ValidateKubeletConfiguration(kc *kubeletconfig.KubeletConfiguration) error if (kc.ShutdownGracePeriod.Duration > 0 || kc.ShutdownGracePeriodCriticalPods.Duration > 0) && !localFeatureGate.Enabled(features.GracefulNodeShutdown) { allErrors = append(allErrors, fmt.Errorf("invalid configuration: Specifying ShutdownGracePeriod or ShutdownGracePeriodCriticalPods requires feature gate GracefulNodeShutdown")) } + if localFeatureGate.Enabled(features.GracefulNodeShutdownBasedOnPodPriority) { + if len(kc.ShutdownGracePeriodByPodPriority) != 0 && (kc.ShutdownGracePeriod.Duration > 0 || kc.ShutdownGracePeriodCriticalPods.Duration > 0) { + allErrors = append(allErrors, fmt.Errorf("invalid configuration: Cannot specify both shutdownGracePeriodByPodPriority and shutdownGracePeriod at the same time")) + } + } + if !localFeatureGate.Enabled(features.GracefulNodeShutdownBasedOnPodPriority) { + if len(kc.ShutdownGracePeriodByPodPriority) != 0 { + allErrors = append(allErrors, fmt.Errorf("invalid configuration: Specifying shutdownGracePeriodByPodPriority requires feature gate GracefulNodeShutdownBasedOnPodPriority")) + } + } if localFeatureGate.Enabled(features.NodeSwap) { 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 eb346dc6a98..2128cbbe423 100644 --- a/pkg/kubelet/apis/config/validation/validation_test.go +++ b/pkg/kubelet/apis/config/validation/validation_test.go @@ -108,8 +108,9 @@ func TestValidateKubeletConfiguration(t *testing.T) { ShutdownGracePeriodCriticalPods: metav1.Duration{Duration: 0}, MemoryThrottlingFactor: utilpointer.Float64Ptr(0.9), FeatureGates: map[string]bool{ - "CustomCPUCFSQuotaPeriod": true, - "MemoryQoS": true, + "CustomCPUCFSQuotaPeriod": true, + "MemoryQoS": true, + "GracefulNodeShutdownBasedOnPodPriority": true, }, Logging: componentbaseconfig.LoggingConfiguration{ Format: "text", @@ -149,15 +150,22 @@ func TestValidateKubeletConfiguration(t *testing.T) { ReservedSystemCPUs: "0-3", TopologyManagerScope: kubeletconfig.ContainerTopologyManagerScope, TopologyManagerPolicy: kubeletconfig.NoneTopologyManagerPolicy, - ShutdownGracePeriod: metav1.Duration{Duration: 10 * time.Minute}, + ShutdownGracePeriod: metav1.Duration{Duration: 0}, ShutdownGracePeriodCriticalPods: metav1.Duration{Duration: 0}, - MemorySwap: kubeletconfig.MemorySwapConfiguration{SwapBehavior: kubetypes.UnlimitedSwap}, - MemoryThrottlingFactor: utilpointer.Float64Ptr(0.5), + ShutdownGracePeriodByPodPriority: []kubeletconfig.ShutdownGracePeriodByPodPriority{ + { + Priority: 0, + ShutdownGracePeriodSeconds: 10, + }, + }, + MemorySwap: kubeletconfig.MemorySwapConfiguration{SwapBehavior: kubetypes.UnlimitedSwap}, + MemoryThrottlingFactor: utilpointer.Float64Ptr(0.5), FeatureGates: map[string]bool{ - "CustomCPUCFSQuotaPeriod": true, - "GracefulNodeShutdown": true, - "NodeSwap": true, - "MemoryQoS": true, + "CustomCPUCFSQuotaPeriod": true, + "GracefulNodeShutdown": true, + "GracefulNodeShutdownBasedOnPodPriority": true, + "NodeSwap": true, + "MemoryQoS": true, }, Logging: componentbaseconfig.LoggingConfiguration{ Format: "text", @@ -194,12 +202,18 @@ func TestValidateKubeletConfiguration(t *testing.T) { CPUCFSQuotaPeriod: metav1.Duration{Duration: 100 * time.Millisecond}, ShutdownGracePeriod: metav1.Duration{Duration: 30 * time.Second}, ShutdownGracePeriodCriticalPods: metav1.Duration{Duration: 60 * time.Second}, + ShutdownGracePeriodByPodPriority: []kubeletconfig.ShutdownGracePeriodByPodPriority{ + { + Priority: 0, + ShutdownGracePeriodSeconds: 10, + }, + }, Logging: componentbaseconfig.LoggingConfiguration{ Format: "", }, MemorySwap: kubeletconfig.MemorySwapConfiguration{SwapBehavior: kubetypes.UnlimitedSwap}, } - const numErrsErrorCase1 = 30 + const numErrsErrorCase1 = 31 if allErrors := ValidateKubeletConfiguration(errorCase1); len(allErrors.(utilerrors.Aggregate).Errors()) != numErrsErrorCase1 { t.Errorf("expect %d errors, got %v", numErrsErrorCase1, len(allErrors.(utilerrors.Aggregate).Errors())) }