Skip to content

KinD (Kubernetes in Docker) コード調査

Kenichi Omichi edited this page Sep 2, 2020 · 4 revisions

kind create cluster実行時の内部処理

Kubernetes 同様、CLIアプリ向けライブラリである Cobra (https://github.com/spf13/cobra) をベースにして作られている。

pkg/cmd/kind/root.go

 44 // NewCommand returns a new cobra.Command implementing the root command for kind
 45 func NewCommand(logger log.Logger, streams cmd.IOStreams) *cobra.Command {
 46         flags := &flagpole{}
 47         cmd := &cobra.Command{      ★ここでベースコマンドである kind を作成
 48                 Args:  cobra.NoArgs,
 49                 Use:   "kind",      ★ベースコマンド kind を登録
 50                 Short: "kind is a tool for managing local Kubernetes clusters",
 51                 Long:  "kind creates and manages local Kubernetes clusters using Docker container 'nodes'"    ,
 52                 PersistentPreRunE: func(cmd *cobra.Command, args []string) error {
 53                         return runE(logger, flags, cmd)
 54                 },
 55                 SilenceUsage:  true,
 56                 SilenceErrors: true,
 57                 Version:       version.Version(),
 58         }
 [..]
 81         // add all top level subcommands
 82         cmd.AddCommand(build.NewCommand(logger, streams))
 83         cmd.AddCommand(completion.NewCommand(logger, streams))
 84         cmd.AddCommand(create.NewCommand(logger, streams))        ★ここでベースコマンド kind に対して create サブコマンドを追加「kind create」
 85         cmd.AddCommand(delete.NewCommand(logger, streams))        ★他のサブコマンドも同様に登録
 86         cmd.AddCommand(export.NewCommand(logger, streams))
 87         cmd.AddCommand(get.NewCommand(logger, streams))
 88         cmd.AddCommand(version.NewCommand(logger, streams))
 89         cmd.AddCommand(load.NewCommand(logger, streams))
 90         return cmd
 91 }

pkg/cmd/kind/create/create.go

 28 // NewCommand returns a new cobra.Command for cluster creation
 29 func NewCommand(logger log.Logger, streams cmd.IOStreams) *cobra.Command {
 30         cmd := &cobra.Command{
 31                 Args:  cobra.NoArgs,
 32                 Use:   "create",     ★サブコマンド create を登録
 33                 Short: "Creates one of [cluster]",
 34                 Long:  "Creates one of local Kubernetes cluster (cluster)",
 35         }
 36         cmd.AddCommand(createcluster.NewCommand(logger, streams))  ★更にサブサブコマンド cluster を登録 「kind create cluster」
 37         return cmd
 38 }

pkg/cmd/kind/create/cluster/createcluster.go

 45 // NewCommand returns a new cobra.Command for cluster creation
 46 func NewCommand(logger log.Logger, streams cmd.IOStreams) *cobra.Command {
 47         flags := &flagpole{}
 48         cmd := &cobra.Command{
 49                 Args:  cobra.NoArgs,
 50                 Use:   "cluster",       ★サブサブコマンド cluster 登録
 51                 Short: "Creates a local Kubernetes cluster",
 52                 Long:  "Creates a local Kubernetes cluster using Docker container 'nodes'",
 53                 RunE: func(cmd *cobra.Command, args []string) error {
 54                         cli.OverrideDefaultName(cmd.Flags())
 55                         return runE(logger, streams, flags)    ★「kind create cluster」で呼び出される関数 runE を登録
 56                 },
 57         }
 [..]
 67 func runE(logger log.Logger, streams cmd.IOStreams, flags *flagpole) error {
 68         provider := cluster.NewProvider(
 69                 cluster.ProviderWithLogger(logger),
 70                 runtime.GetDefault(logger),
 71         )
 72 
 73         // handle config flag, we might need to read from stdin
 74         withConfig, err := configOption(flags.Config, streams.In)
 75         if err != nil {
 76                 return err
 77         }
 78 
 79         // create the cluster
 80         if err = provider.Create(    ★cluster作成処理
 81                 flags.Name,
 82                 withConfig,
 83                 cluster.CreateWithNodeImage(flags.ImageName),
 84                 cluster.CreateWithRetain(flags.Retain),
 85                 cluster.CreateWithWaitForReady(flags.Wait),
 86                 cluster.CreateWithKubeconfigPath(flags.Kubeconfig),
 87                 cluster.CreateWithDisplayUsage(true),
 88                 cluster.CreateWithDisplaySalutation(true),
 89         ); err != nil {
 90                 return errors.Wrap(err, "failed to create cluster")
 91         }
 92 
 93         return nil
 94 }

pkg/cluster/provider.go

131 // Create provisions and starts a kubernetes-in-docker cluster
132 // TODO: move name to an option to override config
133 func (p *Provider) Create(name string, options ...CreateOption) error {
134         // apply options
135         opts := &internalcreate.ClusterOptions{
136                 NameOverride: name,
137         }
138         for _, o := range options {
139                 if err := o.apply(opts); err != nil {
140                         return err
141                 }
142         }
143         return internalcreate.Cluster(p.logger, p.provider, opts)  
144 }

pkg/cluster/internal/create/create.go

 74 // Cluster creates a cluster
 75 func Cluster(logger log.Logger, p providers.Provider, opts *ClusterOptions) error {
 [..]
124         if !opts.StopBeforeSettingUpKubernetes {
125                 actionsToRun = append(actionsToRun,
126                         kubeadminit.NewAction(), // run kubeadm init
127                 )
128                 // this step might be skipped, but is next after init
129                 if !opts.Config.Networking.DisableDefaultCNI {
130                         actionsToRun = append(actionsToRun,
131                                 installcni.NewAction(), // install CNI
132                         )
133                 }
134                 // add remaining steps
135                 actionsToRun = append(actionsToRun,
136                         installstorage.NewAction(),                // install StorageClass
137                         kubeadmjoin.NewAction(),                   // run kubeadm join
138                         waitforready.NewAction(opts.WaitForReady), // wait for cluster readiness
139                 )
140         }
[..]
142         // run all actions
143         actionsContext := actions.NewActionContext(logger, status, p, opts.Config)
144         for _, action := range actionsToRun {
145                 if err := action.Execute(actionsContext); err != nil {
146                         if !opts.Retain {
147                                 _ = delete.Cluster(logger, p, opts.Config.Name, opts.KubeconfigPath)
148                         }
149                         return err
150                 }
151         }

下記のように kubeadm init を実行 pkg/cluster/internal/create/actions/kubeadminit/init.go

 41 // Execute runs the action
 42 func (a *action) Execute(ctx *actions.ActionContext) error {
 [..]
 59         // run kubeadm
 60         cmd := node.Command(
 61                 // init because this is the control plane node
 62                 "kubeadm", "init",
 63                 // skip preflight checks, as these have undesirable side effects
 64                 // and don't tell us much. requires kubeadm 1.13+
 65                 "--skip-phases=preflight",
 66                 // specify our generated config file
 67                 "--config=/kind/kubeadm.conf",
 68                 "--skip-token-print",
 69                 // increase verbosity for debugging
 70                 "--v=6",
 71         )
Clone this wiki locally