Merge pull request #104774 from kerthcet/bug/fix-kubelet-log-defer-conflict-with-exit

fix kubelet flushlogs not working together with exit
This commit is contained in:
Kubernetes Prow Robot 2022-01-06 10:40:32 -08:00 committed by GitHub
commit b1c204a237
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -115,6 +115,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 {
@ -151,31 +152,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: %w", 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
@ -183,14 +178,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: %w", 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: %w", err)
}
if kubeletFlags.ContainerRuntime == "remote" && cleanFlagSet.Changed("pod-infra-container-image") {
@ -201,28 +194,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: %w, 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: %w", 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: %w", 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: %w, path: %s", err, kubeletConfig)
}
if (kubeletConfig.KubeletCgroups != "" && kubeletConfig.KubeReservedCgroup != "") && (strings.Index(kubeletConfig.KubeletCgroups, kubeletConfig.KubeReservedCgroup) != 0) {
@ -242,8 +231,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: %w, dynamicConfigDir: %s", err, dynamicConfigDir)
}
// If we should just use our existing, local config, the controller will return a nil config
if dynamicKubeletConfig != nil {
@ -251,8 +239,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: %w", err)
}
}
}
@ -275,8 +262,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: %w", err)
}
// add the kubelet config controller to kubeletDeps
@ -297,10 +283,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)
},
}