From 56ce743f7b68335683eebaec4dfb7cc1804170d4 Mon Sep 17 00:00:00 2001 From: Eric Date: Mon, 6 May 2019 20:53:38 +0800 Subject: [PATCH] kubeadm: fix a bug related to volume unmount if the kubelet run directory is a symbolic link unexpected deleting of contents of mount points due to symbolic link of KubeletRunDirectory --- cmd/kubeadm/app/cmd/reset.go | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/cmd/kubeadm/app/cmd/reset.go b/cmd/kubeadm/app/cmd/reset.go index 9ac3c6d5877..30aa44e7f23 100644 --- a/cmd/kubeadm/app/cmd/reset.go +++ b/cmd/kubeadm/app/cmd/reset.go @@ -179,12 +179,23 @@ func (r *Reset) Run(out io.Writer, client clientset.Interface, cfg *kubeadmapi.I // Try to unmount mounted directories under kubeadmconstants.KubeletRunDirectory in order to be able to remove the kubeadmconstants.KubeletRunDirectory directory later fmt.Printf("[reset] Unmounting mounted directories in %q\n", kubeadmconstants.KubeletRunDirectory) - umountDirsCmd := fmt.Sprintf("awk '$2 ~ path {print $2}' path=%s/ /proc/mounts | xargs -r umount", kubeadmconstants.KubeletRunDirectory) - klog.V(1).Infof("[reset] Executing command %q", umountDirsCmd) - umountOutputBytes, err := exec.Command("sh", "-c", umountDirsCmd).Output() + // In case KubeletRunDirectory holds a symbolic link, evaluate it + var absoluteKubeletRunDirectory string + absoluteKubeletRunDirectory, err = filepath.EvalSymlinks(kubeadmconstants.KubeletRunDirectory) if err != nil { - klog.Errorf("[reset] Failed to unmount mounted directories in %s: %s\n", kubeadmconstants.KubeletRunDirectory, string(umountOutputBytes)) + klog.Errorf("[reset] Failed to evaluate the %q directory. Skipping its unmount and cleanup: %v", kubeadmconstants.KubeletRunDirectory, err) + } else { + // Only unmount mount points which start with "/var/lib/kubelet" or absolute path of symbolic link, and avoid using empty absoluteKubeletRunDirectory + umountDirsCmd := fmt.Sprintf("awk '$2 ~ path {print $2}' path=%s/ /proc/mounts | xargs -r umount", absoluteKubeletRunDirectory) + klog.V(1).Infof("[reset] Executing command %q", umountDirsCmd) + umountOutputBytes, err := exec.Command("sh", "-c", umountDirsCmd).Output() + if err != nil { + klog.Errorf("[reset] Failed to unmount mounted directories in %s: %s\n", kubeadmconstants.KubeletRunDirectory, string(umountOutputBytes)) + } else { + // Only clean absoluteKubeletRunDirectory if umountDirsCmd passed without error + dirsToClean = append(dirsToClean, absoluteKubeletRunDirectory) + } } klog.V(1).Info("[reset] Removing Kubernetes-managed containers") @@ -192,7 +203,7 @@ func (r *Reset) Run(out io.Writer, client clientset.Interface, cfg *kubeadmapi.I klog.Errorf("[reset] Failed to remove containers: %v", err) } - dirsToClean = append(dirsToClean, []string{kubeadmconstants.KubeletRunDirectory, "/etc/cni/net.d", "/var/lib/dockershim", "/var/run/kubernetes"}...) + dirsToClean = append(dirsToClean, []string{"/etc/cni/net.d", "/var/lib/dockershim", "/var/run/kubernetes"}...) // Then clean contents from the stateful kubelet, etcd and cni directories fmt.Printf("[reset] Deleting contents of stateful directories: %v\n", dirsToClean) @@ -217,7 +228,7 @@ func (r *Reset) Run(out io.Writer, client clientset.Interface, cfg *kubeadmapi.I If your cluster was setup to utilize IPVS, run ipvsadm --clear (or similar) to reset your system's IPVS tables. - + The reset process does not clean your kubeconfig files and you must remove them manually. Please, check the contents of the $HOME/.kube/config file. `)