diff --git a/cmd/kubelet/app/options/options.go b/cmd/kubelet/app/options/options.go index 6363949588d..5321d738c8a 100644 --- a/cmd/kubelet/app/options/options.go +++ b/cmd/kubelet/app/options/options.go @@ -143,9 +143,6 @@ type KubeletFlags struct { // bootstrapCheckpointPath is the path to the directory containing pod checkpoints to // run on restore BootstrapCheckpointPath string - // NodeStatusMaxImages caps the number of images reported in Node.Status.Images. - // This is an experimental, short-term flag to help with node scalability. - NodeStatusMaxImages int32 // DEPRECATED FLAGS // minimumGCAge is the minimum age for a finished container before it is @@ -198,7 +195,6 @@ func NewKubeletFlags() *KubeletFlags { RegisterNode: true, SeccompProfileRoot: filepath.Join(defaultRootDir, "seccomp"), // prior to the introduction of this flag, there was a hardcoded cap of 50 images - NodeStatusMaxImages: 50, EnableCAdvisorJSONEndpoints: false, } } @@ -209,9 +205,6 @@ func ValidateKubeletFlags(f *KubeletFlags) error { if f.DynamicConfigDir.Provided() && !utilfeature.DefaultFeatureGate.Enabled(features.DynamicKubeletConfig) { return fmt.Errorf("the DynamicKubeletConfig feature gate must be enabled in order to use the --dynamic-config-dir flag") } - if f.NodeStatusMaxImages < -1 { - return fmt.Errorf("invalid configuration: NodeStatusMaxImages (--node-status-max-images) must be -1 or greater") - } unknownLabels := sets.NewString() for k := range f.NodeLabels { @@ -366,7 +359,6 @@ func (f *KubeletFlags) AddFlags(mainfs *pflag.FlagSet) { fs.StringVar(&f.LockFilePath, "lock-file", f.LockFilePath, " The path to file for kubelet to use as a lock file.") fs.BoolVar(&f.ExitOnLockContention, "exit-on-lock-contention", f.ExitOnLockContention, "Whether kubelet should exit upon lock-file contention.") fs.StringVar(&f.BootstrapCheckpointPath, "bootstrap-checkpoint-path", f.BootstrapCheckpointPath, " Path to the directory where the checkpoints are stored") - fs.Int32Var(&f.NodeStatusMaxImages, "node-status-max-images", f.NodeStatusMaxImages, " The maximum number of images to report in Node.Status.Images. If -1 is specified, no cap will be applied.") // DEPRECATED FLAGS fs.StringVar(&f.BootstrapKubeconfig, "experimental-bootstrap-kubeconfig", f.BootstrapKubeconfig, "") @@ -523,6 +515,8 @@ func AddKubeletConfigFlags(mainfs *pflag.FlagSet, c *kubeletconfig.KubeletConfig fs.Int32Var(&c.ContainerLogMaxFiles, "container-log-max-files", c.ContainerLogMaxFiles, " Set the maximum number of container log files that can be present for a container. The number must be >= 2. This flag can only be used with --container-runtime=remote.") fs.StringSliceVar(&c.AllowedUnsafeSysctls, "allowed-unsafe-sysctls", c.AllowedUnsafeSysctls, "Comma-separated whitelist of unsafe sysctls or unsafe sysctl patterns (ending in *). Use these at your own risk.") + fs.Int32Var(&c.NodeStatusMaxImages, "node-status-max-images", c.NodeStatusMaxImages, "The maximum number of images to report in Node.Status.Images. If -1 is specified, no cap will be applied.") + // Flags intended for testing, not recommended used in production environments. fs.Int64Var(&c.MaxOpenFiles, "max-open-files", c.MaxOpenFiles, "Number of files that can be opened by Kubelet process.") diff --git a/pkg/kubelet/apis/config/fuzzer/fuzzer.go b/pkg/kubelet/apis/config/fuzzer/fuzzer.go index fdd4a55db13..c9008be145d 100644 --- a/pkg/kubelet/apis/config/fuzzer/fuzzer.go +++ b/pkg/kubelet/apis/config/fuzzer/fuzzer.go @@ -67,6 +67,7 @@ func Funcs(codecs runtimeserializer.CodecFactory) []interface{} { obj.NodeLeaseDurationSeconds = 40 obj.CPUManagerPolicy = "none" obj.CPUManagerReconcilePeriod = obj.NodeStatusUpdateFrequency + obj.NodeStatusMaxImages = 50 obj.TopologyManagerPolicy = kubeletconfig.NoneTopologyManagerPolicy obj.QOSReserved = map[string]string{ "memory": "50%", diff --git a/pkg/kubelet/apis/config/helpers_test.go b/pkg/kubelet/apis/config/helpers_test.go index eedc5763110..4cfaf04b5d0 100644 --- a/pkg/kubelet/apis/config/helpers_test.go +++ b/pkg/kubelet/apis/config/helpers_test.go @@ -201,9 +201,10 @@ var ( "StaticPodURLHeader[*][*]", "MaxOpenFiles", "MaxPods", + "NodeLeaseDurationSeconds", + "NodeStatusMaxImages", "NodeStatusUpdateFrequency.Duration", "NodeStatusReportFrequency.Duration", - "NodeLeaseDurationSeconds", "OOMScoreAdj", "PodCIDR", "PodPidsLimit", diff --git a/pkg/kubelet/apis/config/scheme/testdata/KubeletConfiguration/after/v1beta1.yaml b/pkg/kubelet/apis/config/scheme/testdata/KubeletConfiguration/after/v1beta1.yaml index fc71f87656e..703b742b4ab 100644 --- a/pkg/kubelet/apis/config/scheme/testdata/KubeletConfiguration/after/v1beta1.yaml +++ b/pkg/kubelet/apis/config/scheme/testdata/KubeletConfiguration/after/v1beta1.yaml @@ -53,6 +53,7 @@ makeIPTablesUtilChains: true maxOpenFiles: 1000000 maxPods: 110 nodeLeaseDurationSeconds: 40 +nodeStatusMaxImages: 50 nodeStatusReportFrequency: 5m0s nodeStatusUpdateFrequency: 10s oomScoreAdj: -999 diff --git a/pkg/kubelet/apis/config/scheme/testdata/KubeletConfiguration/roundtrip/default/v1beta1.yaml b/pkg/kubelet/apis/config/scheme/testdata/KubeletConfiguration/roundtrip/default/v1beta1.yaml index fc71f87656e..703b742b4ab 100644 --- a/pkg/kubelet/apis/config/scheme/testdata/KubeletConfiguration/roundtrip/default/v1beta1.yaml +++ b/pkg/kubelet/apis/config/scheme/testdata/KubeletConfiguration/roundtrip/default/v1beta1.yaml @@ -53,6 +53,7 @@ makeIPTablesUtilChains: true maxOpenFiles: 1000000 maxPods: 110 nodeLeaseDurationSeconds: 40 +nodeStatusMaxImages: 50 nodeStatusReportFrequency: 5m0s nodeStatusUpdateFrequency: 10s oomScoreAdj: -999 diff --git a/pkg/kubelet/apis/config/types.go b/pkg/kubelet/apis/config/types.go index ec8deb81fe2..bcafb460b50 100644 --- a/pkg/kubelet/apis/config/types.go +++ b/pkg/kubelet/apis/config/types.go @@ -257,6 +257,8 @@ type KubeletConfiguration struct { CPUCFSQuotaPeriod metav1.Duration // maxOpenFiles is Number of files that can be opened by Kubelet process. MaxOpenFiles int64 + // nodeStatusMaxImages caps the number of images reported in Node.Status.Images. + NodeStatusMaxImages int32 // contentType is contentType of requests sent to apiserver. ContentType string // kubeAPIQPS is the QPS to use while talking with kubernetes apiserver diff --git a/pkg/kubelet/apis/config/v1beta1/defaults.go b/pkg/kubelet/apis/config/v1beta1/defaults.go index ac8bd0045b6..880d028e381 100644 --- a/pkg/kubelet/apis/config/v1beta1/defaults.go +++ b/pkg/kubelet/apis/config/v1beta1/defaults.go @@ -179,6 +179,9 @@ func SetDefaults_KubeletConfiguration(obj *kubeletconfigv1beta1.KubeletConfigura if obj.CPUCFSQuotaPeriod == nil { obj.CPUCFSQuotaPeriod = &metav1.Duration{Duration: 100 * time.Millisecond} } + if obj.NodeStatusMaxImages == nil { + obj.NodeStatusMaxImages = utilpointer.Int32Ptr(50) + } if obj.MaxOpenFiles == 0 { obj.MaxOpenFiles = 1000000 } diff --git a/pkg/kubelet/apis/config/v1beta1/zz_generated.conversion.go b/pkg/kubelet/apis/config/v1beta1/zz_generated.conversion.go index c1c7c37f79c..f0579411672 100644 --- a/pkg/kubelet/apis/config/v1beta1/zz_generated.conversion.go +++ b/pkg/kubelet/apis/config/v1beta1/zz_generated.conversion.go @@ -290,6 +290,9 @@ func autoConvert_v1beta1_KubeletConfiguration_To_config_KubeletConfiguration(in if err := v1.Convert_Pointer_v1_Duration_To_v1_Duration(&in.CPUCFSQuotaPeriod, &out.CPUCFSQuotaPeriod, s); err != nil { return err } + if err := v1.Convert_Pointer_int32_To_int32(&in.NodeStatusMaxImages, &out.NodeStatusMaxImages, s); err != nil { + return err + } out.MaxOpenFiles = in.MaxOpenFiles out.ContentType = in.ContentType if err := v1.Convert_Pointer_int32_To_int32(&in.KubeAPIQPS, &out.KubeAPIQPS, s); err != nil { @@ -433,6 +436,9 @@ func autoConvert_config_KubeletConfiguration_To_v1beta1_KubeletConfiguration(in return err } out.MaxOpenFiles = in.MaxOpenFiles + if err := v1.Convert_int32_To_Pointer_int32(&in.NodeStatusMaxImages, &out.NodeStatusMaxImages, s); err != nil { + return err + } out.ContentType = in.ContentType if err := v1.Convert_int32_To_Pointer_int32(&in.KubeAPIQPS, &out.KubeAPIQPS, s); err != nil { return err diff --git a/pkg/kubelet/apis/config/validation/validation.go b/pkg/kubelet/apis/config/validation/validation.go index 03681306850..0e87f89aec5 100644 --- a/pkg/kubelet/apis/config/validation/validation.go +++ b/pkg/kubelet/apis/config/validation/validation.go @@ -83,6 +83,9 @@ func ValidateKubeletConfiguration(kc *kubeletconfig.KubeletConfiguration) error if kc.KubeAPIQPS < 0 { allErrors = append(allErrors, fmt.Errorf("invalid configuration: KubeAPIQPS (--kube-api-qps) %v must not be a negative number", kc.KubeAPIQPS)) } + if kc.NodeStatusMaxImages < -1 { + allErrors = append(allErrors, fmt.Errorf("invalid configuration: NodeStatusMaxImages (--node-status-max-images) must be -1 or greater")) + } if kc.MaxOpenFiles < 0 { allErrors = append(allErrors, fmt.Errorf("invalid configuration: MaxOpenFiles (--max-open-files) %v must not be a negative number", kc.MaxOpenFiles)) } diff --git a/staging/src/k8s.io/kubelet/config/v1beta1/types.go b/staging/src/k8s.io/kubelet/config/v1beta1/types.go index a6cf5a2b43a..5c61c130dd6 100644 --- a/staging/src/k8s.io/kubelet/config/v1beta1/types.go +++ b/staging/src/k8s.io/kubelet/config/v1beta1/types.go @@ -515,6 +515,13 @@ type KubeletConfiguration struct { // Default: "100ms" // +optional CPUCFSQuotaPeriod *metav1.Duration `json:"cpuCFSQuotaPeriod,omitempty"` + // nodeStatusMaxImages caps the number of images reported in Node.Status.Images. + // Note: If -1 is specified, no cap will be applied. If 0 is specified, no image is returned. + // Dynamic Kubelet Config (beta): If dynamically updating this field, consider that + // different values can be reported on node status. + // Default: 50 + // +optional + NodeStatusMaxImages *int32 `json:"nodeStatusMaxImages,omitempty"` // maxOpenFiles is Number of files that can be opened by Kubelet process. // Dynamic Kubelet Config (beta): If dynamically updating this field, consider that // it may impact the ability of the Kubelet to interact with the node's filesystem. diff --git a/staging/src/k8s.io/kubelet/config/v1beta1/zz_generated.deepcopy.go b/staging/src/k8s.io/kubelet/config/v1beta1/zz_generated.deepcopy.go index 6a005507e46..176d1643235 100644 --- a/staging/src/k8s.io/kubelet/config/v1beta1/zz_generated.deepcopy.go +++ b/staging/src/k8s.io/kubelet/config/v1beta1/zz_generated.deepcopy.go @@ -190,6 +190,11 @@ func (in *KubeletConfiguration) DeepCopyInto(out *KubeletConfiguration) { *out = new(v1.Duration) **out = **in } + if in.NodeStatusMaxImages != nil { + in, out := &in.NodeStatusMaxImages, &out.NodeStatusMaxImages + *out = new(int32) + **out = **in + } if in.KubeAPIQPS != nil { in, out := &in.KubeAPIQPS, &out.KubeAPIQPS *out = new(int32)