mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 20:24:09 +00:00
Merge pull request #60022 from fabriziopandini/kubeadm567
Automatic merge from submit-queue (batch tested with PRs 60148, 60022, 59125, 60068, 60154). 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>. Refactor kubeadm join command generation **What this PR does / why we need it**: Creation of the `kubeadm join` command is implemented in three different points of kubeadm: - `kubeadm init` - `kubeadm token create` - `kubeadm phase bootstrap-token create` This PR refactor above points in order to share a common function for creating the `kubeadm join` command. **Which issue(s) this PR fixes**: Fixes [#567](https://github.com/kubernetes/kubeadm/issues/567) **Special notes for your reviewer**: While implementing the PR, I changed the order of parameters in `kubeadm join` from: ``` kubeadm join --token 8df4zm.5jyv2nrxb18y84jq 172.31.0.101:6443 --discovery-token-ca-cert-hash sha256:b62e1f70c1c6afebe36bc971b15b90f7e453f1c0fe2ddc4d92e07512f1143194 ``` to ``` kubeadm join 172.31.0.101:6443 --token 8df4zm.5jyv2nrxb18y84jq --discovery-token-ca-cert-hash sha256:b62e1f70c1c6afebe36bc971b15b90f7e453f1c0fe2ddc4d92e07512f1143194 ``` **Release note**: ```release-note NONE ```
This commit is contained in:
commit
5e64f075dc
@ -36,7 +36,6 @@ go_library(
|
|||||||
"//cmd/kubeadm/app/phases/bootstraptoken/clusterinfo:go_default_library",
|
"//cmd/kubeadm/app/phases/bootstraptoken/clusterinfo:go_default_library",
|
||||||
"//cmd/kubeadm/app/phases/bootstraptoken/node:go_default_library",
|
"//cmd/kubeadm/app/phases/bootstraptoken/node:go_default_library",
|
||||||
"//cmd/kubeadm/app/phases/certs:go_default_library",
|
"//cmd/kubeadm/app/phases/certs:go_default_library",
|
||||||
"//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library",
|
|
||||||
"//cmd/kubeadm/app/phases/controlplane:go_default_library",
|
"//cmd/kubeadm/app/phases/controlplane:go_default_library",
|
||||||
"//cmd/kubeadm/app/phases/etcd:go_default_library",
|
"//cmd/kubeadm/app/phases/etcd:go_default_library",
|
||||||
"//cmd/kubeadm/app/phases/kubeconfig:go_default_library",
|
"//cmd/kubeadm/app/phases/kubeconfig:go_default_library",
|
||||||
@ -51,7 +50,6 @@ go_library(
|
|||||||
"//cmd/kubeadm/app/util/config:go_default_library",
|
"//cmd/kubeadm/app/util/config:go_default_library",
|
||||||
"//cmd/kubeadm/app/util/dryrun:go_default_library",
|
"//cmd/kubeadm/app/util/dryrun:go_default_library",
|
||||||
"//cmd/kubeadm/app/util/kubeconfig:go_default_library",
|
"//cmd/kubeadm/app/util/kubeconfig:go_default_library",
|
||||||
"//cmd/kubeadm/app/util/pubkeypin:go_default_library",
|
|
||||||
"//cmd/kubeadm/app/util/token:go_default_library",
|
"//cmd/kubeadm/app/util/token:go_default_library",
|
||||||
"//pkg/api/legacyscheme:go_default_library",
|
"//pkg/api/legacyscheme:go_default_library",
|
||||||
"//pkg/apis/core:go_default_library",
|
"//pkg/apis/core:go_default_library",
|
||||||
@ -75,7 +73,6 @@ go_library(
|
|||||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/tools/bootstrap/token/api:go_default_library",
|
"//vendor/k8s.io/client-go/tools/bootstrap/token/api:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/tools/bootstrap/token/util:go_default_library",
|
"//vendor/k8s.io/client-go/tools/bootstrap/token/util:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/tools/clientcmd:go_default_library",
|
|
||||||
"//vendor/k8s.io/client-go/util/cert:go_default_library",
|
"//vendor/k8s.io/client-go/util/cert:go_default_library",
|
||||||
"//vendor/k8s.io/utils/exec:go_default_library",
|
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||||
],
|
],
|
||||||
|
@ -38,6 +38,7 @@ import (
|
|||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
kubeadmapiext "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/v1alpha1"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
|
"k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm/validation"
|
||||||
|
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
||||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/features"
|
"k8s.io/kubernetes/cmd/kubeadm/app/features"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/images"
|
"k8s.io/kubernetes/cmd/kubeadm/app/images"
|
||||||
@ -46,7 +47,6 @@ import (
|
|||||||
clusterinfophase "k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo"
|
clusterinfophase "k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo"
|
||||||
nodebootstraptokenphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/node"
|
nodebootstraptokenphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/node"
|
||||||
certsphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs"
|
certsphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/certs"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil"
|
|
||||||
controlplanephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/controlplane"
|
controlplanephase "k8s.io/kubernetes/cmd/kubeadm/app/phases/controlplane"
|
||||||
etcdphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/etcd"
|
etcdphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/etcd"
|
||||||
kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
|
kubeconfigphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubeconfig"
|
||||||
@ -61,7 +61,6 @@ import (
|
|||||||
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
|
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
|
||||||
dryrunutil "k8s.io/kubernetes/cmd/kubeadm/app/util/dryrun"
|
dryrunutil "k8s.io/kubernetes/cmd/kubeadm/app/util/dryrun"
|
||||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/pubkeypin"
|
|
||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||||
utilsexec "k8s.io/utils/exec"
|
utilsexec "k8s.io/utils/exec"
|
||||||
)
|
)
|
||||||
@ -83,7 +82,7 @@ var (
|
|||||||
You can now join any number of machines by running the following on each node
|
You can now join any number of machines by running the following on each node
|
||||||
as root:
|
as root:
|
||||||
|
|
||||||
kubeadm join --token {{.Token}} {{.MasterHostPort}} --discovery-token-ca-cert-hash {{.CAPubKeyPin}}
|
{{.joinCommand}}
|
||||||
|
|
||||||
`)))
|
`)))
|
||||||
|
|
||||||
@ -467,26 +466,15 @@ func (i *Init) Run(out io.Writer) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load the CA certificate from so we can pin its public key
|
// Gets the join command
|
||||||
caCert, err := pkiutil.TryLoadCertFromDisk(i.cfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName)
|
joinCommand, err := cmdutil.GetJoinCommand(kubeadmconstants.GetAdminKubeConfigPath(), i.cfg.Token, i.skipTokenPrint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("error loading ca cert from disk: %v", err)
|
return fmt.Errorf("failed to get join command: %v", err)
|
||||||
}
|
|
||||||
|
|
||||||
// Generate the Master host/port pair used by initDoneTempl
|
|
||||||
masterHostPort, err := kubeadmutil.GetMasterHostPort(i.cfg)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error getting master host port: %v", err)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := map[string]string{
|
ctx := map[string]string{
|
||||||
"KubeConfigPath": adminKubeConfigPath,
|
"KubeConfigPath": adminKubeConfigPath,
|
||||||
"Token": i.cfg.Token,
|
"joinCommand": joinCommand,
|
||||||
"CAPubKeyPin": pubkeypin.Hash(caCert),
|
|
||||||
"MasterHostPort": masterHostPort,
|
|
||||||
}
|
|
||||||
if i.skipTokenPrint {
|
|
||||||
ctx["Token"] = "<value withheld>"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return initDoneTempl.Execute(out, ctx)
|
return initDoneTempl.Execute(out, ctx)
|
||||||
|
@ -35,7 +35,6 @@ go_library(
|
|||||||
"//cmd/kubeadm/app/phases/bootstraptoken/clusterinfo:go_default_library",
|
"//cmd/kubeadm/app/phases/bootstraptoken/clusterinfo:go_default_library",
|
||||||
"//cmd/kubeadm/app/phases/bootstraptoken/node:go_default_library",
|
"//cmd/kubeadm/app/phases/bootstraptoken/node:go_default_library",
|
||||||
"//cmd/kubeadm/app/phases/certs:go_default_library",
|
"//cmd/kubeadm/app/phases/certs:go_default_library",
|
||||||
"//cmd/kubeadm/app/phases/certs/pkiutil:go_default_library",
|
|
||||||
"//cmd/kubeadm/app/phases/controlplane:go_default_library",
|
"//cmd/kubeadm/app/phases/controlplane:go_default_library",
|
||||||
"//cmd/kubeadm/app/phases/etcd:go_default_library",
|
"//cmd/kubeadm/app/phases/etcd:go_default_library",
|
||||||
"//cmd/kubeadm/app/phases/kubeconfig:go_default_library",
|
"//cmd/kubeadm/app/phases/kubeconfig:go_default_library",
|
||||||
@ -47,7 +46,6 @@ go_library(
|
|||||||
"//cmd/kubeadm/app/util/apiclient:go_default_library",
|
"//cmd/kubeadm/app/util/apiclient:go_default_library",
|
||||||
"//cmd/kubeadm/app/util/config:go_default_library",
|
"//cmd/kubeadm/app/util/config:go_default_library",
|
||||||
"//cmd/kubeadm/app/util/kubeconfig:go_default_library",
|
"//cmd/kubeadm/app/util/kubeconfig:go_default_library",
|
||||||
"//cmd/kubeadm/app/util/pubkeypin:go_default_library",
|
|
||||||
"//pkg/api/legacyscheme:go_default_library",
|
"//pkg/api/legacyscheme:go_default_library",
|
||||||
"//pkg/util/normalizer:go_default_library",
|
"//pkg/util/normalizer:go_default_library",
|
||||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||||
|
@ -34,11 +34,9 @@ import (
|
|||||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo"
|
"k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/clusterinfo"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/node"
|
"k8s.io/kubernetes/cmd/kubeadm/app/phases/bootstraptoken/node"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/phases/certs/pkiutil"
|
|
||||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||||
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
|
configutil "k8s.io/kubernetes/cmd/kubeadm/app/util/config"
|
||||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/pubkeypin"
|
|
||||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||||
"k8s.io/kubernetes/pkg/util/normalizer"
|
"k8s.io/kubernetes/pkg/util/normalizer"
|
||||||
)
|
)
|
||||||
@ -137,7 +135,7 @@ func NewSubCmdBootstrapTokenAll(kubeConfigFile *string) *cobra.Command {
|
|||||||
kubeadmutil.CheckErr(err)
|
kubeadmutil.CheckErr(err)
|
||||||
|
|
||||||
// Creates the bootstap token
|
// Creates the bootstap token
|
||||||
err = createBootstrapToken(client, cfgPath, cfg, description, usages, extraGroups, skipTokenPrint)
|
err = createBootstrapToken(*kubeConfigFile, client, cfgPath, cfg, description, usages, extraGroups, skipTokenPrint)
|
||||||
kubeadmutil.CheckErr(err)
|
kubeadmutil.CheckErr(err)
|
||||||
|
|
||||||
// Create the cluster-info ConfigMap or update if it already exists
|
// Create the cluster-info ConfigMap or update if it already exists
|
||||||
@ -194,7 +192,7 @@ func NewSubCmdBootstrapToken(kubeConfigFile *string) *cobra.Command {
|
|||||||
client, err := kubeconfigutil.ClientSetFromFile(*kubeConfigFile)
|
client, err := kubeconfigutil.ClientSetFromFile(*kubeConfigFile)
|
||||||
kubeadmutil.CheckErr(err)
|
kubeadmutil.CheckErr(err)
|
||||||
|
|
||||||
err = createBootstrapToken(client, cfgPath, cfg, description, usages, extraGroups, skipTokenPrint)
|
err = createBootstrapToken(*kubeConfigFile, client, cfgPath, cfg, description, usages, extraGroups, skipTokenPrint)
|
||||||
kubeadmutil.CheckErr(err)
|
kubeadmutil.CheckErr(err)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -288,10 +286,6 @@ func addBootstrapTokenFlags(flagSet *pflag.FlagSet, cfg *kubeadmapiext.MasterCon
|
|||||||
cfgPath, "config", *cfgPath,
|
cfgPath, "config", *cfgPath,
|
||||||
"Path to kubeadm config file (WARNING: Usage of a configuration file is experimental)",
|
"Path to kubeadm config file (WARNING: Usage of a configuration file is experimental)",
|
||||||
)
|
)
|
||||||
flagSet.StringVar(
|
|
||||||
&cfg.CertificatesDir, "cert-dir", cfg.CertificatesDir,
|
|
||||||
"The path where certificates are stored",
|
|
||||||
)
|
|
||||||
flagSet.StringVar(
|
flagSet.StringVar(
|
||||||
&cfg.Token, "token", cfg.Token,
|
&cfg.Token, "token", cfg.Token,
|
||||||
"The token to use for establishing bidirectional trust between nodes and masters",
|
"The token to use for establishing bidirectional trust between nodes and masters",
|
||||||
@ -318,7 +312,7 @@ func addBootstrapTokenFlags(flagSet *pflag.FlagSet, cfg *kubeadmapiext.MasterCon
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
func createBootstrapToken(client clientset.Interface, cfgPath string, cfg *kubeadmapiext.MasterConfiguration, description string, usages, extraGroups []string, skipTokenPrint bool) error {
|
func createBootstrapToken(kubeConfigFile string, client clientset.Interface, cfgPath string, cfg *kubeadmapiext.MasterConfiguration, description string, usages, extraGroups []string, skipTokenPrint bool) error {
|
||||||
// adding groups only makes sense for authentication
|
// adding groups only makes sense for authentication
|
||||||
usagesSet := sets.NewString(usages...)
|
usagesSet := sets.NewString(usages...)
|
||||||
usageAuthentication := strings.TrimPrefix(bootstrapapi.BootstrapTokenUsageAuthentication, bootstrapapi.BootstrapTokenUsagePrefix)
|
usageAuthentication := strings.TrimPrefix(bootstrapapi.BootstrapTokenUsageAuthentication, bootstrapapi.BootstrapTokenUsagePrefix)
|
||||||
@ -337,23 +331,19 @@ func createBootstrapToken(client clientset.Interface, cfgPath string, cfg *kubea
|
|||||||
internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, cfg)
|
internalcfg, err := configutil.ConfigFileAndDefaultsToInternalConfig(cfgPath, cfg)
|
||||||
kubeadmutil.CheckErr(err)
|
kubeadmutil.CheckErr(err)
|
||||||
|
|
||||||
// Load the CA certificate from so we can pin its public key
|
|
||||||
caCert, err := pkiutil.TryLoadCertFromDisk(internalcfg.CertificatesDir, kubeadmconstants.CACertAndKeyBaseName)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("error loading ca cert from disk: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Creates or updates the token
|
// Creates or updates the token
|
||||||
if err := node.UpdateOrCreateToken(client, internalcfg.Token, false, internalcfg.TokenTTL.Duration, usages, extraGroups, description); err != nil {
|
if err := node.UpdateOrCreateToken(client, internalcfg.Token, false, internalcfg.TokenTTL.Duration, usages, extraGroups, description); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
fmt.Println("[bootstraptoken] Bootstrap token Created")
|
fmt.Println("[bootstraptoken] Bootstrap token Created")
|
||||||
if skipTokenPrint {
|
|
||||||
internalcfg.Token = "{token}"
|
|
||||||
}
|
|
||||||
fmt.Println("[bootstraptoken] You can now join any number of machines by running:")
|
fmt.Println("[bootstraptoken] You can now join any number of machines by running:")
|
||||||
fmt.Printf("[bootstraptoken] kubeadm join {master} --token %s --discovery-token-ca-cert-hash %s \n", internalcfg.Token, pubkeypin.Hash(caCert))
|
|
||||||
|
joinCommand, err := cmdutil.GetJoinCommand(kubeConfigFile, internalcfg.Token, skipTokenPrint)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get join command: %v", err)
|
||||||
|
}
|
||||||
|
fmt.Println(joinCommand)
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -17,15 +17,12 @@ limitations under the License.
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"crypto/x509"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
"os"
|
||||||
"sort"
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"text/tabwriter"
|
"text/tabwriter"
|
||||||
"text/template"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/renstrom/dedent"
|
"github.com/renstrom/dedent"
|
||||||
@ -38,8 +35,6 @@ import (
|
|||||||
clientset "k8s.io/client-go/kubernetes"
|
clientset "k8s.io/client-go/kubernetes"
|
||||||
bootstrapapi "k8s.io/client-go/tools/bootstrap/token/api"
|
bootstrapapi "k8s.io/client-go/tools/bootstrap/token/api"
|
||||||
bootstraputil "k8s.io/client-go/tools/bootstrap/token/util"
|
bootstraputil "k8s.io/client-go/tools/bootstrap/token/util"
|
||||||
"k8s.io/client-go/tools/clientcmd"
|
|
||||||
clientcertutil "k8s.io/client-go/util/cert"
|
|
||||||
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
kubeadmapi "k8s.io/kubernetes/cmd/kubeadm/app/apis/kubeadm"
|
||||||
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
cmdutil "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util"
|
||||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
@ -47,16 +42,11 @@ import (
|
|||||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
|
"k8s.io/kubernetes/cmd/kubeadm/app/util/apiclient"
|
||||||
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/util/pubkeypin"
|
|
||||||
tokenutil "k8s.io/kubernetes/cmd/kubeadm/app/util/token"
|
tokenutil "k8s.io/kubernetes/cmd/kubeadm/app/util/token"
|
||||||
api "k8s.io/kubernetes/pkg/apis/core"
|
api "k8s.io/kubernetes/pkg/apis/core"
|
||||||
"k8s.io/kubernetes/pkg/printers"
|
"k8s.io/kubernetes/pkg/printers"
|
||||||
)
|
)
|
||||||
|
|
||||||
var joinCommandTemplate = template.Must(template.New("join").Parse(`` +
|
|
||||||
`kubeadm join --token {{.Token}} {{.MasterHostPort}}{{range $h := .CAPubKeyPins}} --discovery-token-ca-cert-hash {{$h}}{{end}}`,
|
|
||||||
))
|
|
||||||
|
|
||||||
// NewCmdToken returns cobra.Command for token management
|
// NewCmdToken returns cobra.Command for token management
|
||||||
func NewCmdToken(out io.Writer, errW io.Writer) *cobra.Command {
|
func NewCmdToken(out io.Writer, errW io.Writer) *cobra.Command {
|
||||||
var kubeConfigFile string
|
var kubeConfigFile string
|
||||||
@ -247,7 +237,7 @@ func RunCreateToken(out io.Writer, client clientset.Interface, token string, tok
|
|||||||
// if --print-join-command was specified, print the full `kubeadm join` command
|
// if --print-join-command was specified, print the full `kubeadm join` command
|
||||||
// otherwise, just print the token
|
// otherwise, just print the token
|
||||||
if printJoinCommand {
|
if printJoinCommand {
|
||||||
joinCommand, err := getJoinCommand(token, kubeConfigFile)
|
joinCommand, err := cmdutil.GetJoinCommand(kubeConfigFile, token, false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get join command: %v", err)
|
return fmt.Errorf("failed to get join command: %v", err)
|
||||||
}
|
}
|
||||||
@ -395,52 +385,3 @@ func getClientset(file string, dryRun bool) (clientset.Interface, error) {
|
|||||||
}
|
}
|
||||||
return kubeconfigutil.ClientSetFromFile(file)
|
return kubeconfigutil.ClientSetFromFile(file)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getJoinCommand(token string, kubeConfigFile string) (string, error) {
|
|
||||||
// load the kubeconfig file to get the CA certificate and endpoint
|
|
||||||
config, err := clientcmd.LoadFromFile(kubeConfigFile)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("failed to load kubeconfig: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// load the default cluster config
|
|
||||||
clusterConfig := kubeconfigutil.GetClusterFromKubeConfig(config)
|
|
||||||
if clusterConfig == nil {
|
|
||||||
return "", fmt.Errorf("failed to get default cluster config")
|
|
||||||
}
|
|
||||||
|
|
||||||
// load CA certificates from the kubeconfig (either from PEM data or by file path)
|
|
||||||
var caCerts []*x509.Certificate
|
|
||||||
if clusterConfig.CertificateAuthorityData != nil {
|
|
||||||
caCerts, err = clientcertutil.ParseCertsPEM(clusterConfig.CertificateAuthorityData)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("failed to parse CA certificate from kubeconfig: %v", err)
|
|
||||||
}
|
|
||||||
} else if clusterConfig.CertificateAuthority != "" {
|
|
||||||
caCerts, err = clientcertutil.CertsFromFile(clusterConfig.CertificateAuthority)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("failed to load CA certificate referenced by kubeconfig: %v", err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return "", fmt.Errorf("no CA certificates found in kubeconfig")
|
|
||||||
}
|
|
||||||
|
|
||||||
// hash all the CA certs and include their public key pins as trusted values
|
|
||||||
publicKeyPins := make([]string, 0, len(caCerts))
|
|
||||||
for _, caCert := range caCerts {
|
|
||||||
publicKeyPins = append(publicKeyPins, pubkeypin.Hash(caCert))
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx := map[string]interface{}{
|
|
||||||
"Token": token,
|
|
||||||
"CAPubKeyPins": publicKeyPins,
|
|
||||||
"MasterHostPort": strings.Replace(clusterConfig.Server, "https://", "", -1),
|
|
||||||
}
|
|
||||||
|
|
||||||
var out bytes.Buffer
|
|
||||||
err = joinCommandTemplate.Execute(&out, ctx)
|
|
||||||
if err != nil {
|
|
||||||
return "", fmt.Errorf("failed to render join command template: %v", err)
|
|
||||||
}
|
|
||||||
return out.String(), nil
|
|
||||||
}
|
|
||||||
|
@ -5,12 +5,17 @@ go_library(
|
|||||||
srcs = [
|
srcs = [
|
||||||
"cmdutil.go",
|
"cmdutil.go",
|
||||||
"documentation.go",
|
"documentation.go",
|
||||||
|
"join.go",
|
||||||
],
|
],
|
||||||
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util",
|
importpath = "k8s.io/kubernetes/cmd/kubeadm/app/cmd/util",
|
||||||
visibility = ["//visibility:public"],
|
visibility = ["//visibility:public"],
|
||||||
deps = [
|
deps = [
|
||||||
|
"//cmd/kubeadm/app/util/kubeconfig:go_default_library",
|
||||||
|
"//cmd/kubeadm/app/util/pubkeypin:go_default_library",
|
||||||
"//pkg/util/normalizer:go_default_library",
|
"//pkg/util/normalizer:go_default_library",
|
||||||
"//vendor/github.com/spf13/cobra:go_default_library",
|
"//vendor/github.com/spf13/cobra:go_default_library",
|
||||||
|
"//vendor/k8s.io/client-go/tools/clientcmd:go_default_library",
|
||||||
|
"//vendor/k8s.io/client-go/util/cert:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
89
cmd/kubeadm/app/cmd/util/join.go
Normal file
89
cmd/kubeadm/app/cmd/util/join.go
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
Copyright 2018 The Kubernetes Authors.
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package util
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"crypto/x509"
|
||||||
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"k8s.io/client-go/tools/clientcmd"
|
||||||
|
clientcertutil "k8s.io/client-go/util/cert"
|
||||||
|
kubeconfigutil "k8s.io/kubernetes/cmd/kubeadm/app/util/kubeconfig"
|
||||||
|
"k8s.io/kubernetes/cmd/kubeadm/app/util/pubkeypin"
|
||||||
|
)
|
||||||
|
|
||||||
|
var joinCommandTemplate = template.Must(template.New("join").Parse(`` +
|
||||||
|
`kubeadm join {{.MasterHostPort}} --token {{.Token}}{{range $h := .CAPubKeyPins}} --discovery-token-ca-cert-hash {{$h}}{{end}}`,
|
||||||
|
))
|
||||||
|
|
||||||
|
// GetJoinCommand returns the kubeadm join command for a given token and
|
||||||
|
// and kubernetes cluster (the current cluster in the kubeconfig file)
|
||||||
|
func GetJoinCommand(kubeConfigFile string, token string, skipTokenPrint bool) (string, error) {
|
||||||
|
// load the kubeconfig file to get the CA certificate and endpoint
|
||||||
|
config, err := clientcmd.LoadFromFile(kubeConfigFile)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to load kubeconfig: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// load the default cluster config
|
||||||
|
clusterConfig := kubeconfigutil.GetClusterFromKubeConfig(config)
|
||||||
|
if clusterConfig == nil {
|
||||||
|
return "", fmt.Errorf("failed to get default cluster config")
|
||||||
|
}
|
||||||
|
|
||||||
|
// load CA certificates from the kubeconfig (either from PEM data or by file path)
|
||||||
|
var caCerts []*x509.Certificate
|
||||||
|
if clusterConfig.CertificateAuthorityData != nil {
|
||||||
|
caCerts, err = clientcertutil.ParseCertsPEM(clusterConfig.CertificateAuthorityData)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to parse CA certificate from kubeconfig: %v", err)
|
||||||
|
}
|
||||||
|
} else if clusterConfig.CertificateAuthority != "" {
|
||||||
|
caCerts, err = clientcertutil.CertsFromFile(clusterConfig.CertificateAuthority)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to load CA certificate referenced by kubeconfig: %v", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return "", fmt.Errorf("no CA certificates found in kubeconfig")
|
||||||
|
}
|
||||||
|
|
||||||
|
// hash all the CA certs and include their public key pins as trusted values
|
||||||
|
publicKeyPins := make([]string, 0, len(caCerts))
|
||||||
|
for _, caCert := range caCerts {
|
||||||
|
publicKeyPins = append(publicKeyPins, pubkeypin.Hash(caCert))
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx := map[string]interface{}{
|
||||||
|
"Token": token,
|
||||||
|
"CAPubKeyPins": publicKeyPins,
|
||||||
|
"MasterHostPort": strings.Replace(clusterConfig.Server, "https://", "", -1),
|
||||||
|
}
|
||||||
|
|
||||||
|
if skipTokenPrint {
|
||||||
|
ctx["Token"] = template.HTML("<value withheld>")
|
||||||
|
}
|
||||||
|
|
||||||
|
var out bytes.Buffer
|
||||||
|
err = joinCommandTemplate.Execute(&out, ctx)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("failed to render join command template: %v", err)
|
||||||
|
}
|
||||||
|
return out.String(), nil
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user