k8s.io/kubernetes@v1.31.0-alpha.0.0.20240520171757-56147500dadc/cmd/kubelet/app/options/options.go (about)

     1  /*
     2  Copyright 2015 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  // Package options contains all of the primary arguments for a kubelet.
    18  package options
    19  
    20  import (
    21  	"fmt"
    22  	_ "net/http/pprof" // Enable pprof HTTP handlers.
    23  	"path/filepath"
    24  	"strings"
    25  
    26  	"github.com/spf13/pflag"
    27  
    28  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    29  	"k8s.io/apimachinery/pkg/util/sets"
    30  	"k8s.io/apimachinery/pkg/util/validation"
    31  	utilfeature "k8s.io/apiserver/pkg/util/feature"
    32  	cliflag "k8s.io/component-base/cli/flag"
    33  	logsapi "k8s.io/component-base/logs/api/v1"
    34  	"k8s.io/kubelet/config/v1beta1"
    35  	kubeletapis "k8s.io/kubelet/pkg/apis"
    36  	"k8s.io/kubernetes/pkg/cluster/ports"
    37  	kubeletconfig "k8s.io/kubernetes/pkg/kubelet/apis/config"
    38  	kubeletscheme "k8s.io/kubernetes/pkg/kubelet/apis/config/scheme"
    39  	kubeletconfigvalidation "k8s.io/kubernetes/pkg/kubelet/apis/config/validation"
    40  	"k8s.io/kubernetes/pkg/kubelet/config"
    41  	utilflag "k8s.io/kubernetes/pkg/util/flag"
    42  )
    43  
    44  const defaultRootDir = "/var/lib/kubelet"
    45  
    46  // KubeletFlags contains configuration flags for the Kubelet.
    47  // A configuration field should go in KubeletFlags instead of KubeletConfiguration if any of these are true:
    48  //   - its value will never, or cannot safely be changed during the lifetime of a node, or
    49  //   - its value cannot be safely shared between nodes at the same time (e.g. a hostname);
    50  //     KubeletConfiguration is intended to be shared between nodes.
    51  //
    52  // In general, please try to avoid adding flags or configuration fields,
    53  // we already have a confusingly large amount of them.
    54  type KubeletFlags struct {
    55  	KubeConfig          string
    56  	BootstrapKubeconfig string
    57  
    58  	// HostnameOverride is the hostname used to identify the kubelet instead
    59  	// of the actual hostname.
    60  	HostnameOverride string
    61  	// NodeIP is IP address of the node.
    62  	// If set, kubelet will use this IP address for the node.
    63  	NodeIP string
    64  
    65  	// Container-runtime-specific options.
    66  	config.ContainerRuntimeOptions
    67  
    68  	// certDirectory is the directory where the TLS certs are located.
    69  	// If tlsCertFile and tlsPrivateKeyFile are provided, this flag will be ignored.
    70  	CertDirectory string
    71  
    72  	// cloudProvider is the provider for cloud services.
    73  	// +optional
    74  	CloudProvider string
    75  
    76  	// cloudConfigFile is the path to the cloud provider configuration file.
    77  	// +optional
    78  	CloudConfigFile string
    79  
    80  	// rootDirectory is the directory path to place kubelet files (volume
    81  	// mounts,etc).
    82  	RootDirectory string
    83  
    84  	// The Kubelet will load its initial configuration from this file.
    85  	// The path may be absolute or relative; relative paths are under the Kubelet's current working directory.
    86  	// Omit this flag to use the combination of built-in default configuration values and flags.
    87  	KubeletConfigFile string
    88  
    89  	// kubeletDropinConfigDirectory is a path to a directory to specify dropins allows the user to optionally specify
    90  	// additional configs to overwrite what is provided by default and in the KubeletConfigFile flag
    91  	KubeletDropinConfigDirectory string
    92  
    93  	// WindowsService should be set to true if kubelet is running as a service on Windows.
    94  	// Its corresponding flag only gets registered in Windows builds.
    95  	WindowsService bool
    96  
    97  	// WindowsPriorityClass sets the priority class associated with the Kubelet process
    98  	// Its corresponding flag only gets registered in Windows builds
    99  	// The default priority class associated with any process in Windows is NORMAL_PRIORITY_CLASS. Keeping it as is
   100  	// to maintain backwards compatibility.
   101  	// Source: https://docs.microsoft.com/en-us/windows/win32/procthread/scheduling-priorities
   102  	WindowsPriorityClass string
   103  
   104  	// experimentalMounterPath is the path of mounter binary. Leave empty to use the default mount path
   105  	ExperimentalMounterPath string
   106  	// This flag, if set, will avoid including `EvictionHard` limits while computing Node Allocatable.
   107  	// Refer to [Node Allocatable](https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/#node-allocatable) doc for more information.
   108  	ExperimentalNodeAllocatableIgnoreEvictionThreshold bool
   109  	// Node Labels are the node labels to add when registering the node in the cluster
   110  	NodeLabels map[string]string
   111  	// lockFilePath is the path that kubelet will use to as a lock file.
   112  	// It uses this file as a lock to synchronize with other kubelet processes
   113  	// that may be running.
   114  	LockFilePath string
   115  	// ExitOnLockContention is a flag that signifies to the kubelet that it is running
   116  	// in "bootstrap" mode. This requires that 'LockFilePath' has been set.
   117  	// This will cause the kubelet to listen to inotify events on the lock file,
   118  	// releasing it and exiting when another process tries to open that file.
   119  	ExitOnLockContention bool
   120  	// DEPRECATED FLAGS
   121  	// minimumGCAge is the minimum age for a finished container before it is
   122  	// garbage collected.
   123  	MinimumGCAge metav1.Duration
   124  	// maxPerPodContainerCount is the maximum number of old instances to
   125  	// retain per container. Each container takes up some disk space.
   126  	MaxPerPodContainerCount int32
   127  	// maxContainerCount is the maximum number of old instances of containers
   128  	// to retain globally. Each container takes up some disk space.
   129  	MaxContainerCount int32
   130  	// registerSchedulable tells the kubelet to register the node as
   131  	// schedulable. Won't have any effect if register-node is false.
   132  	// DEPRECATED: use registerWithTaints instead
   133  	RegisterSchedulable bool
   134  	// SeccompDefault enables the use of `RuntimeDefault` as the default seccomp profile for all workloads on the node.
   135  	SeccompDefault bool
   136  }
   137  
   138  // NewKubeletFlags will create a new KubeletFlags with default values
   139  func NewKubeletFlags() *KubeletFlags {
   140  	return &KubeletFlags{
   141  		ContainerRuntimeOptions: *NewContainerRuntimeOptions(),
   142  		CertDirectory:           "/var/lib/kubelet/pki",
   143  		RootDirectory:           filepath.Clean(defaultRootDir),
   144  		MaxContainerCount:       -1,
   145  		MaxPerPodContainerCount: 1,
   146  		MinimumGCAge:            metav1.Duration{Duration: 0},
   147  		RegisterSchedulable:     true,
   148  		NodeLabels:              make(map[string]string),
   149  	}
   150  }
   151  
   152  // ValidateKubeletFlags validates Kubelet's configuration flags and returns an error if they are invalid.
   153  func ValidateKubeletFlags(f *KubeletFlags) error {
   154  	unknownLabels := sets.NewString()
   155  	invalidLabelErrs := make(map[string][]string)
   156  	for k, v := range f.NodeLabels {
   157  		if isKubernetesLabel(k) && !kubeletapis.IsKubeletLabel(k) {
   158  			unknownLabels.Insert(k)
   159  		}
   160  
   161  		if errs := validation.IsQualifiedName(k); len(errs) > 0 {
   162  			invalidLabelErrs[k] = append(invalidLabelErrs[k], errs...)
   163  		}
   164  		if errs := validation.IsValidLabelValue(v); len(errs) > 0 {
   165  			invalidLabelErrs[v] = append(invalidLabelErrs[v], errs...)
   166  		}
   167  	}
   168  	if len(unknownLabels) > 0 {
   169  		return fmt.Errorf("unknown 'kubernetes.io' or 'k8s.io' labels specified with --node-labels: %v\n--node-labels in the 'kubernetes.io' namespace must begin with an allowed prefix (%s) or be in the specifically allowed set (%s)", unknownLabels.List(), strings.Join(kubeletapis.KubeletLabelNamespaces(), ", "), strings.Join(kubeletapis.KubeletLabels(), ", "))
   170  	}
   171  	if len(invalidLabelErrs) > 0 {
   172  		labelErrs := []string{}
   173  		for k, v := range invalidLabelErrs {
   174  			labelErrs = append(labelErrs, fmt.Sprintf("'%s' - %s", k, strings.Join(v, ", ")))
   175  		}
   176  		return fmt.Errorf("invalid node labels: %s", strings.Join(labelErrs, "; "))
   177  	}
   178  	return nil
   179  }
   180  
   181  func isKubernetesLabel(key string) bool {
   182  	namespace := getLabelNamespace(key)
   183  	if namespace == "kubernetes.io" || strings.HasSuffix(namespace, ".kubernetes.io") {
   184  		return true
   185  	}
   186  	if namespace == "k8s.io" || strings.HasSuffix(namespace, ".k8s.io") {
   187  		return true
   188  	}
   189  	return false
   190  }
   191  
   192  func getLabelNamespace(key string) string {
   193  	if parts := strings.SplitN(key, "/", 2); len(parts) == 2 {
   194  		return parts[0]
   195  	}
   196  	return ""
   197  }
   198  
   199  // NewKubeletConfiguration will create a new KubeletConfiguration with default values
   200  func NewKubeletConfiguration() (*kubeletconfig.KubeletConfiguration, error) {
   201  	scheme, _, err := kubeletscheme.NewSchemeAndCodecs()
   202  	if err != nil {
   203  		return nil, err
   204  	}
   205  	versioned := &v1beta1.KubeletConfiguration{}
   206  	scheme.Default(versioned)
   207  	config := &kubeletconfig.KubeletConfiguration{}
   208  	if err := scheme.Convert(versioned, config, nil); err != nil {
   209  		return nil, err
   210  	}
   211  	applyLegacyDefaults(config)
   212  	return config, nil
   213  }
   214  
   215  // applyLegacyDefaults applies legacy default values to the KubeletConfiguration in order to
   216  // preserve the command line API. This is used to construct the baseline default KubeletConfiguration
   217  // before the first round of flag parsing.
   218  func applyLegacyDefaults(kc *kubeletconfig.KubeletConfiguration) {
   219  	// --anonymous-auth
   220  	kc.Authentication.Anonymous.Enabled = true
   221  	// --authentication-token-webhook
   222  	kc.Authentication.Webhook.Enabled = false
   223  	// --authorization-mode
   224  	kc.Authorization.Mode = kubeletconfig.KubeletAuthorizationModeAlwaysAllow
   225  	// --read-only-port
   226  	kc.ReadOnlyPort = ports.KubeletReadOnlyPort
   227  }
   228  
   229  // KubeletServer encapsulates all of the parameters necessary for starting up
   230  // a kubelet. These can either be set via command line or directly.
   231  type KubeletServer struct {
   232  	KubeletFlags
   233  	kubeletconfig.KubeletConfiguration
   234  }
   235  
   236  // NewKubeletServer will create a new KubeletServer with default values.
   237  func NewKubeletServer() (*KubeletServer, error) {
   238  	config, err := NewKubeletConfiguration()
   239  	if err != nil {
   240  		return nil, err
   241  	}
   242  	return &KubeletServer{
   243  		KubeletFlags:         *NewKubeletFlags(),
   244  		KubeletConfiguration: *config,
   245  	}, nil
   246  }
   247  
   248  // ValidateKubeletServer validates configuration of KubeletServer and returns an error if the input configuration is invalid.
   249  func ValidateKubeletServer(s *KubeletServer) error {
   250  	// please add any KubeletConfiguration validation to the kubeletconfigvalidation.ValidateKubeletConfiguration function
   251  	if err := kubeletconfigvalidation.ValidateKubeletConfiguration(&s.KubeletConfiguration, utilfeature.DefaultFeatureGate); err != nil {
   252  		return err
   253  	}
   254  	if err := ValidateKubeletFlags(&s.KubeletFlags); err != nil {
   255  		return err
   256  	}
   257  	return nil
   258  }
   259  
   260  // AddFlags adds flags for a specific KubeletServer to the specified FlagSet
   261  func (s *KubeletServer) AddFlags(fs *pflag.FlagSet) {
   262  	s.KubeletFlags.AddFlags(fs)
   263  	AddKubeletConfigFlags(fs, &s.KubeletConfiguration)
   264  }
   265  
   266  // AddFlags adds flags for a specific KubeletFlags to the specified FlagSet
   267  func (f *KubeletFlags) AddFlags(mainfs *pflag.FlagSet) {
   268  	fs := pflag.NewFlagSet("", pflag.ExitOnError)
   269  	defer func() {
   270  		// Unhide deprecated flags. We want deprecated flags to show in Kubelet help.
   271  		// We have some hidden flags, but we might as well unhide these when they are deprecated,
   272  		// as silently deprecating and removing (even hidden) things is unkind to people who use them.
   273  		fs.VisitAll(func(f *pflag.Flag) {
   274  			if len(f.Deprecated) > 0 {
   275  				f.Hidden = false
   276  			}
   277  		})
   278  		mainfs.AddFlagSet(fs)
   279  	}()
   280  
   281  	f.ContainerRuntimeOptions.AddFlags(fs)
   282  	f.addOSFlags(fs)
   283  
   284  	fs.StringVar(&f.KubeletConfigFile, "config", f.KubeletConfigFile, "The Kubelet will load its initial configuration from this file. The path may be absolute or relative; relative paths start at the Kubelet's current working directory. Omit this flag to use the built-in default configuration values. Command-line flags override configuration from this file.")
   285  	fs.StringVar(&f.KubeletDropinConfigDirectory, "config-dir", "", "Path to a directory to specify drop-ins, allows the user to optionally specify additional configs to overwrite what is provided by default and in the KubeletConfigFile flag. [default='']")
   286  	fs.StringVar(&f.KubeConfig, "kubeconfig", f.KubeConfig, "Path to a kubeconfig file, specifying how to connect to the API server. Providing --kubeconfig enables API server mode, omitting --kubeconfig enables standalone mode.")
   287  
   288  	fs.StringVar(&f.BootstrapKubeconfig, "bootstrap-kubeconfig", f.BootstrapKubeconfig, "Path to a kubeconfig file that will be used to get client certificate for kubelet. "+
   289  		"If the file specified by --kubeconfig does not exist, the bootstrap kubeconfig is used to request a client certificate from the API server. "+
   290  		"On success, a kubeconfig file referencing the generated client certificate and key is written to the path specified by --kubeconfig. "+
   291  		"The client certificate and key file will be stored in the directory pointed by --cert-dir.")
   292  
   293  	fs.StringVar(&f.HostnameOverride, "hostname-override", f.HostnameOverride, "If non-empty, will use this string as identification instead of the actual hostname. If --cloud-provider is set, the cloud provider determines the name of the node (consult cloud provider documentation to determine if and how the hostname is used).")
   294  
   295  	fs.StringVar(&f.NodeIP, "node-ip", f.NodeIP, "IP address (or comma-separated dual-stack IP addresses) of the node. If unset, kubelet will use the node's default IPv4 address, if any, or its default IPv6 address if it has no IPv4 addresses. You can pass '::' to make it prefer the default IPv6 address rather than the default IPv4 address.")
   296  
   297  	fs.StringVar(&f.CertDirectory, "cert-dir", f.CertDirectory, "The directory where the TLS certs are located. "+
   298  		"If --tls-cert-file and --tls-private-key-file are provided, this flag will be ignored.")
   299  
   300  	fs.StringVar(&f.CloudProvider, "cloud-provider", f.CloudProvider, "The provider for cloud services. Set to empty string for running with no cloud provider. Set to 'external' for running with an external cloud provider. If set, the cloud provider determines the name of the node (consult cloud provider documentation to determine if and how the hostname is used).")
   301  
   302  	fs.StringVar(&f.RootDirectory, "root-dir", f.RootDirectory, "Directory path for managing kubelet files (volume mounts,etc).")
   303  	fs.BoolVar(&f.SeccompDefault, "seccomp-default", f.SeccompDefault, "Enable the use of `RuntimeDefault` as the default seccomp profile for all workloads.")
   304  
   305  	bindableNodeLabels := cliflag.ConfigurationMap(f.NodeLabels)
   306  	fs.Var(&bindableNodeLabels, "node-labels", fmt.Sprintf("Labels to add when registering the node in the cluster.  Labels must be key=value pairs separated by ','. Labels in the 'kubernetes.io' namespace must begin with an allowed prefix (%s) or be in the specifically allowed set (%s)", strings.Join(kubeletapis.KubeletLabelNamespaces(), ", "), strings.Join(kubeletapis.KubeletLabels(), ", ")))
   307  
   308  	// EXPERIMENTAL FLAGS
   309  	fs.StringVar(&f.LockFilePath, "lock-file", f.LockFilePath, "<Warning: Alpha feature> The path to file for kubelet to use as a lock file.")
   310  	fs.BoolVar(&f.ExitOnLockContention, "exit-on-lock-contention", f.ExitOnLockContention, "Whether kubelet should exit upon lock-file contention.")
   311  
   312  	// DEPRECATED FLAGS
   313  	fs.DurationVar(&f.MinimumGCAge.Duration, "minimum-container-ttl-duration", f.MinimumGCAge.Duration, "Minimum age for a finished container before it is garbage collected.  Examples: '300ms', '10s' or '2h45m'")
   314  	fs.MarkDeprecated("minimum-container-ttl-duration", "Use --eviction-hard or --eviction-soft instead. Will be removed in a future version.")
   315  	fs.Int32Var(&f.MaxPerPodContainerCount, "maximum-dead-containers-per-container", f.MaxPerPodContainerCount, "Maximum number of old instances to retain per container.  Each container takes up some disk space.")
   316  	fs.MarkDeprecated("maximum-dead-containers-per-container", "Use --eviction-hard or --eviction-soft instead. Will be removed in a future version.")
   317  	fs.Int32Var(&f.MaxContainerCount, "maximum-dead-containers", f.MaxContainerCount, "Maximum number of old instances of containers to retain globally.  Each container takes up some disk space. To disable, set to a negative number.")
   318  	fs.MarkDeprecated("maximum-dead-containers", "Use --eviction-hard or --eviction-soft instead. Will be removed in a future version.")
   319  	fs.BoolVar(&f.RegisterSchedulable, "register-schedulable", f.RegisterSchedulable, "Register the node as schedulable. Won't have any effect if register-node is false.")
   320  	fs.MarkDeprecated("register-schedulable", "will be removed in a future version")
   321  	fs.StringVar(&f.ExperimentalMounterPath, "experimental-mounter-path", f.ExperimentalMounterPath, "[Experimental] Path of mounter binary. Leave empty to use the default mount.")
   322  	fs.MarkDeprecated("experimental-mounter-path", "will be removed in 1.25 or later. in favor of using CSI.")
   323  	fs.StringVar(&f.CloudConfigFile, "cloud-config", f.CloudConfigFile, "The path to the cloud provider configuration file. Empty string for no configuration file.")
   324  	fs.MarkDeprecated("cloud-config", "will be removed in 1.25 or later, in favor of removing cloud provider code from Kubelet.")
   325  	fs.BoolVar(&f.ExperimentalNodeAllocatableIgnoreEvictionThreshold, "experimental-allocatable-ignore-eviction", f.ExperimentalNodeAllocatableIgnoreEvictionThreshold, "When set to 'true', Hard Eviction Thresholds will be ignored while calculating Node Allocatable. See https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/ for more details. [default=false]")
   326  	fs.MarkDeprecated("experimental-allocatable-ignore-eviction", "will be removed in 1.25 or later.")
   327  }
   328  
   329  // AddKubeletConfigFlags adds flags for a specific kubeletconfig.KubeletConfiguration to the specified FlagSet
   330  func AddKubeletConfigFlags(mainfs *pflag.FlagSet, c *kubeletconfig.KubeletConfiguration) {
   331  	fs := pflag.NewFlagSet("", pflag.ExitOnError)
   332  	defer func() {
   333  		// All KubeletConfiguration flags are now deprecated, and any new flags that point to
   334  		// KubeletConfiguration fields are deprecated-on-creation. When removing flags at the end
   335  		// of their deprecation period, be careful to check that they have *actually* been deprecated
   336  		// members of the KubeletConfiguration for the entire deprecation period:
   337  		// e.g. if a flag was added after this deprecation function, it may not be at the end
   338  		// of its lifetime yet, even if the rest are.
   339  		deprecated := "This parameter should be set via the config file specified by the Kubelet's --config flag. See https://kubernetes.io/docs/tasks/administer-cluster/kubelet-config-file/ for more information."
   340  		// Some flags are permanently (?) meant to be available. In
   341  		// Kubernetes 1.23, the following options were added to
   342  		// LoggingConfiguration (long-term goal, more complete
   343  		// configuration file) but deprecating the flags seemed
   344  		// premature.
   345  		notDeprecated := map[string]bool{
   346  			"v":                   true,
   347  			"vmodule":             true,
   348  			"log-flush-frequency": true,
   349  			"provider-id":         true,
   350  		}
   351  		fs.VisitAll(func(f *pflag.Flag) {
   352  			if notDeprecated[f.Name] {
   353  				return
   354  			}
   355  			f.Deprecated = deprecated
   356  		})
   357  		mainfs.AddFlagSet(fs)
   358  	}()
   359  
   360  	fs.BoolVar(&c.EnableServer, "enable-server", c.EnableServer, "Enable the Kubelet's server")
   361  
   362  	fs.BoolVar(&c.FailSwapOn, "fail-swap-on", c.FailSwapOn, "Makes the Kubelet fail to start if swap is enabled on the node. ")
   363  	fs.StringVar(&c.StaticPodPath, "pod-manifest-path", c.StaticPodPath, "Path to the directory containing static pod files to run, or the path to a single static pod file. Files starting with dots will be ignored.")
   364  	fs.DurationVar(&c.SyncFrequency.Duration, "sync-frequency", c.SyncFrequency.Duration, "Max period between synchronizing running containers and config")
   365  	fs.DurationVar(&c.FileCheckFrequency.Duration, "file-check-frequency", c.FileCheckFrequency.Duration, "Duration between checking config files for new data")
   366  	fs.DurationVar(&c.HTTPCheckFrequency.Duration, "http-check-frequency", c.HTTPCheckFrequency.Duration, "Duration between checking http for new data")
   367  	fs.StringVar(&c.StaticPodURL, "manifest-url", c.StaticPodURL, "URL for accessing additional Pod specifications to run")
   368  	fs.Var(cliflag.NewColonSeparatedMultimapStringString(&c.StaticPodURLHeader), "manifest-url-header", "Comma-separated list of HTTP headers to use when accessing the url provided to --manifest-url. Multiple headers with the same name will be added in the same order provided. This flag can be repeatedly invoked. For example: --manifest-url-header 'a:hello,b:again,c:world' --manifest-url-header 'b:beautiful'")
   369  	fs.Var(&utilflag.IPVar{Val: &c.Address}, "address", "The IP address for the Kubelet to serve on (set to '0.0.0.0' or '::' for listening on all interfaces and IP address families)")
   370  	fs.Int32Var(&c.Port, "port", c.Port, "The port for the Kubelet to serve on.")
   371  	fs.Int32Var(&c.ReadOnlyPort, "read-only-port", c.ReadOnlyPort, "The read-only port for the Kubelet to serve on with no authentication/authorization (set to 0 to disable)")
   372  
   373  	// runtime flags
   374  	fs.StringVar(&c.ContainerRuntimeEndpoint, "container-runtime-endpoint", c.ContainerRuntimeEndpoint, "The endpoint of container runtime service. Unix Domain Sockets are supported on Linux, while npipe and tcp endpoints are supported on Windows. Examples:'unix:///path/to/runtime.sock', 'npipe:////./pipe/runtime'")
   375  	fs.StringVar(&c.ImageServiceEndpoint, "image-service-endpoint", c.ImageServiceEndpoint, "The endpoint of container image service. If not specified, it will be the same with --container-runtime-endpoint by default. Unix Domain Socket are supported on Linux, while npipe and tcp endpoints are supported on Windows. Examples:'unix:///path/to/runtime.sock', 'npipe:////./pipe/runtime'")
   376  
   377  	// Authentication
   378  	fs.BoolVar(&c.Authentication.Anonymous.Enabled, "anonymous-auth", c.Authentication.Anonymous.Enabled, ""+
   379  		"Enables anonymous requests to the Kubelet server. Requests that are not rejected by another "+
   380  		"authentication method are treated as anonymous requests. Anonymous requests have a username "+
   381  		"of system:anonymous, and a group name of system:unauthenticated.")
   382  	fs.BoolVar(&c.Authentication.Webhook.Enabled, "authentication-token-webhook", c.Authentication.Webhook.Enabled, ""+
   383  		"Use the TokenReview API to determine authentication for bearer tokens.")
   384  	fs.DurationVar(&c.Authentication.Webhook.CacheTTL.Duration, "authentication-token-webhook-cache-ttl", c.Authentication.Webhook.CacheTTL.Duration, ""+
   385  		"The duration to cache responses from the webhook token authenticator.")
   386  	fs.StringVar(&c.Authentication.X509.ClientCAFile, "client-ca-file", c.Authentication.X509.ClientCAFile, ""+
   387  		"If set, any request presenting a client certificate signed by one of the authorities in the client-ca-file "+
   388  		"is authenticated with an identity corresponding to the CommonName of the client certificate.")
   389  
   390  	// Authorization
   391  	fs.StringVar((*string)(&c.Authorization.Mode), "authorization-mode", string(c.Authorization.Mode), ""+
   392  		"Authorization mode for Kubelet server. Valid options are AlwaysAllow or Webhook. "+
   393  		"Webhook mode uses the SubjectAccessReview API to determine authorization.")
   394  	fs.DurationVar(&c.Authorization.Webhook.CacheAuthorizedTTL.Duration, "authorization-webhook-cache-authorized-ttl", c.Authorization.Webhook.CacheAuthorizedTTL.Duration, ""+
   395  		"The duration to cache 'authorized' responses from the webhook authorizer.")
   396  	fs.DurationVar(&c.Authorization.Webhook.CacheUnauthorizedTTL.Duration, "authorization-webhook-cache-unauthorized-ttl", c.Authorization.Webhook.CacheUnauthorizedTTL.Duration, ""+
   397  		"The duration to cache 'unauthorized' responses from the webhook authorizer.")
   398  
   399  	fs.StringVar(&c.TLSCertFile, "tls-cert-file", c.TLSCertFile, ""+
   400  		"File containing x509 Certificate used for serving HTTPS (with intermediate certs, if any, concatenated after server cert). "+
   401  		"If --tls-cert-file and --tls-private-key-file are not provided, a self-signed certificate and key "+
   402  		"are generated for the public address and saved to the directory passed to --cert-dir.")
   403  	fs.StringVar(&c.TLSPrivateKeyFile, "tls-private-key-file", c.TLSPrivateKeyFile, "File containing x509 private key matching --tls-cert-file.")
   404  	fs.BoolVar(&c.ServerTLSBootstrap, "rotate-server-certificates", c.ServerTLSBootstrap, "Auto-request and rotate the kubelet serving certificates by requesting new certificates from the kube-apiserver when the certificate expiration approaches. Requires the RotateKubeletServerCertificate feature gate to be enabled, and approval of the submitted CertificateSigningRequest objects.")
   405  
   406  	tlsCipherPreferredValues := cliflag.PreferredTLSCipherNames()
   407  	tlsCipherInsecureValues := cliflag.InsecureTLSCipherNames()
   408  	fs.StringSliceVar(&c.TLSCipherSuites, "tls-cipher-suites", c.TLSCipherSuites,
   409  		"Comma-separated list of cipher suites for the server. "+
   410  			"If omitted, the default Go cipher suites will be used. \n"+
   411  			"Preferred values: "+strings.Join(tlsCipherPreferredValues, ", ")+". \n"+
   412  			"Insecure values: "+strings.Join(tlsCipherInsecureValues, ", ")+".")
   413  	tlsPossibleVersions := cliflag.TLSPossibleVersions()
   414  	fs.StringVar(&c.TLSMinVersion, "tls-min-version", c.TLSMinVersion,
   415  		"Minimum TLS version supported. "+
   416  			"Possible values: "+strings.Join(tlsPossibleVersions, ", "))
   417  	fs.BoolVar(&c.RotateCertificates, "rotate-certificates", c.RotateCertificates, "Auto rotate the kubelet client certificates by requesting new certificates from the kube-apiserver when the certificate expiration approaches.")
   418  
   419  	fs.Int32Var(&c.RegistryPullQPS, "registry-qps", c.RegistryPullQPS, "If > 0, limit registry pull QPS to this value.  If 0, unlimited.")
   420  	fs.Int32Var(&c.RegistryBurst, "registry-burst", c.RegistryBurst, "Maximum size of a bursty pulls, temporarily allows pulls to burst to this number, while still not exceeding registry-qps. Only used if --registry-qps > 0")
   421  	fs.Int32Var(&c.EventRecordQPS, "event-qps", c.EventRecordQPS, "QPS to limit event creations. The number must be >= 0. If 0 will use DefaultQPS: 5.")
   422  	fs.Int32Var(&c.EventBurst, "event-burst", c.EventBurst, "Maximum size of a bursty event records, temporarily allows event records to burst to this number, while still not exceeding event-qps. The number must be >= 0. If 0 will use DefaultBurst: 10.")
   423  
   424  	fs.BoolVar(&c.EnableDebuggingHandlers, "enable-debugging-handlers", c.EnableDebuggingHandlers, "Enables server endpoints for log collection and local running of containers and commands")
   425  	fs.BoolVar(&c.EnableContentionProfiling, "contention-profiling", c.EnableContentionProfiling, "Enable block profiling, if profiling is enabled")
   426  	fs.Int32Var(&c.HealthzPort, "healthz-port", c.HealthzPort, "The port of the localhost healthz endpoint (set to 0 to disable)")
   427  	fs.Var(&utilflag.IPVar{Val: &c.HealthzBindAddress}, "healthz-bind-address", "The IP address for the healthz server to serve on (set to '0.0.0.0' or '::' for listening on all interfaces and IP address families)")
   428  	fs.Int32Var(&c.OOMScoreAdj, "oom-score-adj", c.OOMScoreAdj, "The oom-score-adj value for kubelet process. Values must be within the range [-1000, 1000]")
   429  	fs.StringVar(&c.ClusterDomain, "cluster-domain", c.ClusterDomain, "Domain for this cluster.  If set, kubelet will configure all containers to search this domain in addition to the host's search domains")
   430  
   431  	fs.StringVar(&c.VolumePluginDir, "volume-plugin-dir", c.VolumePluginDir, "The full path of the directory in which to search for additional third party volume plugins")
   432  	fs.StringSliceVar(&c.ClusterDNS, "cluster-dns", c.ClusterDNS, "Comma-separated list of DNS server IP address.  This value is used for containers DNS server in case of Pods with \"dnsPolicy=ClusterFirst\". Note: all DNS servers appearing in the list MUST serve the same set of records otherwise name resolution within the cluster may not work correctly. There is no guarantee as to which DNS server may be contacted for name resolution.")
   433  	fs.DurationVar(&c.StreamingConnectionIdleTimeout.Duration, "streaming-connection-idle-timeout", c.StreamingConnectionIdleTimeout.Duration, "Maximum time a streaming connection can be idle before the connection is automatically closed. 0 indicates no timeout. Example: '5m'. Note: All connections to the kubelet server have a maximum duration of 4 hours.")
   434  	fs.DurationVar(&c.NodeStatusUpdateFrequency.Duration, "node-status-update-frequency", c.NodeStatusUpdateFrequency.Duration, "Specifies how often kubelet posts node status to master. Note: be cautious when changing the constant, it must work with nodeMonitorGracePeriod in nodecontroller.")
   435  	fs.DurationVar(&c.ImageMinimumGCAge.Duration, "minimum-image-ttl-duration", c.ImageMinimumGCAge.Duration, "Minimum age for an unused image before it is garbage collected.  Examples: '300ms', '10s' or '2h45m'.")
   436  	fs.Int32Var(&c.ImageGCHighThresholdPercent, "image-gc-high-threshold", c.ImageGCHighThresholdPercent, "The percent of disk usage after which image garbage collection is always run. Values must be within the range [0, 100], To disable image garbage collection, set to 100. ")
   437  	fs.Int32Var(&c.ImageGCLowThresholdPercent, "image-gc-low-threshold", c.ImageGCLowThresholdPercent, "The percent of disk usage before which image garbage collection is never run. Lowest disk usage to garbage collect to. Values must be within the range [0, 100] and must be less than that of --image-gc-high-threshold.")
   438  	fs.DurationVar(&c.VolumeStatsAggPeriod.Duration, "volume-stats-agg-period", c.VolumeStatsAggPeriod.Duration, "Specifies interval for kubelet to calculate and cache the volume disk usage for all pods and volumes.  To disable volume calculations, set to a negative number.")
   439  	fs.Var(cliflag.NewMapStringBool(&c.FeatureGates), "feature-gates", "A set of key=value pairs that describe feature gates for alpha/experimental features. "+
   440  		"Options are:\n"+strings.Join(utilfeature.DefaultFeatureGate.KnownFeatures(), "\n"))
   441  	fs.StringVar(&c.KubeletCgroups, "kubelet-cgroups", c.KubeletCgroups, "Optional absolute name of cgroups to create and run the Kubelet in.")
   442  	fs.StringVar(&c.SystemCgroups, "system-cgroups", c.SystemCgroups, "Optional absolute name of cgroups in which to place all non-kernel processes that are not already inside a cgroup under '/'. Empty for no container. Rolling back the flag requires a reboot.")
   443  
   444  	fs.StringVar(&c.ProviderID, "provider-id", c.ProviderID, "Unique identifier for identifying the node in a machine database, i.e cloudprovider")
   445  
   446  	fs.BoolVar(&c.CgroupsPerQOS, "cgroups-per-qos", c.CgroupsPerQOS, "Enable creation of QoS cgroup hierarchy, if true top level QoS and pod cgroups are created.")
   447  	fs.StringVar(&c.CgroupDriver, "cgroup-driver", c.CgroupDriver, "Driver that the kubelet uses to manipulate cgroups on the host.  Possible values: 'cgroupfs', 'systemd'")
   448  	fs.StringVar(&c.CgroupRoot, "cgroup-root", c.CgroupRoot, "Optional root cgroup to use for pods. This is handled by the container runtime on a best effort basis. Default: '', which means use the container runtime default.")
   449  	fs.StringVar(&c.CPUManagerPolicy, "cpu-manager-policy", c.CPUManagerPolicy, "CPU Manager policy to use. Possible values: 'none', 'static'.")
   450  	fs.Var(cliflag.NewMapStringStringNoSplit(&c.CPUManagerPolicyOptions), "cpu-manager-policy-options", "A set of key=value CPU Manager policy options to use, to fine tune their behaviour. If not supplied, keep the default behaviour.")
   451  	fs.DurationVar(&c.CPUManagerReconcilePeriod.Duration, "cpu-manager-reconcile-period", c.CPUManagerReconcilePeriod.Duration, "<Warning: Alpha feature> CPU Manager reconciliation period. Examples: '10s', or '1m'. If not supplied, defaults to 'NodeStatusUpdateFrequency'")
   452  	fs.Var(cliflag.NewMapStringString(&c.QOSReserved), "qos-reserved", "<Warning: Alpha feature> A set of ResourceName=Percentage (e.g. memory=50%) pairs that describe how pod resource requests are reserved at the QoS level. Currently only memory is supported. Requires the QOSReserved feature gate to be enabled.")
   453  	fs.StringVar(&c.TopologyManagerPolicy, "topology-manager-policy", c.TopologyManagerPolicy, "Topology Manager policy to use. Possible values: 'none', 'best-effort', 'restricted', 'single-numa-node'.")
   454  	fs.DurationVar(&c.RuntimeRequestTimeout.Duration, "runtime-request-timeout", c.RuntimeRequestTimeout.Duration, "Timeout of all runtime requests except long running request - pull, logs, exec and attach. When timeout exceeded, kubelet will cancel the request, throw out an error and retry later.")
   455  	fs.StringVar(&c.HairpinMode, "hairpin-mode", c.HairpinMode, "How should the kubelet setup hairpin NAT. This allows endpoints of a Service to loadbalance back to themselves if they should try to access their own Service. Valid values are \"promiscuous-bridge\", \"hairpin-veth\" and \"none\".")
   456  	fs.Int32Var(&c.MaxPods, "max-pods", c.MaxPods, "Number of Pods that can run on this Kubelet.")
   457  
   458  	fs.StringVar(&c.PodCIDR, "pod-cidr", c.PodCIDR, "The CIDR to use for pod IP addresses, only used in standalone mode.  In cluster mode, this is obtained from the master. For IPv6, the maximum number of IP's allocated is 65536")
   459  	fs.Int64Var(&c.PodPidsLimit, "pod-max-pids", c.PodPidsLimit, "Set the maximum number of processes per pod.  If -1, the kubelet defaults to the node allocatable pid capacity.")
   460  
   461  	fs.StringVar(&c.ResolverConfig, "resolv-conf", c.ResolverConfig, "Resolver configuration file used as the basis for the container DNS resolution configuration.")
   462  
   463  	fs.BoolVar(&c.RunOnce, "runonce", c.RunOnce, "If true, exit after spawning pods from static pod files or remote urls. Exclusive with --enable-server")
   464  
   465  	fs.BoolVar(&c.CPUCFSQuota, "cpu-cfs-quota", c.CPUCFSQuota, "Enable CPU CFS quota enforcement for containers that specify CPU limits")
   466  	fs.DurationVar(&c.CPUCFSQuotaPeriod.Duration, "cpu-cfs-quota-period", c.CPUCFSQuotaPeriod.Duration, "Sets CPU CFS quota period value, cpu.cfs_period_us, defaults to Linux Kernel default")
   467  	fs.BoolVar(&c.EnableControllerAttachDetach, "enable-controller-attach-detach", c.EnableControllerAttachDetach, "Enables the Attach/Detach controller to manage attachment/detachment of volumes scheduled to this node, and disables kubelet from executing any attach/detach operations")
   468  	fs.BoolVar(&c.MakeIPTablesUtilChains, "make-iptables-util-chains", c.MakeIPTablesUtilChains, "If true, kubelet will ensure iptables utility rules are present on host.")
   469  	fs.StringVar(&c.ContainerLogMaxSize, "container-log-max-size", c.ContainerLogMaxSize, "<Warning: Beta feature> Set the maximum size (e.g. 10Mi) of container log file before it is rotated.")
   470  	fs.Int32Var(&c.ContainerLogMaxFiles, "container-log-max-files", c.ContainerLogMaxFiles, "<Warning: Beta feature> Set the maximum number of container log files that can be present for a container. The number must be >= 2.")
   471  	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.")
   472  
   473  	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.")
   474  	fs.BoolVar(&c.KernelMemcgNotification, "kernel-memcg-notification", c.KernelMemcgNotification, "If enabled, the kubelet will integrate with the kernel memcg notification to determine if memory eviction thresholds are crossed rather than polling.")
   475  	fs.BoolVar(&c.LocalStorageCapacityIsolation, "local-storage-capacity-isolation", c.LocalStorageCapacityIsolation, "If true, local ephemeral storage isolation is enabled. Otherwise, local storage isolation feature will be disabled")
   476  
   477  	// Flags intended for testing, not recommended used in production environments.
   478  	fs.Int64Var(&c.MaxOpenFiles, "max-open-files", c.MaxOpenFiles, "Number of files that can be opened by Kubelet process.")
   479  
   480  	fs.StringVar(&c.ContentType, "kube-api-content-type", c.ContentType, "Content type of requests sent to apiserver.")
   481  	fs.Int32Var(&c.KubeAPIQPS, "kube-api-qps", c.KubeAPIQPS, "QPS to use while talking with kubernetes apiserver. The number must be >= 0. If 0 will use DefaultQPS: 50. Doesn't cover events and node heartbeat apis which rate limiting is controlled by a different set of flags")
   482  	fs.Int32Var(&c.KubeAPIBurst, "kube-api-burst", c.KubeAPIBurst, "Burst to use while talking with kubernetes apiserver. The number must be >= 0. If 0 will use DefaultBurst: 100. Doesn't cover events and node heartbeat apis which rate limiting is controlled by a different set of flags")
   483  	fs.BoolVar(&c.SerializeImagePulls, "serialize-image-pulls", c.SerializeImagePulls, "Pull images one at a time. We recommend *not* changing the default value on nodes that run docker daemon with version < 1.9 or an Aufs storage backend. Issue #10959 has more details.")
   484  
   485  	fs.Var(cliflag.NewLangleSeparatedMapStringString(&c.EvictionHard), "eviction-hard", "A set of eviction thresholds (e.g. memory.available<1Gi) that if met would trigger a pod eviction.")
   486  	fs.Var(cliflag.NewLangleSeparatedMapStringString(&c.EvictionSoft), "eviction-soft", "A set of eviction thresholds (e.g. memory.available<1.5Gi) that if met over a corresponding grace period would trigger a pod eviction.")
   487  	fs.Var(cliflag.NewMapStringString(&c.EvictionSoftGracePeriod), "eviction-soft-grace-period", "A set of eviction grace periods (e.g. memory.available=1m30s) that correspond to how long a soft eviction threshold must hold before triggering a pod eviction.")
   488  	fs.DurationVar(&c.EvictionPressureTransitionPeriod.Duration, "eviction-pressure-transition-period", c.EvictionPressureTransitionPeriod.Duration, "Duration for which the kubelet has to wait before transitioning out of an eviction pressure condition.")
   489  	fs.Int32Var(&c.EvictionMaxPodGracePeriod, "eviction-max-pod-grace-period", c.EvictionMaxPodGracePeriod, "Maximum allowed grace period (in seconds) to use when terminating pods in response to a soft eviction threshold being met.  If negative, defer to pod specified value.")
   490  	fs.Var(cliflag.NewMapStringString(&c.EvictionMinimumReclaim), "eviction-minimum-reclaim", "A set of minimum reclaims (e.g. imagefs.available=2Gi) that describes the minimum amount of resource the kubelet will reclaim when performing a pod eviction if that resource is under pressure.")
   491  	fs.Int32Var(&c.PodsPerCore, "pods-per-core", c.PodsPerCore, "Number of Pods per core that can run on this Kubelet. The total number of Pods on this Kubelet cannot exceed max-pods, so max-pods will be used if this calculation results in a larger number of Pods allowed on the Kubelet. A value of 0 disables this limit.")
   492  	fs.BoolVar(&c.ProtectKernelDefaults, "protect-kernel-defaults", c.ProtectKernelDefaults, "Default kubelet behaviour for kernel tuning. If set, kubelet errors if any of kernel tunables is different than kubelet defaults.")
   493  	fs.StringVar(&c.ReservedSystemCPUs, "reserved-cpus", c.ReservedSystemCPUs, "A comma-separated list of CPUs or CPU ranges that are reserved for system and kubernetes usage. This specific list will supersede cpu counts in --system-reserved and --kube-reserved.")
   494  	fs.StringVar(&c.TopologyManagerScope, "topology-manager-scope", c.TopologyManagerScope, "Scope to which topology hints applied. Topology Manager collects hints from Hint Providers and applies them to defined scope to ensure the pod admission. Possible values: 'container', 'pod'.")
   495  	fs.Var(cliflag.NewMapStringStringNoSplit(&c.TopologyManagerPolicyOptions), "topology-manager-policy-options", "A set of key=value Topology Manager policy options to use, to fine tune their behaviour. If not supplied, keep the default behaviour.")
   496  	// Node Allocatable Flags
   497  	fs.Var(cliflag.NewMapStringString(&c.SystemReserved), "system-reserved", "A set of ResourceName=ResourceQuantity (e.g. cpu=200m,memory=500Mi,ephemeral-storage=1Gi,pid=1000) pairs that describe resources reserved for non-kubernetes components. Currently only cpu, memory, pid and local ephemeral storage for root file system are supported. See https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ for more detail. [default=none]")
   498  	fs.Var(cliflag.NewMapStringString(&c.KubeReserved), "kube-reserved", "A set of ResourceName=ResourceQuantity (e.g. cpu=200m,memory=500Mi,ephemeral-storage=1Gi,pid=1000) pairs that describe resources reserved for kubernetes system components. Currently only cpu, memory, pid and local ephemeral storage for root file system are supported. See https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ for more detail. [default=none]")
   499  	fs.StringSliceVar(&c.EnforceNodeAllocatable, "enforce-node-allocatable", c.EnforceNodeAllocatable, "A comma separated list of levels of node allocatable enforcement to be enforced by kubelet. Acceptable options are 'none', 'pods', 'system-reserved', and 'kube-reserved'. If the latter two options are specified, '--system-reserved-cgroup' and '--kube-reserved-cgroup' must also be set, respectively. If 'none' is specified, no additional options should be set. See https://kubernetes.io/docs/tasks/administer-cluster/reserve-compute-resources/ for more details.")
   500  	fs.StringVar(&c.SystemReservedCgroup, "system-reserved-cgroup", c.SystemReservedCgroup, "Absolute name of the top level cgroup that is used to manage non-kubernetes components for which compute resources were reserved via '--system-reserved' flag. Ex. '/system-reserved'. [default='']")
   501  	fs.StringVar(&c.KubeReservedCgroup, "kube-reserved-cgroup", c.KubeReservedCgroup, "Absolute name of the top level cgroup that is used to manage kubernetes components for which compute resources were reserved via '--kube-reserved' flag. Ex. '/kube-reserved'. [default='']")
   502  	logsapi.AddFlags(&c.Logging, fs)
   503  
   504  	// Memory Manager Flags
   505  	fs.StringVar(&c.MemoryManagerPolicy, "memory-manager-policy", c.MemoryManagerPolicy, "Memory Manager policy to use. Possible values: 'None', 'Static'.")
   506  	fs.Var(&utilflag.ReservedMemoryVar{Value: &c.ReservedMemory}, "reserved-memory", "A comma separated list of memory reservations for NUMA nodes. (e.g. --reserved-memory 0:memory=1Gi,hugepages-1M=2Gi --reserved-memory 1:memory=2Gi). The total sum for each memory type should be equal to the sum of kube-reserved, system-reserved and eviction-threshold. See https://kubernetes.io/docs/tasks/administer-cluster/memory-manager/#reserved-memory-flag for more details.")
   507  
   508  	fs.BoolVar(&c.RegisterNode, "register-node", c.RegisterNode, "Register the node with the apiserver. If --kubeconfig is not provided, this flag is irrelevant, as the Kubelet won't have an apiserver to register with.")
   509  
   510  	fs.Var(&utilflag.RegisterWithTaintsVar{Value: &c.RegisterWithTaints}, "register-with-taints", "Register the node with the given list of taints (comma separated \"<key>=<value>:<effect>\"). No-op if register-node is false.")
   511  }