kubectl
实际运行的函数(k8s.io/kubernetes/pkg/kubectl/app/kubectl.go
):
func Run() error {
cmd := cmd.NewKubectlCommand(cmdutil.NewFactory(nil), os.Stdin, os.Stdout, os.Stderr)
return cmd.Execute()
}
NewKubectlCommand
的代码(k8s.io/kubernetes/pkg/kubectl/cmd/cmd.go
):
// NewKubectlCommand creates the `kubectl` command and its nested children.
func NewKubectlCommand(f *cmdutil.Factory, in io.Reader, out, err io.Writer) *cobra.Command {
// Parent command to which all subcommands are added.
cmds := &cobra.Command{
Use: "kubectl",
Short: "kubectl controls the Kubernetes cluster manager",
Long: `kubectl controls the Kubernetes cluster manager.
Find more information at https://github.com/kubernetes/kubernetes.`,
Run: runHelp,
BashCompletionFunction: bash_completion_func,
}
f.BindFlags(cmds.PersistentFlags())
// From this point and forward we get warnings on flags that contain "_" separators
cmds.SetGlobalNormalizationFunc(util.WarnWordSepNormalizeFunc)
cmds.AddCommand(NewCmdGet(f, out))
cmds.AddCommand(NewCmdDescribe(f, out))
cmds.AddCommand(NewCmdCreate(f, out))
......
return &cmds
}
所以cmd := cmd.NewKubectlCommand(cmdutil.NewFactory(nil), os.Stdin, os.Stdout, os.Stderr)
得到的cmd
是一个指向cobra.Command
的指针。
cmdutil.NewFactory
代码(k8s.io/kubernetes/pkg/kubectl/cmd/util/factory.go
):
// NewFactory creates a factory with the default Kubernetes resources defined
// if optionalClientConfig is nil, then flags will be bound to a new clientcmd.ClientConfig.
// if optionalClientConfig is not nil, then this factory will make use of it.
func NewFactory(optionalClientConfig clientcmd.ClientConfig) *Factory {
mapper := kubectl.ShortcutExpander{RESTMapper: api.RESTMapper}
flags := pflag.NewFlagSet("", pflag.ContinueOnError)
flags.SetNormalizeFunc(util.WarnWordSepNormalizeFunc) // Warn for "_" flags
generators := map[string]kubectl.Generator{
"run/v1": kubectl.BasicReplicationController{},
"run-pod/v1": kubectl.BasicPod{},
"service/v1": kubectl.ServiceGeneratorV1{},
"service/v2": kubectl.ServiceGeneratorV2{},
"horizontalpodautoscaler/v1beta1": kubectl.HorizontalPodAutoscalerV1Beta1{},
"deployment/v1beta1": kubectl.DeploymentV1Beta1{},
"job/v1beta1": kubectl.JobV1Beta1{},
}
clientConfig := optionalClientConfig
if optionalClientConfig == nil {
clientConfig = DefaultClientConfig(flags)
}
clients := NewClientCache(clientConfig)
return &Factory{
......
}
因为cmdutil.NewFactory(nil)
参数为nil
,所以调用的是DefaultClientConfig
函数。
clientcmd.ClientConfig
定义在k8s.io/kubernetes/pkg/client/unversioned/clientcmd/client_config.go
文件:
// ClientConfig is used to make it easy to get an api server client
type ClientConfig interface {
// RawConfig returns the merged result of all overrides
RawConfig() (clientcmdapi.Config, error)
// ClientConfig returns a complete client config
ClientConfig() (*client.Config, error)
// Namespace returns the namespace resulting from the merged
// result of all overrides and a boolean indicating if it was
// overridden
Namespace() (string, bool, error)
}
DefaultClientConfig
代码(k8s.io/kubernetes/pkg/kubectl/cmd/util/factory.go
):
func DefaultClientConfig(flags *pflag.FlagSet) clientcmd.ClientConfig {
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
flags.StringVar(&loadingRules.ExplicitPath, "kubeconfig", "", "Path to the kubeconfig file to use for CLI requests.")
overrides := &clientcmd.ConfigOverrides{}
flagNames := clientcmd.RecommendedConfigOverrideFlags("")
// short flagnames are disabled by default. These are here for compatibility with existing scripts
flagNames.ClusterOverrideFlags.APIServer.ShortName = "s"
clientcmd.BindOverrideFlags(overrides, flags, flagNames)
clientConfig := clientcmd.NewInteractiveDeferredLoadingClientConfig(loadingRules, overrides, os.Stdin)
return clientConfig
}
最后返回一个DeferredLoadingClientConfig
结构体(定义在k8s.io/kubernetes/pkg/client/unversioned/clientcmd/merged_client_builder.go
):
// DeferredLoadingClientConfig is a ClientConfig interface that is backed by a set of loading rules
// It is used in cases where the loading rules may change after you've instantiated them and you want to be sure that
// the most recent rules are used. This is useful in cases where you bind flags to loading rule parameters before
// the parse happens and you want your calling code to be ignorant of how the values are being mutated to avoid
// passing extraneous information down a call stack
type DeferredLoadingClientConfig struct {
loadingRules *ClientConfigLoadingRules
overrides *ConfigOverrides
fallbackReader io.Reader
}
有疑问加站长微信联系(非本文作者)