diff --git a/cmd/kubelet/app/server.go b/cmd/kubelet/app/server.go index 5648659699e..55e026ad3cd 100644 --- a/cmd/kubelet/app/server.go +++ b/cmd/kubelet/app/server.go @@ -116,6 +116,7 @@ func NewKubeletCommand() *cobra.Command { cleanFlagSet := pflag.NewFlagSet(componentKubelet, pflag.ContinueOnError) cleanFlagSet.SetNormalizeFunc(cliflag.WordSepNormalizeFunc) kubeletFlags := options.NewKubeletFlags() + kubeletConfig, err := options.NewKubeletConfiguration() // programmer error if err != nil { @@ -152,31 +153,25 @@ HTTP server: The kubelet can also listen for HTTP and respond to a simple API // DisableFlagParsing=true provides the full set of flags passed to the kubelet in the // `args` arg to Run, without Cobra's interference. DisableFlagParsing: true, - Run: func(cmd *cobra.Command, args []string) { + RunE: func(cmd *cobra.Command, args []string) error { // initial flag parse, since we disable cobra's flag parsing if err := cleanFlagSet.Parse(args); err != nil { - klog.ErrorS(err, "Failed to parse kubelet flag") - cmd.Usage() - os.Exit(1) + return fmt.Errorf("failed to parse kubelet flag: %v", err) } // check if there are non-flag arguments in the command line cmds := cleanFlagSet.Args() if len(cmds) > 0 { - klog.ErrorS(nil, "Unknown command", "command", cmds[0]) - cmd.Usage() - os.Exit(1) + return fmt.Errorf("unknown command %+s", cmds[0]) } // short-circuit on help help, err := cleanFlagSet.GetBool("help") if err != nil { - klog.InfoS(`"help" flag is non-bool, programmer error, please correct`) - os.Exit(1) + return errors.New(`"help" flag is non-bool, programmer error, please correct`) } if help { - cmd.Help() - return + return cmd.Help() } // short-circuit on verflag @@ -185,14 +180,12 @@ HTTP server: The kubelet can also listen for HTTP and respond to a simple API // set feature gates from initial flags-based config if err := utilfeature.DefaultMutableFeatureGate.SetFromMap(kubeletConfig.FeatureGates); err != nil { - klog.ErrorS(err, "Failed to set feature gates from initial flags-based config") - os.Exit(1) + return fmt.Errorf("failed to set feature gates from initial flags-based config: %v", err) } // validate the initial KubeletFlags if err := options.ValidateKubeletFlags(kubeletFlags); err != nil { - klog.ErrorS(err, "Failed to validate kubelet flags") - os.Exit(1) + return fmt.Errorf("failed to validate kubelet flags: %v", err) } if kubeletFlags.ContainerRuntime == "remote" && cleanFlagSet.Changed("pod-infra-container-image") { @@ -203,28 +196,24 @@ HTTP server: The kubelet can also listen for HTTP and respond to a simple API if configFile := kubeletFlags.KubeletConfigFile; len(configFile) > 0 { kubeletConfig, err = loadConfigFile(configFile) if err != nil { - klog.ErrorS(err, "Failed to load kubelet config file", "path", configFile) - os.Exit(1) + return fmt.Errorf("failed to load kubelet config file, error: %v, path: %s", err, configFile) } // We must enforce flag precedence by re-parsing the command line into the new object. // This is necessary to preserve backwards-compatibility across binary upgrades. // See issue #56171 for more details. if err := kubeletConfigFlagPrecedence(kubeletConfig, args); err != nil { - klog.ErrorS(err, "Failed to precedence kubeletConfigFlag") - os.Exit(1) + return fmt.Errorf("failed to precedence kubeletConfigFlag: %v", err) } // update feature gates based on new config if err := utilfeature.DefaultMutableFeatureGate.SetFromMap(kubeletConfig.FeatureGates); err != nil { - klog.ErrorS(err, "Failed to set feature gates from initial flags-based config") - os.Exit(1) + return fmt.Errorf("failed to set feature gates from initial flags-based config: %v", err) } } // We always validate the local configuration (command line + config file). // This is the default "last-known-good" config for dynamic config, and must always remain valid. if err := kubeletconfigvalidation.ValidateKubeletConfiguration(kubeletConfig); err != nil { - klog.ErrorS(err, "Failed to validate kubelet configuration", "path", kubeletConfig) - os.Exit(1) + return fmt.Errorf("failed to validate kubelet configuration, error: %v, path: %s", err, kubeletConfig) } if (kubeletConfig.KubeletCgroups != "" && kubeletConfig.KubeReservedCgroup != "") && (strings.Index(kubeletConfig.KubeletCgroups, kubeletConfig.KubeReservedCgroup) != 0) { @@ -244,8 +233,7 @@ HTTP server: The kubelet can also listen for HTTP and respond to a simple API return kubeletConfigFlagPrecedence(kc, args) }) if err != nil { - klog.ErrorS(err, "Failed to bootstrap a configuration controller", "dynamicConfigDir", dynamicConfigDir) - os.Exit(1) + return fmt.Errorf("failed to bootstrap a configuration controller, error: %v, dynamicConfigDir: %s", err, dynamicConfigDir) } // If we should just use our existing, local config, the controller will return a nil config if dynamicKubeletConfig != nil { @@ -253,8 +241,7 @@ HTTP server: The kubelet can also listen for HTTP and respond to a simple API // Note: flag precedence was already enforced in the controller, prior to validation, // by our above transform function. Now we simply update feature gates from the new config. if err := utilfeature.DefaultMutableFeatureGate.SetFromMap(kubeletConfig.FeatureGates); err != nil { - klog.ErrorS(err, "Failed to set feature gates from initial flags-based config") - os.Exit(1) + return fmt.Errorf("failed to set feature gates from initial flags-based config: %v", err) } } } @@ -276,8 +263,7 @@ HTTP server: The kubelet can also listen for HTTP and respond to a simple API // use kubeletServer to construct the default KubeletDeps kubeletDeps, err := UnsecuredDependencies(kubeletServer, utilfeature.DefaultFeatureGate) if err != nil { - klog.ErrorS(err, "Failed to construct kubelet dependencies") - os.Exit(1) + return fmt.Errorf("failed to construct kubelet dependencies: %v", err) } // add the kubelet config controller to kubeletDeps @@ -298,10 +284,7 @@ HTTP server: The kubelet can also listen for HTTP and respond to a simple API klog.V(5).InfoS("KubeletConfiguration", "configuration", kubeletServer.KubeletConfiguration) // run the kubelet - if err := Run(ctx, kubeletServer, kubeletDeps, utilfeature.DefaultFeatureGate); err != nil { - klog.ErrorS(err, "Failed to run kubelet") - os.Exit(1) - } + return Run(ctx, kubeletServer, kubeletDeps, utilfeature.DefaultFeatureGate) }, }