Merge pull request #58405 from deads2k/kubelet-01-start

Automatic merge from submit-queue (batch tested with PRs 58209, 57561, 58405). If you want to cherry-pick this change to another branch, please follow the instructions <a href="https://github.com/kubernetes/community/blob/master/contributors/devel/cherry-picks.md">here</a>.

make the kubelet cobra command complete

This pull attempts a move from the cmd/kubelet to the cobra command where it can re-used.

/assign @mtaufen 
/assign @liggitt 
@ncdc fyi

xref: https://github.com/kubernetes/kubernetes/issues/34732

```release-note
NONE
```
This commit is contained in:
Kubernetes Submit Queue 2018-01-18 10:27:39 -08:00 committed by GitHub
commit 7f6dae7235
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 63 additions and 100 deletions

View File

@ -20,14 +20,8 @@ go_library(
importpath = "k8s.io/kubernetes/cmd/kubelet",
deps = [
"//cmd/kubelet/app:go_default_library",
"//cmd/kubelet/app/options:go_default_library",
"//pkg/client/metrics/prometheus:go_default_library",
"//pkg/version/prometheus:go_default_library",
"//pkg/version/verflag:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/github.com/spf13/pflag:go_default_library",
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//vendor/k8s.io/apiserver/pkg/util/flag:go_default_library",
"//vendor/k8s.io/apiserver/pkg/util/logs:go_default_library",
],
)

View File

@ -99,6 +99,7 @@ go_library(
"//pkg/util/oom:go_default_library",
"//pkg/util/rlimit:go_default_library",
"//pkg/version:go_default_library",
"//pkg/version/verflag:go_default_library",
"//pkg/volume:go_default_library",
"//pkg/volume/aws_ebs:go_default_library",
"//pkg/volume/azure_dd:go_default_library",
@ -130,7 +131,6 @@ go_library(
"//pkg/volume/vsphere_volume:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/github.com/spf13/cobra:go_default_library",
"//vendor/github.com/spf13/pflag:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/resource:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",

View File

@ -34,7 +34,6 @@ import (
"github.com/golang/glog"
"github.com/spf13/cobra"
"github.com/spf13/pflag"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
@ -87,6 +86,7 @@ import (
"k8s.io/kubernetes/pkg/util/oom"
"k8s.io/kubernetes/pkg/util/rlimit"
"k8s.io/kubernetes/pkg/version"
"k8s.io/kubernetes/pkg/version/verflag"
)
const (
@ -96,9 +96,13 @@ const (
// NewKubeletCommand creates a *cobra.Command object with default parameters
func NewKubeletCommand() *cobra.Command {
// ignore the error, as this is just for generating docs and the like
s, _ := options.NewKubeletServer()
s.AddFlags(pflag.CommandLine)
kubeletFlags := options.NewKubeletFlags()
kubeletConfiguration, err := options.NewKubeletConfiguration()
// programmer error
if err != nil {
glog.Fatal(err)
}
cmd := &cobra.Command{
Use: componentKubelet,
Long: `The kubelet is the primary "node agent" that runs on each
@ -121,9 +125,59 @@ is checked every 20 seconds (also configurable with a flag).
HTTP server: The kubelet can also listen for HTTP and respond to a simple API
(underspec'd currently) to submit a new manifest.`,
Run: func(cmd *cobra.Command, args []string) {
// short-circuit on verflag
verflag.PrintAndExitIfRequested()
// TODO(mtaufen): won't need this this once dynamic config is GA
// set feature gates so we can check if dynamic config is enabled
if err := utilfeature.DefaultFeatureGate.SetFromMap(kubeletConfiguration.FeatureGates); err != nil {
glog.Fatal(err)
}
// validate the initial KubeletFlags, to make sure the dynamic-config-related flags aren't used unless the feature gate is on
if err := options.ValidateKubeletFlags(kubeletFlags); err != nil {
glog.Fatal(err)
}
// bootstrap the kubelet config controller, app.BootstrapKubeletConfigController will check
// feature gates and only turn on relevant parts of the controller
kubeletConfig, kubeletConfigController, err := BootstrapKubeletConfigController(
kubeletConfiguration, kubeletFlags.KubeletConfigFile, kubeletFlags.DynamicConfigDir)
if err != nil {
glog.Fatal(err)
}
// construct a KubeletServer from kubeletFlags and kubeletConfig
kubeletServer := &options.KubeletServer{
KubeletFlags: *kubeletFlags,
KubeletConfiguration: *kubeletConfig,
}
// use kubeletServer to construct the default KubeletDeps
kubeletDeps, err := UnsecuredDependencies(kubeletServer)
if err != nil {
glog.Fatal(err)
}
// add the kubelet config controller to kubeletDeps
kubeletDeps.KubeletConfigController = kubeletConfigController
// start the experimental docker shim, if enabled
if kubeletServer.KubeletFlags.ExperimentalDockershim {
if err := RunDockershim(&kubeletServer.KubeletFlags, kubeletConfig); err != nil {
glog.Fatal(err)
}
}
// run the kubelet
if err := Run(kubeletServer, kubeletDeps); err != nil {
glog.Fatal(err)
}
},
}
kubeletFlags.AddFlags(cmd.Flags())
options.AddKubeletConfigFlags(cmd.Flags(), kubeletConfiguration)
options.AddGlobalFlags(cmd.Flags())
return cmd
}

View File

@ -26,107 +26,22 @@ import (
"os"
"time"
"github.com/golang/glog"
"github.com/spf13/pflag"
utilfeature "k8s.io/apiserver/pkg/util/feature"
"k8s.io/apiserver/pkg/util/flag"
"k8s.io/apiserver/pkg/util/logs"
"k8s.io/kubernetes/cmd/kubelet/app"
"k8s.io/kubernetes/cmd/kubelet/app/options"
_ "k8s.io/kubernetes/pkg/client/metrics/prometheus" // for client metric registration
_ "k8s.io/kubernetes/pkg/version/prometheus" // for version metric registration
"k8s.io/kubernetes/pkg/version/verflag"
)
func parseFlagSet(fs *pflag.FlagSet, args []string) error {
if err := fs.Parse(args); err != nil {
return err
}
fs.VisitAll(func(flag *pflag.Flag) {
glog.V(2).Infof("FLAG: --%s=%q", flag.Name, flag.Value)
})
return nil
}
func die(err error) {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
os.Exit(1)
}
func main() {
rand.Seed(time.Now().UTC().UnixNano())
fs := pflag.NewFlagSet(os.Args[0], pflag.ExitOnError)
// set the normalize func, similar to k8s.io/apiserver/pkg/util/flag/flags.go:InitFlags
fs.SetNormalizeFunc(flag.WordSepNormalizeFunc)
// explicitly add flags from libs that register global flags
options.AddGlobalFlags(fs)
command := app.NewKubeletCommand()
// register kubelet flags
kubeletFlags := options.NewKubeletFlags()
kubeletFlags.AddFlags(fs)
// register kubelet config flags
defaultConfig, err := options.NewKubeletConfiguration()
if err != nil {
die(err)
}
options.AddKubeletConfigFlags(fs, defaultConfig)
// parse flags
if err := parseFlagSet(fs, os.Args[1:]); err != nil {
die(err)
}
// initialize logging and defer flush
logs.InitLogs()
defer logs.FlushLogs()
// short-circuit on verflag
verflag.PrintAndExitIfRequested()
// TODO(mtaufen): won't need this this once dynamic config is GA
// set feature gates so we can check if dynamic config is enabled
if err := utilfeature.DefaultFeatureGate.SetFromMap(defaultConfig.FeatureGates); err != nil {
die(err)
}
// validate the initial KubeletFlags, to make sure the dynamic-config-related flags aren't used unless the feature gate is on
if err := options.ValidateKubeletFlags(kubeletFlags); err != nil {
die(err)
}
// bootstrap the kubelet config controller, app.BootstrapKubeletConfigController will check
// feature gates and only turn on relevant parts of the controller
kubeletConfig, kubeletConfigController, err := app.BootstrapKubeletConfigController(
defaultConfig, kubeletFlags.KubeletConfigFile, kubeletFlags.DynamicConfigDir)
if err != nil {
die(err)
}
// construct a KubeletServer from kubeletFlags and kubeletConfig
kubeletServer := &options.KubeletServer{
KubeletFlags: *kubeletFlags,
KubeletConfiguration: *kubeletConfig,
}
// use kubeletServer to construct the default KubeletDeps
kubeletDeps, err := app.UnsecuredDependencies(kubeletServer)
if err != nil {
die(err)
}
// add the kubelet config controller to kubeletDeps
kubeletDeps.KubeletConfigController = kubeletConfigController
// start the experimental docker shim, if enabled
if kubeletFlags.ExperimentalDockershim {
if err := app.RunDockershim(kubeletFlags, kubeletConfig); err != nil {
die(err)
}
}
// run the kubelet
if err := app.Run(kubeletServer, kubeletDeps); err != nil {
die(err)
if err := command.Execute(); err != nil {
fmt.Fprintf(os.Stderr, "%v\n", err)
os.Exit(1)
}
}