Skip to content

Commit

Permalink
Merge pull request #2547 from twz123/ignore-join-token-when-bootstrapped
Browse files Browse the repository at this point in the history
Restore correct auth source precedence for kubelet bootstrapping
  • Loading branch information
twz123 authored Dec 22, 2022
2 parents c08eba0 + 417f967 commit bb33d05
Showing 1 changed file with 31 additions and 15 deletions.
46 changes: 31 additions & 15 deletions pkg/component/worker/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,49 +44,65 @@ import (
)

func BootstrapKubeletKubeconfig(ctx context.Context, k0sVars constant.CfgVars, workerOpts *config.WorkerOptions) error {
var bootstrapKubeconfigPath string
var bootstrapKubeconfig *clientcmdapi.Config

if workerOpts.TokenArg == "" {
if file.Exists(k0sVars.KubeletAuthConfigPath) {
// Regular kubelet kubeconfig file exists, nothing to do.
return nil
}
bootstrapKubeconfigPath := filepath.Join(k0sVars.DataDir, "kubelet-bootstrap.conf")

// Fallback to bootstrap kubeconfig file, if it exists.
bootstrapKubeconfigPath = filepath.Join(k0sVars.DataDir, "kubelet-bootstrap.conf")
if !file.Exists(bootstrapKubeconfigPath) {
return fmt.Errorf("neither regular nor bootstrap kubelet kubeconfig files exist and no join token given; dunno how to make kubelet authenticate to API server")
}
// When using `k0s install` along with a join token, that join token
// argument will be registered within the k0s service definition and be
// passed to k0s each time it gets started as a service. Hence that token
// needs to be ignored if it has already been used. This results in the
// following order of precedence:

var bootstrapKubeconfig *clientcmdapi.Config
switch {
// 1: Regular kubelet kubeconfig file exists.
// The kubelet kubeconfig has been bootstrapped already.
case file.Exists(k0sVars.KubeletAuthConfigPath):
return nil

// 2: Kubelet bootstrap kubeconfig file exists.
// The kubelet kubeconfig will be bootstrapped without a join token.
case file.Exists(bootstrapKubeconfigPath):
var err error
bootstrapKubeconfig, err = clientcmd.LoadFromFile(bootstrapKubeconfigPath)
if err != nil {
return fmt.Errorf("failed to parse kubelet bootstrap kubeconfig from file: %w", err)
}
} else {

// 3: A join token has been given.
// Bootstrap the kubelet kubeconfig via the embedded bootstrap config.
case workerOpts.TokenArg != "":
// Join token given, so use that.
kubeconfig, err := token.DecodeJoinToken(workerOpts.TokenArg)
if err != nil {
return fmt.Errorf("failed to decode join token: %w", err)
}

// Load the bootstrap kubeconfig to validate it
// Load the bootstrap kubeconfig to validate it.
bootstrapKubeconfig, err = clientcmd.Load(kubeconfig)
if err != nil {
return fmt.Errorf("failed to parse kubelet bootstrap kubeconfig from join token: %w", err)
}

// Write the kubelet bootstrap kubeconfig to a temporary file, as the
// kubelet bootstrap API only accepts files.
bootstrapKubeconfigPath, err = writeKubeletBootstrapKubeconfig(kubeconfig)
if err != nil {
return fmt.Errorf("failed to write kubelet bootstrap kubeconfig: %w", err)
}

// Ensure that the temporary kubelet bootstrap kubeconfig file will be
// removed when done.
defer func() {
if err := os.Remove(bootstrapKubeconfigPath); err != nil && !os.IsNotExist(err) {
logrus.WithError(err).Error("Failed to remove kubelet bootstrap kubeconfig file")
}
}()

logrus.Debug("Wrote kubelet bootstrap kubeconfig file: ", bootstrapKubeconfigPath)

// 4: None of the above, bail out.
default:
return fmt.Errorf("neither regular nor bootstrap kubelet kubeconfig files exist and no join token given; dunno how to make kubelet authenticate to API server")
}

kubeletCAPath := path.Join(k0sVars.CertRootDir, "ca.crt")
Expand Down

0 comments on commit bb33d05

Please sign in to comment.