Merge pull request #34501 from mikedanese/kubeadm-init-cfg

Automatic merge from submit-queue

kubeadm: allow kubeadm init to read config from file

@kubernetes/sig-cluster-lifecycle
This commit is contained in:
Kubernetes Submit Queue 2016-10-13 04:19:05 -07:00 committed by GitHub
commit c1986f0fc7

View File

@ -19,6 +19,7 @@ package cmd
import (
"fmt"
"io"
"io/ioutil"
"github.com/renstrom/dedent"
"github.com/spf13/cobra"
@ -26,9 +27,11 @@ import (
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
kubemaster "k8s.io/kubernetes/cmd/kubeadm/app/master"
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
"k8s.io/kubernetes/pkg/api"
"k8s.io/kubernetes/pkg/cloudprovider"
_ "k8s.io/kubernetes/pkg/cloudprovider/providers"
cmdutil "k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/runtime"
netutil "k8s.io/kubernetes/pkg/util/net"
)
@ -45,12 +48,19 @@ var (
// NewCmdInit returns "kubeadm init" command.
func NewCmdInit(out io.Writer) *cobra.Command {
cfg := &kubeadmapi.MasterConfiguration{}
var cfgPath string
cmd := &cobra.Command{
Use: "init",
Short: "Run this in order to set up the Kubernetes master.",
Run: func(cmd *cobra.Command, args []string) {
err := RunInit(out, cmd, args, cfg)
cmdutil.CheckErr(err)
check := func(err error) {
if err != nil {
cmdutil.CheckErr(fmt.Errorf("<cmd/init> %v", err))
}
}
i, err := NewInit(cfgPath, cfg)
check(err)
check(i.Run(out))
},
}
@ -88,6 +98,8 @@ func NewCmdInit(out io.Writer) *cobra.Command {
`Choose a specific Kubernetes version for the control plane`,
)
cmd.PersistentFlags().StringVar(&cfgPath, "config", "", "Path to kubeadm config file")
// TODO (phase1+) @errordeveloper make the flags below not show up in --help but rather on --advanced-help
cmd.PersistentFlags().StringSliceVar(
&cfg.Etcd.Endpoints, "external-etcd-endpoints", []string{},
@ -116,14 +128,26 @@ func NewCmdInit(out io.Writer) *cobra.Command {
return cmd
}
// RunInit executes master node provisioning, including certificates, needed static pod manifests, etc.
func RunInit(out io.Writer, cmd *cobra.Command, args []string, cfg *kubeadmapi.MasterConfiguration) error {
type Init struct {
cfg *kubeadmapi.MasterConfiguration
}
func NewInit(cfgPath string, cfg *kubeadmapi.MasterConfiguration) (*Init, error) {
if cfgPath != "" {
b, err := ioutil.ReadFile(cfgPath)
if err != nil {
return nil, fmt.Errorf("unable to read config from %q [%v]", cfgPath, err)
}
if err := runtime.DecodeInto(api.Codecs.UniversalDecoder(), b, cfg); err != nil {
return nil, fmt.Errorf("unable to decode config from %q [%v]", cfgPath, err)
}
}
// Auto-detect the IP
if len(cfg.API.AdvertiseAddresses) == 0 {
// TODO(phase1+) perhaps we could actually grab eth0 and eth1
ip, err := netutil.ChooseHostInterface()
if err != nil {
return err
return nil, err
}
cfg.API.AdvertiseAddresses = []string{ip.String()}
}
@ -131,26 +155,31 @@ func RunInit(out io.Writer, cmd *cobra.Command, args []string, cfg *kubeadmapi.M
// TODO(phase1+) create a custom flag
if cfg.CloudProvider != "" {
if cloudprovider.IsCloudProvider(cfg.CloudProvider) {
fmt.Printf("<cmd/init> cloud provider %q initialized for the control plane. Remember to set the same cloud provider flag on the kubelet.\n", cfg.CloudProvider)
fmt.Printf("cloud provider %q initialized for the control plane. Remember to set the same cloud provider flag on the kubelet.\n", cfg.CloudProvider)
} else {
return fmt.Errorf("<cmd/init> cloud provider %q is not supported, you can use any of %v, or leave it unset.\n", cfg.CloudProvider, cloudprovider.CloudProviders())
return nil, fmt.Errorf("cloud provider %q is not supported, you can use any of %v, or leave it unset.\n", cfg.CloudProvider, cloudprovider.CloudProviders())
}
}
return &Init{cfg: cfg}, nil
}
if err := kubemaster.CreateTokenAuthFile(&cfg.Secrets); err != nil {
// RunInit executes master node provisioning, including certificates, needed static pod manifests, etc.
func (i *Init) Run(out io.Writer) error {
if err := kubemaster.CreateTokenAuthFile(&i.cfg.Secrets); err != nil {
return err
}
if err := kubemaster.WriteStaticPodManifests(cfg); err != nil {
if err := kubemaster.WriteStaticPodManifests(i.cfg); err != nil {
return err
}
caKey, caCert, err := kubemaster.CreatePKIAssets(cfg)
caKey, caCert, err := kubemaster.CreatePKIAssets(i.cfg)
if err != nil {
return err
}
kubeconfigs, err := kubemaster.CreateCertsAndConfigForClients(cfg.API.AdvertiseAddresses, []string{"kubelet", "admin"}, caKey, caCert)
kubeconfigs, err := kubemaster.CreateCertsAndConfigForClients(i.cfg.API.AdvertiseAddresses, []string{"kubelet", "admin"}, caKey, caCert)
if err != nil {
return err
}
@ -180,18 +209,18 @@ func RunInit(out io.Writer, cmd *cobra.Command, args []string, cfg *kubeadmapi.M
return err
}
if err := kubemaster.CreateDiscoveryDeploymentAndSecret(cfg, client, caCert); err != nil {
if err := kubemaster.CreateDiscoveryDeploymentAndSecret(i.cfg, client, caCert); err != nil {
return err
}
if err := kubemaster.CreateEssentialAddons(cfg, client); err != nil {
if err := kubemaster.CreateEssentialAddons(i.cfg, client); err != nil {
return err
}
// TODO(phase1+) use templates to reference struct fields directly as order of args is fragile
fmt.Fprintf(out, initDoneMsgf,
cfg.Secrets.GivenToken,
cfg.API.AdvertiseAddresses[0],
i.cfg.Secrets.GivenToken,
i.cfg.API.AdvertiseAddresses[0],
)
return nil