diff --git a/cmd/kubeadm/app/cmd/init.go b/cmd/kubeadm/app/cmd/init.go index b55aa9e87c..8c2302d1bc 100644 --- a/cmd/kubeadm/app/cmd/init.go +++ b/cmd/kubeadm/app/cmd/init.go @@ -63,11 +63,25 @@ var ( Run "kubectl apply -f [podnetwork].yaml" with one of the options listed at: https://kubernetes.io/docs/concepts/cluster-administration/addons/ - You can now join any number of machines by running the following on each node - as root: - - {{.joinCommand}} - + {{if .ControlPlaneEndpoint -}} + {{if .UploadCerts -}} + You can now join any number of the control-plane node running the following command on each as root: + + {{.joinControlPlaneCommand}} + + Please note that the certificate-key gives access to cluster sensitive data, keep it secret! + As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use + "kubeadm init phase upload-certs --experimental-upload-certs" to reload certs afterward. + + {{else -}} + You can now join any number of control-plane nodes by copying certificate authorities + and service account keys on each node and then running the following as root: + + {{.joinControlPlaneCommand}} + + {{end}}{{end}}Then you can join any number of worker nodes by running the following on each as root: + + {{.joinWorkerCommand}} `))) ) @@ -490,14 +504,22 @@ func (d *initData) Tokens() []string { } func printJoinCommand(out io.Writer, adminKubeConfigPath, token string, i *initData) error { - joinCommand, err := cmdutil.GetJoinCommand(adminKubeConfigPath, token, i.certificateKey, i.skipTokenPrint, i.uploadCerts, i.skipCertificateKeyPrint) + joinControlPlaneCommand, err := cmdutil.GetJoinControlPlaneCommand(adminKubeConfigPath, token, i.certificateKey, i.skipTokenPrint, i.skipCertificateKeyPrint) if err != nil { return err } - ctx := map[string]string{ - "KubeConfigPath": adminKubeConfigPath, - "joinCommand": joinCommand, + joinWorkerCommand, err := cmdutil.GetJoinWorkerCommand(adminKubeConfigPath, token, i.skipTokenPrint) + if err != nil { + return err + } + + ctx := map[string]interface{}{ + "KubeConfigPath": adminKubeConfigPath, + "ControlPlaneEndpoint": i.Cfg().ControlPlaneEndpoint, + "UploadCerts": i.uploadCerts, + "joinControlPlaneCommand": joinControlPlaneCommand, + "joinWorkerCommand": joinWorkerCommand, } return initDoneTempl.Execute(out, ctx) diff --git a/cmd/kubeadm/app/cmd/token.go b/cmd/kubeadm/app/cmd/token.go index 881f3cb7f5..de6916c412 100644 --- a/cmd/kubeadm/app/cmd/token.go +++ b/cmd/kubeadm/app/cmd/token.go @@ -228,11 +228,8 @@ func RunCreateToken(out io.Writer, client clientset.Interface, cfgPath string, c // if --print-join-command was specified, print the full `kubeadm join` command // otherwise, just print the token if printJoinCommand { - key := "" skipTokenPrint := false - uploadCerts := false - skipCertificateKeyPrint := false - joinCommand, err := cmdutil.GetJoinCommand(kubeConfigFile, internalcfg.BootstrapTokens[0].Token.String(), key, skipTokenPrint, uploadCerts, skipCertificateKeyPrint) + joinCommand, err := cmdutil.GetJoinWorkerCommand(kubeConfigFile, internalcfg.BootstrapTokens[0].Token.String(), skipTokenPrint) if err != nil { return errors.Wrap(err, "failed to get join command") } diff --git a/cmd/kubeadm/app/cmd/util/join.go b/cmd/kubeadm/app/cmd/util/join.go index a4f73d25d8..601a467af8 100644 --- a/cmd/kubeadm/app/cmd/util/join.go +++ b/cmd/kubeadm/app/cmd/util/join.go @@ -30,19 +30,24 @@ import ( ) var joinCommandTemplate = template.Must(template.New("join").Parse(`` + - `{{if .UploadCerts}}You can now join any number of control-plane node running the following command on each as a root:{{else}}You can now join any number of control-plane node by copying the required certificate authorities on each node and then running the following as root:{{end}} - kubeadm join {{.ControlPlaneHostPort}} --token {{.Token}}{{range $h := .CAPubKeyPins}} --discovery-token-ca-cert-hash {{$h}}{{end}} --experimental-control-plane {{if .UploadCerts}}--certificate-key {{.CertificateKey}} - - Please note that the certificate-key gives access to cluster sensitive data, keep it secret! - As a safeguard, uploaded-certs will be deleted in two hours; If necessary, you can use kubeadm init phase upload-certs to reload certs afterward.{{end}} - - Then you can join any number of worker nodes by running the following on each as root: - kubeadm join {{.ControlPlaneHostPort}} --token {{.Token}}{{range $h := .CAPubKeyPins}} --discovery-token-ca-cert-hash {{$h}}{{end}}`, + `kubeadm join {{.ControlPlaneHostPort}} --token {{.Token}} \ + {{range $h := .CAPubKeyPins}}--discovery-token-ca-cert-hash {{$h}} {{end}}{{if .ControlPlane}}\ + --experimental-control-plane {{if .CertificateKey}}--certificate-key {{.CertificateKey}}{{end}}{{end}}`, )) -// GetJoinCommand returns the kubeadm join command for a given token and +// GetJoinWorkerCommand returns the kubeadm join command for a given token and // and Kubernetes cluster (the current cluster in the kubeconfig file) -func GetJoinCommand(kubeConfigFile, token, key string, skipTokenPrint, uploadCerts, skipCertificateKeyPrint bool) (string, error) { +func GetJoinWorkerCommand(kubeConfigFile, token string, skipTokenPrint bool) (string, error) { + return getJoinCommand(kubeConfigFile, token, "", false, skipTokenPrint, false) +} + +// GetJoinControlPlaneCommand returns the kubeadm join command for a given token and +// and Kubernetes cluster (the current cluster in the kubeconfig file) +func GetJoinControlPlaneCommand(kubeConfigFile, token, key string, skipTokenPrint, skipCertificateKeyPrint bool) (string, error) { + return getJoinCommand(kubeConfigFile, token, key, true, skipTokenPrint, skipCertificateKeyPrint) +} + +func getJoinCommand(kubeConfigFile, token, key string, controlPlane, skipTokenPrint, skipCertificateKeyPrint bool) (string, error) { // load the kubeconfig file to get the CA certificate and endpoint config, err := clientcmd.LoadFromFile(kubeConfigFile) if err != nil { @@ -81,8 +86,8 @@ func GetJoinCommand(kubeConfigFile, token, key string, skipTokenPrint, uploadCer "Token": token, "CAPubKeyPins": publicKeyPins, "ControlPlaneHostPort": strings.Replace(clusterConfig.Server, "https://", "", -1), - "UploadCerts": uploadCerts, "CertificateKey": key, + "ControlPlane": controlPlane, } if skipTokenPrint {