mirror of https://github.com/k3s-io/k3s
Merge pull request #74671 from yagonobre/certificate-key
Add certificate-key to kubeadm upload-certs phase, and improve init outputpull/564/head
commit
2b63efcd3e
|
@ -75,16 +75,18 @@ var (
|
||||||
// Please note that this structure includes the public kubeadm config API, but only a subset of the options
|
// Please note that this structure includes the public kubeadm config API, but only a subset of the options
|
||||||
// supported by this api will be exposed as a flag.
|
// supported by this api will be exposed as a flag.
|
||||||
type initOptions struct {
|
type initOptions struct {
|
||||||
cfgPath string
|
cfgPath string
|
||||||
skipTokenPrint bool
|
skipTokenPrint bool
|
||||||
dryRun bool
|
dryRun bool
|
||||||
kubeconfigDir string
|
kubeconfigDir string
|
||||||
kubeconfigPath string
|
kubeconfigPath string
|
||||||
featureGatesString string
|
featureGatesString string
|
||||||
ignorePreflightErrors []string
|
ignorePreflightErrors []string
|
||||||
bto *options.BootstrapTokenOptions
|
bto *options.BootstrapTokenOptions
|
||||||
externalcfg *kubeadmapiv1beta1.InitConfiguration
|
externalcfg *kubeadmapiv1beta1.InitConfiguration
|
||||||
uploadCerts bool
|
uploadCerts bool
|
||||||
|
certificateKey string
|
||||||
|
skipCertificateKeyPrint bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// compile-time assert that the local data object satisfies the phases data interface.
|
// compile-time assert that the local data object satisfies the phases data interface.
|
||||||
|
@ -93,20 +95,21 @@ var _ phases.InitData = &initData{}
|
||||||
// initData defines all the runtime information used when running the kubeadm init worklow;
|
// initData defines all the runtime information used when running the kubeadm init worklow;
|
||||||
// this data is shared across all the phases that are included in the workflow.
|
// this data is shared across all the phases that are included in the workflow.
|
||||||
type initData struct {
|
type initData struct {
|
||||||
cfg *kubeadmapi.InitConfiguration
|
cfg *kubeadmapi.InitConfiguration
|
||||||
skipTokenPrint bool
|
skipTokenPrint bool
|
||||||
dryRun bool
|
dryRun bool
|
||||||
kubeconfigDir string
|
kubeconfigDir string
|
||||||
kubeconfigPath string
|
kubeconfigPath string
|
||||||
ignorePreflightErrors sets.String
|
ignorePreflightErrors sets.String
|
||||||
certificatesDir string
|
certificatesDir string
|
||||||
dryRunDir string
|
dryRunDir string
|
||||||
externalCA bool
|
externalCA bool
|
||||||
client clientset.Interface
|
client clientset.Interface
|
||||||
waiter apiclient.Waiter
|
waiter apiclient.Waiter
|
||||||
outputWriter io.Writer
|
outputWriter io.Writer
|
||||||
uploadCerts bool
|
uploadCerts bool
|
||||||
certificateKey string
|
certificateKey string
|
||||||
|
skipCertificateKeyPrint bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCmdInit returns "kubeadm init" command.
|
// NewCmdInit returns "kubeadm init" command.
|
||||||
|
@ -241,7 +244,15 @@ func AddInitOtherFlags(flagSet *flag.FlagSet, initOptions *initOptions) {
|
||||||
)
|
)
|
||||||
flagSet.BoolVar(
|
flagSet.BoolVar(
|
||||||
&initOptions.uploadCerts, options.UploadCerts, initOptions.uploadCerts,
|
&initOptions.uploadCerts, options.UploadCerts, initOptions.uploadCerts,
|
||||||
"Upload certfificates to kubeadm-certs secret.",
|
"Upload control-plane certificates to the kubeadm-certs Secret.",
|
||||||
|
)
|
||||||
|
flagSet.StringVar(
|
||||||
|
&initOptions.certificateKey, options.CertificateKey, "",
|
||||||
|
"Key used to encrypt the control-plane certificates in the kubeadm-certs Secret.",
|
||||||
|
)
|
||||||
|
flagSet.BoolVar(
|
||||||
|
&initOptions.skipCertificateKeyPrint, options.SkipCertificateKeyPrint, initOptions.skipCertificateKeyPrint,
|
||||||
|
"Don't print the key used to encrypt the control-plane certificates.",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,17 +348,19 @@ func newInitData(cmd *cobra.Command, args []string, options *initOptions, out io
|
||||||
}
|
}
|
||||||
|
|
||||||
return &initData{
|
return &initData{
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
certificatesDir: cfg.CertificatesDir,
|
certificatesDir: cfg.CertificatesDir,
|
||||||
skipTokenPrint: options.skipTokenPrint,
|
skipTokenPrint: options.skipTokenPrint,
|
||||||
dryRun: options.dryRun,
|
dryRun: options.dryRun,
|
||||||
dryRunDir: dryRunDir,
|
dryRunDir: dryRunDir,
|
||||||
kubeconfigDir: options.kubeconfigDir,
|
kubeconfigDir: options.kubeconfigDir,
|
||||||
kubeconfigPath: options.kubeconfigPath,
|
kubeconfigPath: options.kubeconfigPath,
|
||||||
ignorePreflightErrors: ignorePreflightErrorsSet,
|
ignorePreflightErrors: ignorePreflightErrorsSet,
|
||||||
externalCA: externalCA,
|
externalCA: externalCA,
|
||||||
outputWriter: out,
|
outputWriter: out,
|
||||||
uploadCerts: options.uploadCerts,
|
uploadCerts: options.uploadCerts,
|
||||||
|
certificateKey: options.certificateKey,
|
||||||
|
skipCertificateKeyPrint: options.skipCertificateKeyPrint,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -472,7 +485,7 @@ func (d *initData) Tokens() []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func printJoinCommand(out io.Writer, adminKubeConfigPath, token string, i *initData) error {
|
func printJoinCommand(out io.Writer, adminKubeConfigPath, token string, i *initData) error {
|
||||||
joinCommand, err := cmdutil.GetJoinCommand(adminKubeConfigPath, token, i.certificateKey, i.skipTokenPrint, i.uploadCerts)
|
joinCommand, err := cmdutil.GetJoinCommand(adminKubeConfigPath, token, i.certificateKey, i.skipTokenPrint, i.uploadCerts, i.skipCertificateKeyPrint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
|
@ -124,4 +124,7 @@ const (
|
||||||
|
|
||||||
// CertificateKey flag sets the key used to encrypt and decrypt certificate secrets
|
// CertificateKey flag sets the key used to encrypt and decrypt certificate secrets
|
||||||
CertificateKey = "certificate-key"
|
CertificateKey = "certificate-key"
|
||||||
|
|
||||||
|
// SkipCertificateKeyPrint flag instruct kubeadm to skip printing certificate key used to encrypt certs by 'kubeadm init'.
|
||||||
|
SkipCertificateKeyPrint = "skip-certificate-key-print"
|
||||||
)
|
)
|
||||||
|
|
|
@ -39,6 +39,7 @@ func NewUploadCertsPhase() workflow.Phase {
|
||||||
InheritFlags: []string{
|
InheritFlags: []string{
|
||||||
options.CfgPath,
|
options.CfgPath,
|
||||||
options.UploadCerts,
|
options.UploadCerts,
|
||||||
|
options.CertificateKey,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -231,7 +231,8 @@ func RunCreateToken(out io.Writer, client clientset.Interface, cfgPath string, c
|
||||||
key := ""
|
key := ""
|
||||||
skipTokenPrint := false
|
skipTokenPrint := false
|
||||||
uploadCerts := false
|
uploadCerts := false
|
||||||
joinCommand, err := cmdutil.GetJoinCommand(kubeConfigFile, internalcfg.BootstrapTokens[0].Token.String(), key, skipTokenPrint, uploadCerts)
|
skipCertificateKeyPrint := false
|
||||||
|
joinCommand, err := cmdutil.GetJoinCommand(kubeConfigFile, internalcfg.BootstrapTokens[0].Token.String(), key, skipTokenPrint, uploadCerts, skipCertificateKeyPrint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "failed to get join command")
|
return errors.Wrap(err, "failed to get join command")
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,12 +30,19 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var joinCommandTemplate = template.Must(template.New("join").Parse(`` +
|
var joinCommandTemplate = template.Must(template.New("join").Parse(`` +
|
||||||
`kubeadm join {{.ControlPlaneHostPort}} --token {{.Token}}{{range $h := .CAPubKeyPins}} --discovery-token-ca-cert-hash {{$h}}{{end}}{{if .UploadCerts}} --certificate-key {{.CertificateKey}}{{end}}`,
|
`{{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}}`,
|
||||||
))
|
))
|
||||||
|
|
||||||
// GetJoinCommand returns the kubeadm join command for a given token and
|
// GetJoinCommand returns the kubeadm join command for a given token and
|
||||||
// and Kubernetes cluster (the current cluster in the kubeconfig file)
|
// and Kubernetes cluster (the current cluster in the kubeconfig file)
|
||||||
func GetJoinCommand(kubeConfigFile, token, key string, skipTokenPrint, uploadCerts bool) (string, error) {
|
func GetJoinCommand(kubeConfigFile, token, key string, skipTokenPrint, uploadCerts, skipCertificateKeyPrint bool) (string, error) {
|
||||||
// load the kubeconfig file to get the CA certificate and endpoint
|
// load the kubeconfig file to get the CA certificate and endpoint
|
||||||
config, err := clientcmd.LoadFromFile(kubeConfigFile)
|
config, err := clientcmd.LoadFromFile(kubeConfigFile)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -81,6 +88,9 @@ func GetJoinCommand(kubeConfigFile, token, key string, skipTokenPrint, uploadCer
|
||||||
if skipTokenPrint {
|
if skipTokenPrint {
|
||||||
ctx["Token"] = template.HTML("<value withheld>")
|
ctx["Token"] = template.HTML("<value withheld>")
|
||||||
}
|
}
|
||||||
|
if skipCertificateKeyPrint {
|
||||||
|
ctx["CertificateKey"] = template.HTML("<value withheld>")
|
||||||
|
}
|
||||||
|
|
||||||
var out bytes.Buffer
|
var out bytes.Buffer
|
||||||
err = joinCommandTemplate.Execute(&out, ctx)
|
err = joinCommandTemplate.Execute(&out, ctx)
|
||||||
|
|
Loading…
Reference in New Issue