From df477a960fbf316c730a5974971ae886acc9d96e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lucas=20K=C3=A4ldstr=C3=B6m?= Date: Sat, 16 Jun 2018 23:45:26 +0300 Subject: [PATCH] kubeadm: Make the environment file writing happen on upgrade as well --- cmd/kubeadm/app/phases/upgrade/postupgrade.go | 52 ++++++++++++++----- cmd/kubeadm/app/util/dryrun/dryrun.go | 8 +++ 2 files changed, 47 insertions(+), 13 deletions(-) diff --git a/cmd/kubeadm/app/phases/upgrade/postupgrade.go b/cmd/kubeadm/app/phases/upgrade/postupgrade.go index e91a024b00b..15a0b2f5ca6 100644 --- a/cmd/kubeadm/app/phases/upgrade/postupgrade.go +++ b/cmd/kubeadm/app/phases/upgrade/postupgrade.go @@ -65,19 +65,8 @@ func PerformPostUpgradeTasks(client clientset.Interface, cfg *kubeadmapi.MasterC errs = append(errs, fmt.Errorf("error creating kubelet configuration ConfigMap: %v", err)) } - kubeletDir, err := getKubeletDir(dryRun) - if err == nil { - // Write the configuration for the kubelet down to disk so the upgraded kubelet can start with fresh config - if err := kubeletphase.DownloadConfig(client, newK8sVer, kubeletDir); err != nil { - // Tolerate the error being NotFound when dryrunning, as there is a pretty common scenario: the dryrun process - // *would* post the new kubelet-config-1.X configmap that doesn't exist now when we're trying to download it - // again. - if !(apierrors.IsNotFound(err) && dryRun) { - errs = append(errs, fmt.Errorf("error downloading kubelet configuration from the ConfigMap: %v", err)) - } - } - } else { - // The error here should never occur in reality, would only be thrown if /tmp doesn't exist on the machine. + // Write the new kubelet config down to disk and the env file if needed + if err := writeKubeletConfigFiles(client, cfg, newK8sVer, dryRun); err != nil { errs = append(errs, err) } @@ -209,6 +198,43 @@ func backupAPIServerCertIfNeeded(cfg *kubeadmapi.MasterConfiguration, dryRun boo return certsphase.CreateAPIServerCertAndKeyFiles(cfg) } +func writeKubeletConfigFiles(client clientset.Interface, cfg *kubeadmapi.MasterConfiguration, newK8sVer *version.Version, dryRun bool) error { + kubeletDir, err := getKubeletDir(dryRun) + if err != nil { + // The error here should never occur in reality, would only be thrown if /tmp doesn't exist on the machine. + return err + } + errs := []error{} + // Write the configuration for the kubelet down to disk so the upgraded kubelet can start with fresh config + if err := kubeletphase.DownloadConfig(client, newK8sVer, kubeletDir); err != nil { + // Tolerate the error being NotFound when dryrunning, as there is a pretty common scenario: the dryrun process + // *would* post the new kubelet-config-1.X configmap that doesn't exist now when we're trying to download it + // again. + if !(apierrors.IsNotFound(err) && dryRun) { + errs = append(errs, fmt.Errorf("error downloading kubelet configuration from the ConfigMap: %v", err)) + } + } + + if dryRun { // Print what contents would be written + dryrunutil.PrintDryRunFile(kubeadmconstants.KubeletConfigurationFileName, kubeletDir, kubeadmconstants.KubeletRunDirectory, os.Stdout) + } + + envFilePath := filepath.Join(kubeadmconstants.KubeletRunDirectory, kubeadmconstants.KubeletEnvFileName) + if _, err := os.Stat(envFilePath); os.IsNotExist(err) { + // Write env file with flags for the kubelet to use. We do not need to write the --register-with-taints for the master, + // as we handle that ourselves in the markmaster phase + // TODO: Maybe we want to do that some time in the future, in order to remove some logic from the markmaster phase? + if err := kubeletphase.WriteKubeletDynamicEnvFile(&cfg.NodeRegistration, cfg.FeatureGates, false, kubeletDir); err != nil { + errs = append(errs, fmt.Errorf("error writing a dynamic environment file for the kubelet: %v", err)) + } + + if dryRun { // Print what contents would be written + dryrunutil.PrintDryRunFile(kubeadmconstants.KubeletEnvFileName, kubeletDir, kubeadmconstants.KubeletRunDirectory, os.Stdout) + } + } + return errors.NewAggregate(errs) +} + // getWaiter gets the right waiter implementation for the right occasion // TODO: Consolidate this with what's in init.go? func getWaiter(dryRun bool, client clientset.Interface) apiclient.Waiter { diff --git a/cmd/kubeadm/app/util/dryrun/dryrun.go b/cmd/kubeadm/app/util/dryrun/dryrun.go index 0dcdb6ccb55..7c18df0672a 100644 --- a/cmd/kubeadm/app/util/dryrun/dryrun.go +++ b/cmd/kubeadm/app/util/dryrun/dryrun.go @@ -20,6 +20,7 @@ import ( "fmt" "io" "io/ioutil" + "path/filepath" "time" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -43,6 +44,13 @@ func NewFileToPrint(realPath, printPath string) FileToPrint { } } +// PrintDryRunFile is a helper method around PrintDryRunFiles +func PrintDryRunFile(fileName, realDir, printDir string, w io.Writer) error { + return PrintDryRunFiles([]FileToPrint{ + NewFileToPrint(filepath.Join(realDir, fileName), filepath.Join(printDir, fileName)), + }, w) +} + // PrintDryRunFiles prints the contents of the FileToPrints given to it to the writer w func PrintDryRunFiles(files []FileToPrint, w io.Writer) error { errs := []error{}