From c55a98fde9d0055b33df1b9e1ffa4596358259d7 Mon Sep 17 00:00:00 2001 From: Dave Chen Date: Mon, 26 Dec 2022 16:06:15 +0800 Subject: [PATCH] kubeadm: fix `invalid cross-device link` error The root cause for that error is because `rename` doesn't work across different mount points. The kubelet config file and back up directory are mounted to different file system in kinder environment. ``` df /var/lib/kubelet/config.yaml | tail -n1 | awk '{print $1}' /dev/sda2 df /etc/kubernetes/tmp/kubeadm-kubelet-configxxx | tail -n1 | awk '{print $1}' overlay ``` Call `cp` instead of `rename` to back up the kubelet file would fix that issue. Signed-off-by: Dave Chen --- .../app/cmd/phases/upgrade/node/kubeletconfig.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/cmd/kubeadm/app/cmd/phases/upgrade/node/kubeletconfig.go b/cmd/kubeadm/app/cmd/phases/upgrade/node/kubeletconfig.go index 2eb50565203..196e6352f3d 100644 --- a/cmd/kubeadm/app/cmd/phases/upgrade/node/kubeletconfig.go +++ b/cmd/kubeadm/app/cmd/phases/upgrade/node/kubeletconfig.go @@ -29,6 +29,7 @@ import ( "k8s.io/kubernetes/cmd/kubeadm/app/constants" kubeletphase "k8s.io/kubernetes/cmd/kubeadm/app/phases/kubelet" "k8s.io/kubernetes/cmd/kubeadm/app/phases/upgrade" + kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util" dryrunutil "k8s.io/kubernetes/cmd/kubeadm/app/util/dryrun" ) @@ -80,8 +81,13 @@ func runKubeletConfigPhase() func(c workflow.RunData) error { dest := filepath.Join(backupDir, constants.KubeletConfigurationFileName) if !dryRun { fmt.Printf("[upgrade] Backing up kubelet config file to %s\n", dest) - if err := os.Rename(src, dest); err != nil { - return errors.Wrap(err, "error backing up the kubelet config file") + // call `cp` instead of `rename` here since the kubelet config file and back up directory (/etc/kubernetes/tmp/) + // might on the filesystem with differnt mount points in the test environment, such as kinder. + // This will lead to a failure to move the file from the source to dest since `rename` normally doesn't work + // across different mount points on most Unix system. + output, err := kubeadmutil.CopyDir(src, dest) + if err != nil { + return errors.Wrapf(err, "error backing up the kubelet config file, output: %q", output) } } else { fmt.Printf("[dryrun] Would back up kubelet config file to %s\n", dest)