Change:
This will be the end of the deprecation period for --require-kubeconfig.
There are no sig labels on this issue. Please by:<br(1) mentioning a sig: <br(2) specifying the label manually: <br<brNote: method (1) will trigger a notification to the team. You can find the team list .
ref
Issues go stale after 90d of inactivity. Mark the issue as fresh with . Stale issues rot after an additional 30d of inactivity and eventually close. Prevent issues from auto-closing with an comment. If this issue is safe to close now please do so with . Send feedback to sig-testing, kubernetes/test-infra and/or . /lifecycle stale

Discussion:
// In general, please try to avoid adding flags or configuration fields, // we already have a confusingly large amount of them. type KubeletFlags struct { <del> KubeConfig          flag.StringFlag </del> <ins> KubeConfig          string </ins> BootstrapKubeconfig string RotateCertificates  bool

// schedulable. Won't have any effect if register-node is false. // DEPRECATED: use registerWithTaints instead RegisterSchedulable bool <del> // RequireKubeConfig is deprecated! A valid KubeConfig is now required if --kubeconfig is provided. RequireKubeConfig bool </del> // nonMasqueradeCIDR configures masquerading: traffic to IPs outside this range will use IP masquerade. NonMasqueradeCIDR string // This flag, if set, instructs the kubelet to keep volumes from terminated pods mounted to the node.

} return &KubeletFlags{ <del> // TODO(#41161:v1.10.0): Remove the default kubeconfig path and --require-kubeconfig. RequireKubeConfig:                   false, KubeConfig:                          flag.NewStringFlag("/var/lib/kubelet/kubeconfig"), </del> ContainerRuntimeOptions:             *NewContainerRuntimeOptions(), CertDirectory:                       "/var/lib/kubelet/pki", RootDirectory:                       v1alpha1.DefaultRootDir,

func (f *KubeletFlags) AddFlags(fs *pflag.FlagSet) { f.ContainerRuntimeOptions.AddFlags(fs) <del> fs.Var(&f.KubeConfig, "kubeconfig", "Path to a kubeconfig file, specifying how to connect to the API server.") // TODO(#41161:v1.10.0): Remove the default kubeconfig path and --require-kubeconfig. fs.BoolVar(&f.RequireKubeConfig, "require-kubeconfig", f.RequireKubeConfig, "This flag is no longer necessary. It has been deprecated and will be removed in a future version.") fs.MarkDeprecated("require-kubeconfig", "You no longer need to use --require-kubeconfig. This will be removed in a future version. Providing --kubeconfig enables API server mode, omitting --kubeconfig enables standalone mode unless --require-kubeconfig=true is also set. In the latter case, the legacy default kubeconfig path will be used until --require-kubeconfig is removed.") </del> <ins> 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.") </ins> fs.MarkDeprecated("experimental-bootstrap-kubeconfig", "Use --bootstrap-kubeconfig") fs.StringVar(&f.BootstrapKubeconfig, "experimental-bootstrap-kubeconfig", f.BootstrapKubeconfig, "deprecated: use --bootstrap-kubeconfig") <ins> // TODO: when pull-kubernetes-e2e-kops-aws does not need this parameter, delete requireKubeConfig. var requireKubeConfig bool fs.BoolVar(&requireKubeConfig, "require-kubeconfig", requireKubeConfig, "This flag is no longer necessary. It has been deprecated and will be removed in a future version.") fs.MarkDeprecated("require-kubeconfig", "You no longer need to use --require-kubeconfig. This will be removed in a future version. Providing --kubeconfig enables API server mode, omitting --kubeconfig enables standalone mode unless --require-kubeconfig=true is also set. In the latter case, the legacy default kubeconfig path will be used until --require-kubeconfig is removed.") </ins> fs.StringVar(&f.BootstrapKubeconfig, "bootstrap-kubeconfig", f.BootstrapKubeconfig, "Path to a kubeconfig file that will be used to get client certificate for kubelet. "+ "If the file specified by --kubeconfig does not exist, the bootstrap kubeconfig is used to request a client certificate from the API server. "+ "On success, a kubeconfig file referencing the generated client certificate and key is written to the path specified by --kubeconfig. "+

} func cleanFlags(s *KubeletServer) { <del> s.KubeConfig = utilflag.NewStringFlag(s.KubeConfig.Value()) </del> s.DynamicConfigDir = utilflag.NewStringFlag(s.DynamicConfigDir.Value()) s.KubeletConfigFile = utilflag.NewStringFlag(s.KubeletConfigFile.Value()) }

// About to get clients and such, detect standaloneMode standaloneMode := true <del> switch { case s.RequireKubeConfig == true: standaloneMode = false glog.Warningf("--require-kubeconfig is deprecated. Set --kubeconfig without using --require-kubeconfig.") case s.KubeConfig.Provided(): </del> <ins> if len(s.KubeConfig) > 0 { </ins> standaloneMode = false }

} if s.BootstrapKubeconfig != "" { <del> if err := bootstrap.LoadClientCert(s.KubeConfig.Value(), s.BootstrapKubeconfig, s.CertDirectory, nodeName); err != nil { </del> <ins> if err := bootstrap.LoadClientCert(s.KubeConfig, s.BootstrapKubeconfig, s.CertDirectory, nodeName); err != nil { </ins> return err } }

var externalKubeClient clientset.Interface clientConfig, err := createAPIServerClientConfig(s) <ins> if err != nil { return fmt.Errorf("invalid kubeconfig: %v", err) } </ins> var clientCertificateManager certificate.Manager <del> if err == nil { if s.RotateCertificates && utilfeature.DefaultFeatureGate.Enabled(features.RotateKubeletClientCertificate) { clientCertificateManager, err = kubeletcertificate.NewKubeletClientCertificateManager(s.CertDirectory, nodeName, clientConfig.CertData, clientConfig.KeyData, clientConfig.CertFile, clientConfig.KeyFile) if err != nil { return err } // we set exitIfExpired to true because we use this client configuration to request new certs - if we are unable // to request new certs, we will be unable to continue normal operation if err := kubeletcertificate.UpdateTransport(wait.NeverStop, clientConfig, clientCertificateManager, true); err != nil { return err } } kubeClient, err = clientset.NewForConfig(clientConfig) </del> <ins> if s.RotateCertificates && utilfeature.DefaultFeatureGate.Enabled(features.RotateKubeletClientCertificate) { clientCertificateManager, err = kubeletcertificate.NewKubeletClientCertificateManager(s.CertDirectory, nodeName, clientConfig.CertData, clientConfig.KeyData, clientConfig.CertFile, clientConfig.KeyFile) </ins> if err != nil { <del> glog.Warningf("New kubeClient from clientConfig error: %v", err) } else if kubeClient.CertificatesV1beta1() != nil && clientCertificateManager != nil { glog.V(2).Info("Starting client certificate rotation.") clientCertificateManager.SetCertificateSigningRequestClient(kubeClient.CertificatesV1beta1().CertificateSigningRequests()) clientCertificateManager.Start() </del> <ins> return err </ins> } <del> externalKubeClient, err = clientset.NewForConfig(clientConfig) if err != nil { glog.Warningf("New kubeClient from clientConfig error: %v", err) </del> <ins> // we set exitIfExpired to true because we use this client configuration to request new certs - if we are unable // to request new certs, we will be unable to continue normal operation if err := kubeletcertificate.UpdateTransport(wait.NeverStop, clientConfig, clientCertificateManager, true); err != nil { return err </ins> } <ins> } </ins> <del> // make a separate client for events eventClientConfig := *clientConfig eventClientConfig.QPS = float32(s.EventRecordQPS) eventClientConfig.Burst = int(s.EventBurst) eventClient, err = v1core.NewForConfig(&eventClientConfig) if err != nil { glog.Warningf("Failed to create API Server client for Events: %v", err) } </del> <ins> kubeClient, err = clientset.NewForConfig(clientConfig) if err != nil { glog.Warningf("New kubeClient from clientConfig error: %v", err) } else if kubeClient.CertificatesV1beta1() != nil && clientCertificateManager != nil { glog.V(2).Info("Starting client certificate rotation.") clientCertificateManager.SetCertificateSigningRequestClient(kubeClient.CertificatesV1beta1().CertificateSigningRequests()) clientCertificateManager.Start() } externalKubeClient, err = clientset.NewForConfig(clientConfig) if err != nil { glog.Warningf("New kubeClient from clientConfig error: %v", err) } </ins> <del> // make a separate client for heartbeat with throttling disabled and a timeout attached heartbeatClientConfig := *clientConfig heartbeatClientConfig.Timeout = s.KubeletConfiguration.NodeStatusUpdateFrequency.Duration heartbeatClientConfig.QPS = float32(-1) heartbeatClient, err = v1core.NewForConfig(&heartbeatClientConfig) if err != nil { glog.Warningf("Failed to create API Server client for heartbeat: %v", err) } } else { switch { case s.RequireKubeConfig: return fmt.Errorf("invalid kubeconfig: %v", err) case s.KubeConfig.Provided(): glog.Warningf("invalid kubeconfig: %v", err) } </del> <ins> // make a separate client for events eventClientConfig := *clientConfig eventClientConfig.QPS = float32(s.EventRecordQPS) eventClientConfig.Burst = int(s.EventBurst) eventClient, err = v1core.NewForConfig(&eventClientConfig) if err != nil { glog.Warningf("Failed to create API Server client for Events: %v", err) } // make a separate client for heartbeat with throttling disabled and a timeout attached heartbeatClientConfig := *clientConfig heartbeatClientConfig.Timeout = s.KubeletConfiguration.NodeStatusUpdateFrequency.Duration heartbeatClientConfig.QPS = float32(-1) heartbeatClient, err = v1core.NewForConfig(&heartbeatClientConfig) if err != nil { glog.Warningf("Failed to create API Server client for heartbeat: %v", err) </ins> } kubeDeps.KubeClient = kubeClient

func kubeconfigClientConfig(s *options.KubeletServer) (*restclient.Config, error) { return clientcmd.NewNonInteractiveDeferredLoadingClientConfig( <del> &clientcmd.ClientConfigLoadingRules{ExplicitPath: s.KubeConfig.Value()}, </del> <ins> &clientcmd.ClientConfigLoadingRules{ExplicitPath: s.KubeConfig}, </ins> &clientcmd.ConfigOverrides{}, ).ClientConfig() } // createClientConfig creates a client configuration from the command line arguments. <del> // If --kubeconfig is explicitly set, it will be used. If it is not set but // --require-kubeconfig=true, we attempt to load the default kubeconfig file. </del> <ins> // If --kubeconfig is explicitly set, it will be used. </ins> func createClientConfig(s *options.KubeletServer) (*restclient.Config, error) { <del> // If --kubeconfig was not provided, it will have a default path set in cmd/kubelet/app/options/options.go. // We only use that default path when --require-kubeconfig=true. The default path is temporary until --require-kubeconfig is removed. // TODO(#41161:v1.10.0): Remove the default kubeconfig path and --require-kubeconfig. if s.BootstrapKubeconfig != "" || s.KubeConfig.Provided() || s.RequireKubeConfig == true { </del> <ins> if s.BootstrapKubeconfig != "" || len(s.KubeConfig) > 0 { </ins> return kubeconfigClientConfig(s) } else { return nil, fmt.Errorf("createClientConfig called in standalone mode")