diff --git a/cmd/kubelet/app/options/options.go b/cmd/kubelet/app/options/options.go index 3ce0b652884..738cf0f27de 100644 --- a/cmd/kubelet/app/options/options.go +++ b/cmd/kubelet/app/options/options.go @@ -150,9 +150,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 @@ -206,7 +203,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, } } @@ -217,9 +213,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 { @@ -379,7 +372,6 @@ func (f *KubeletFlags) AddFlags(mainfs *pflag.FlagSet) { fs.BoolVar(&f.ExitOnLockContention, "exit-on-lock-contention", f.ExitOnLockContention, "Whether kubelet should exit upon lock-file contention.") fs.StringVar(&f.SeccompProfileRoot, "seccomp-profile-root", f.SeccompProfileRoot, " Directory path for seccomp profiles.") 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, "") @@ -530,6 +522,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 ba84d7ecd5d..01aeaa47f0d 100644 --- a/pkg/kubelet/apis/config/fuzzer/fuzzer.go +++ b/pkg/kubelet/apis/config/fuzzer/fuzzer.go @@ -66,6 +66,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 6312cd3e424..0847c57a472 100644 --- a/pkg/kubelet/apis/config/helpers_test.go +++ b/pkg/kubelet/apis/config/helpers_test.go @@ -200,9 +200,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 c201a16df0a..7b7d1c76cee 100644 --- a/pkg/kubelet/apis/config/scheme/testdata/KubeletConfiguration/after/v1beta1.yaml +++ b/pkg/kubelet/apis/config/scheme/testdata/KubeletConfiguration/after/v1beta1.yaml @@ -52,6 +52,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 c201a16df0a..7b7d1c76cee 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 @@ -52,6 +52,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 1fb797d07da..78ac06cc20b 100644 --- a/pkg/kubelet/apis/config/types.go +++ b/pkg/kubelet/apis/config/types.go @@ -251,6 +251,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 9ce9303aa7e..36a95309018 100644 --- a/pkg/kubelet/apis/config/v1beta1/defaults.go +++ b/pkg/kubelet/apis/config/v1beta1/defaults.go @@ -176,6 +176,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 f3cf121cd0e..0876340ee93 100644 --- a/pkg/kubelet/apis/config/v1beta1/zz_generated.conversion.go +++ b/pkg/kubelet/apis/config/v1beta1/zz_generated.conversion.go @@ -287,6 +287,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 { @@ -425,6 +428,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 d323d64adfa..54cc114fa61 100644 --- a/staging/src/k8s.io/kubelet/config/v1beta1/types.go +++ b/staging/src/k8s.io/kubelet/config/v1beta1/types.go @@ -509,6 +509,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 c1dc1d5f56f..bfe72e628a2 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 @@ -185,6 +185,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)