mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-31 23:37:01 +00:00
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:
commit
b1c204a237
@ -115,6 +115,7 @@ func NewKubeletCommand() *cobra.Command {
|
|||||||
cleanFlagSet := pflag.NewFlagSet(componentKubelet, pflag.ContinueOnError)
|
cleanFlagSet := pflag.NewFlagSet(componentKubelet, pflag.ContinueOnError)
|
||||||
cleanFlagSet.SetNormalizeFunc(cliflag.WordSepNormalizeFunc)
|
cleanFlagSet.SetNormalizeFunc(cliflag.WordSepNormalizeFunc)
|
||||||
kubeletFlags := options.NewKubeletFlags()
|
kubeletFlags := options.NewKubeletFlags()
|
||||||
|
|
||||||
kubeletConfig, err := options.NewKubeletConfiguration()
|
kubeletConfig, err := options.NewKubeletConfiguration()
|
||||||
// programmer error
|
// programmer error
|
||||||
if err != nil {
|
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
|
// DisableFlagParsing=true provides the full set of flags passed to the kubelet in the
|
||||||
// `args` arg to Run, without Cobra's interference.
|
// `args` arg to Run, without Cobra's interference.
|
||||||
DisableFlagParsing: true,
|
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
|
// initial flag parse, since we disable cobra's flag parsing
|
||||||
if err := cleanFlagSet.Parse(args); err != nil {
|
if err := cleanFlagSet.Parse(args); err != nil {
|
||||||
klog.ErrorS(err, "Failed to parse kubelet flag")
|
return fmt.Errorf("failed to parse kubelet flag: %w", err)
|
||||||
cmd.Usage()
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if there are non-flag arguments in the command line
|
// check if there are non-flag arguments in the command line
|
||||||
cmds := cleanFlagSet.Args()
|
cmds := cleanFlagSet.Args()
|
||||||
if len(cmds) > 0 {
|
if len(cmds) > 0 {
|
||||||
klog.ErrorS(nil, "Unknown command", "command", cmds[0])
|
return fmt.Errorf("unknown command %+s", cmds[0])
|
||||||
cmd.Usage()
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// short-circuit on help
|
// short-circuit on help
|
||||||
help, err := cleanFlagSet.GetBool("help")
|
help, err := cleanFlagSet.GetBool("help")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.InfoS(`"help" flag is non-bool, programmer error, please correct`)
|
return errors.New(`"help" flag is non-bool, programmer error, please correct`)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
if help {
|
if help {
|
||||||
cmd.Help()
|
return cmd.Help()
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// short-circuit on verflag
|
// 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
|
// set feature gates from initial flags-based config
|
||||||
if err := utilfeature.DefaultMutableFeatureGate.SetFromMap(kubeletConfig.FeatureGates); err != nil {
|
if err := utilfeature.DefaultMutableFeatureGate.SetFromMap(kubeletConfig.FeatureGates); err != nil {
|
||||||
klog.ErrorS(err, "Failed to set feature gates from initial flags-based config")
|
return fmt.Errorf("failed to set feature gates from initial flags-based config: %w", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate the initial KubeletFlags
|
// validate the initial KubeletFlags
|
||||||
if err := options.ValidateKubeletFlags(kubeletFlags); err != nil {
|
if err := options.ValidateKubeletFlags(kubeletFlags); err != nil {
|
||||||
klog.ErrorS(err, "Failed to validate kubelet flags")
|
return fmt.Errorf("failed to validate kubelet flags: %w", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if kubeletFlags.ContainerRuntime == "remote" && cleanFlagSet.Changed("pod-infra-container-image") {
|
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 {
|
if configFile := kubeletFlags.KubeletConfigFile; len(configFile) > 0 {
|
||||||
kubeletConfig, err = loadConfigFile(configFile)
|
kubeletConfig, err = loadConfigFile(configFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.ErrorS(err, "Failed to load kubelet config file", "path", configFile)
|
return fmt.Errorf("failed to load kubelet config file, error: %w, path: %s", err, configFile)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
// We must enforce flag precedence by re-parsing the command line into the new object.
|
// 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.
|
// This is necessary to preserve backwards-compatibility across binary upgrades.
|
||||||
// See issue #56171 for more details.
|
// See issue #56171 for more details.
|
||||||
if err := kubeletConfigFlagPrecedence(kubeletConfig, args); err != nil {
|
if err := kubeletConfigFlagPrecedence(kubeletConfig, args); err != nil {
|
||||||
klog.ErrorS(err, "Failed to precedence kubeletConfigFlag")
|
return fmt.Errorf("failed to precedence kubeletConfigFlag: %w", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
// update feature gates based on new config
|
// update feature gates based on new config
|
||||||
if err := utilfeature.DefaultMutableFeatureGate.SetFromMap(kubeletConfig.FeatureGates); err != nil {
|
if err := utilfeature.DefaultMutableFeatureGate.SetFromMap(kubeletConfig.FeatureGates); err != nil {
|
||||||
klog.ErrorS(err, "Failed to set feature gates from initial flags-based config")
|
return fmt.Errorf("failed to set feature gates from initial flags-based config: %w", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// We always validate the local configuration (command line + config file).
|
// 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.
|
// This is the default "last-known-good" config for dynamic config, and must always remain valid.
|
||||||
if err := kubeletconfigvalidation.ValidateKubeletConfiguration(kubeletConfig); err != nil {
|
if err := kubeletconfigvalidation.ValidateKubeletConfiguration(kubeletConfig); err != nil {
|
||||||
klog.ErrorS(err, "Failed to validate kubelet configuration", "path", kubeletConfig)
|
return fmt.Errorf("failed to validate kubelet configuration, error: %w, path: %s", err, kubeletConfig)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kubeletConfig.KubeletCgroups != "" && kubeletConfig.KubeReservedCgroup != "") && (strings.Index(kubeletConfig.KubeletCgroups, kubeletConfig.KubeReservedCgroup) != 0) {
|
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)
|
return kubeletConfigFlagPrecedence(kc, args)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.ErrorS(err, "Failed to bootstrap a configuration controller", "dynamicConfigDir", dynamicConfigDir)
|
return fmt.Errorf("failed to bootstrap a configuration controller, error: %w, dynamicConfigDir: %s", err, dynamicConfigDir)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
// If we should just use our existing, local config, the controller will return a nil config
|
// If we should just use our existing, local config, the controller will return a nil config
|
||||||
if dynamicKubeletConfig != nil {
|
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,
|
// 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.
|
// by our above transform function. Now we simply update feature gates from the new config.
|
||||||
if err := utilfeature.DefaultMutableFeatureGate.SetFromMap(kubeletConfig.FeatureGates); err != nil {
|
if err := utilfeature.DefaultMutableFeatureGate.SetFromMap(kubeletConfig.FeatureGates); err != nil {
|
||||||
klog.ErrorS(err, "Failed to set feature gates from initial flags-based config")
|
return fmt.Errorf("failed to set feature gates from initial flags-based config: %w", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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
|
// use kubeletServer to construct the default KubeletDeps
|
||||||
kubeletDeps, err := UnsecuredDependencies(kubeletServer, utilfeature.DefaultFeatureGate)
|
kubeletDeps, err := UnsecuredDependencies(kubeletServer, utilfeature.DefaultFeatureGate)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
klog.ErrorS(err, "Failed to construct kubelet dependencies")
|
return fmt.Errorf("failed to construct kubelet dependencies: %w", err)
|
||||||
os.Exit(1)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// add the kubelet config controller to kubeletDeps
|
// 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)
|
klog.V(5).InfoS("KubeletConfiguration", "configuration", kubeletServer.KubeletConfiguration)
|
||||||
|
|
||||||
// run the kubelet
|
// run the kubelet
|
||||||
if err := Run(ctx, kubeletServer, kubeletDeps, utilfeature.DefaultFeatureGate); err != nil {
|
return Run(ctx, kubeletServer, kubeletDeps, utilfeature.DefaultFeatureGate)
|
||||||
klog.ErrorS(err, "Failed to run kubelet")
|
|
||||||
os.Exit(1)
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user