mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-24 20:24:09 +00:00
Merge pull request #107512 from SataQiu/support-reset-dryrun-20220113
kubeadm reset: add support for dry-run
This commit is contained in:
commit
19a37027dc
@ -63,40 +63,55 @@ func runCleanupNode(c workflow.RunData) error {
|
|||||||
klog.Warningln("[reset] The kubelet service could not be stopped by kubeadm. Unable to detect a supported init system!")
|
klog.Warningln("[reset] The kubelet service could not be stopped by kubeadm. Unable to detect a supported init system!")
|
||||||
klog.Warningln("[reset] Please ensure kubelet is stopped manually")
|
klog.Warningln("[reset] Please ensure kubelet is stopped manually")
|
||||||
} else {
|
} else {
|
||||||
fmt.Println("[reset] Stopping the kubelet service")
|
if !r.DryRun() {
|
||||||
if err := initSystem.ServiceStop("kubelet"); err != nil {
|
fmt.Println("[reset] Stopping the kubelet service")
|
||||||
klog.Warningf("[reset] The kubelet service could not be stopped by kubeadm: [%v]\n", err)
|
if err := initSystem.ServiceStop("kubelet"); err != nil {
|
||||||
klog.Warningln("[reset] Please ensure kubelet is stopped manually")
|
klog.Warningf("[reset] The kubelet service could not be stopped by kubeadm: [%v]\n", err)
|
||||||
|
klog.Warningln("[reset] Please ensure kubelet is stopped manually")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Println("[reset] Would stop the kubelet service")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to unmount mounted directories under kubeadmconstants.KubeletRunDirectory in order to be able to remove the kubeadmconstants.KubeletRunDirectory directory later
|
if !r.DryRun() {
|
||||||
fmt.Printf("[reset] Unmounting mounted directories in %q\n", kubeadmconstants.KubeletRunDirectory)
|
// Try to unmount mounted directories under kubeadmconstants.KubeletRunDirectory in order to be able to remove the kubeadmconstants.KubeletRunDirectory directory later
|
||||||
// In case KubeletRunDirectory holds a symbolic link, evaluate it
|
fmt.Printf("[reset] Unmounting mounted directories in %q\n", kubeadmconstants.KubeletRunDirectory)
|
||||||
kubeletRunDir, err := absoluteKubeletRunDirectory()
|
// In case KubeletRunDirectory holds a symbolic link, evaluate it
|
||||||
if err == nil {
|
kubeletRunDir, err := absoluteKubeletRunDirectory()
|
||||||
// Only clean absoluteKubeletRunDirectory if umountDirsCmd passed without error
|
if err == nil {
|
||||||
r.AddDirsToClean(kubeletRunDir)
|
// Only clean absoluteKubeletRunDirectory if umountDirsCmd passed without error
|
||||||
|
r.AddDirsToClean(kubeletRunDir)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Printf("[reset] Would unmount mounted directories in %q\n", kubeadmconstants.KubeletRunDirectory)
|
||||||
}
|
}
|
||||||
|
|
||||||
klog.V(1).Info("[reset] Removing Kubernetes-managed containers")
|
if !r.DryRun() {
|
||||||
if err := removeContainers(utilsexec.New(), r.CRISocketPath()); err != nil {
|
klog.V(1).Info("[reset] Removing Kubernetes-managed containers")
|
||||||
klog.Warningf("[reset] Failed to remove containers: %v\n", err)
|
if err := removeContainers(utilsexec.New(), r.CRISocketPath()); err != nil {
|
||||||
|
klog.Warningf("[reset] Failed to remove containers: %v\n", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Println("[reset] Would remove Kubernetes-managed containers")
|
||||||
}
|
}
|
||||||
|
|
||||||
r.AddDirsToClean("/var/lib/dockershim", "/var/run/kubernetes", "/var/lib/cni")
|
r.AddDirsToClean("/var/lib/dockershim", "/var/run/kubernetes", "/var/lib/cni")
|
||||||
|
|
||||||
// Remove contents from the config and pki directories
|
// Remove contents from the config and pki directories
|
||||||
klog.V(1).Infoln("[reset] Removing contents from the config and pki directories")
|
|
||||||
if certsDir != kubeadmapiv1.DefaultCertificatesDir {
|
if certsDir != kubeadmapiv1.DefaultCertificatesDir {
|
||||||
klog.Warningf("[reset] WARNING: Cleaning a non-default certificates directory: %q\n", certsDir)
|
klog.Warningf("[reset] WARNING: Cleaning a non-default certificates directory: %q\n", certsDir)
|
||||||
}
|
}
|
||||||
resetConfigDir(kubeadmconstants.KubernetesDir, certsDir)
|
resetConfigDir(kubeadmconstants.KubernetesDir, certsDir, r.DryRun())
|
||||||
|
|
||||||
if r.Cfg() != nil && features.Enabled(r.Cfg().FeatureGates, features.RootlessControlPlane) {
|
if r.Cfg() != nil && features.Enabled(r.Cfg().FeatureGates, features.RootlessControlPlane) {
|
||||||
klog.V(1).Infoln("[reset] Removing users and groups created for rootless control-plane")
|
if !r.DryRun() {
|
||||||
if err := users.RemoveUsersAndGroups(); err != nil {
|
klog.V(1).Infoln("[reset] Removing users and groups created for rootless control-plane")
|
||||||
klog.Warningf("[reset] Failed to remove users and groups: %v\n", err)
|
if err := users.RemoveUsersAndGroups(); err != nil {
|
||||||
|
klog.Warningf("[reset] Failed to remove users and groups: %v\n", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Println("[reset] Would remove users and groups created for rootless control-plane")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,16 +145,20 @@ func removeContainers(execer utilsexec.Interface, criSocketPath string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// resetConfigDir is used to cleanup the files kubeadm writes in /etc/kubernetes/.
|
// resetConfigDir is used to cleanup the files kubeadm writes in /etc/kubernetes/.
|
||||||
func resetConfigDir(configPathDir, pkiPathDir string) {
|
func resetConfigDir(configPathDir, pkiPathDir string, isDryRun bool) {
|
||||||
dirsToClean := []string{
|
dirsToClean := []string{
|
||||||
filepath.Join(configPathDir, kubeadmconstants.ManifestsSubDirName),
|
filepath.Join(configPathDir, kubeadmconstants.ManifestsSubDirName),
|
||||||
pkiPathDir,
|
pkiPathDir,
|
||||||
}
|
}
|
||||||
fmt.Printf("[reset] Deleting contents of config directories: %v\n", dirsToClean)
|
if !isDryRun {
|
||||||
for _, dir := range dirsToClean {
|
fmt.Printf("[reset] Deleting contents of directories: %v\n", dirsToClean)
|
||||||
if err := CleanDir(dir); err != nil {
|
for _, dir := range dirsToClean {
|
||||||
klog.Warningf("[reset] Failed to delete contents of %q directory: %v", dir, err)
|
if err := CleanDir(dir); err != nil {
|
||||||
|
klog.Warningf("[reset] Failed to delete contents of %q directory: %v", dir, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Printf("[reset] Would delete contents of directories: %v\n", dirsToClean)
|
||||||
}
|
}
|
||||||
|
|
||||||
filesToClean := []string{
|
filesToClean := []string{
|
||||||
@ -149,11 +168,16 @@ func resetConfigDir(configPathDir, pkiPathDir string) {
|
|||||||
filepath.Join(configPathDir, kubeadmconstants.ControllerManagerKubeConfigFileName),
|
filepath.Join(configPathDir, kubeadmconstants.ControllerManagerKubeConfigFileName),
|
||||||
filepath.Join(configPathDir, kubeadmconstants.SchedulerKubeConfigFileName),
|
filepath.Join(configPathDir, kubeadmconstants.SchedulerKubeConfigFileName),
|
||||||
}
|
}
|
||||||
fmt.Printf("[reset] Deleting files: %v\n", filesToClean)
|
|
||||||
for _, path := range filesToClean {
|
if !isDryRun {
|
||||||
if err := os.RemoveAll(path); err != nil {
|
fmt.Printf("[reset] Deleting files: %v\n", filesToClean)
|
||||||
klog.Warningf("[reset] Failed to remove file: %q [%v]\n", path, err)
|
for _, path := range filesToClean {
|
||||||
|
if err := os.RemoveAll(path); err != nil {
|
||||||
|
klog.Warningf("[reset] Failed to remove file: %q [%v]\n", path, err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Printf("[reset] Would delete files: %v\n", filesToClean)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -174,7 +174,7 @@ func TestConfigDirCleaner(t *testing.T) {
|
|||||||
if test.resetDir == "" {
|
if test.resetDir == "" {
|
||||||
test.resetDir = "pki"
|
test.resetDir = "pki"
|
||||||
}
|
}
|
||||||
resetConfigDir(tmpDir, filepath.Join(tmpDir, test.resetDir))
|
resetConfigDir(tmpDir, filepath.Join(tmpDir, test.resetDir), false)
|
||||||
|
|
||||||
// Verify the files we cleanup implicitly in every test:
|
// Verify the files we cleanup implicitly in every test:
|
||||||
assertExists(t, tmpDir)
|
assertExists(t, tmpDir)
|
||||||
|
@ -32,6 +32,7 @@ type resetData interface {
|
|||||||
InputReader() io.Reader
|
InputReader() io.Reader
|
||||||
IgnorePreflightErrors() sets.String
|
IgnorePreflightErrors() sets.String
|
||||||
Cfg() *kubeadmapi.InitConfiguration
|
Cfg() *kubeadmapi.InitConfiguration
|
||||||
|
DryRun() bool
|
||||||
Client() clientset.Interface
|
Client() clientset.Interface
|
||||||
AddDirsToClean(dirs ...string)
|
AddDirsToClean(dirs ...string)
|
||||||
CertificatesDir() string
|
CertificatesDir() string
|
||||||
|
@ -58,8 +58,12 @@ func runRemoveETCDMemberPhase(c workflow.RunData) error {
|
|||||||
if err == nil {
|
if err == nil {
|
||||||
r.AddDirsToClean(etcdDataDir)
|
r.AddDirsToClean(etcdDataDir)
|
||||||
if cfg != nil {
|
if cfg != nil {
|
||||||
if err := etcdphase.RemoveStackedEtcdMemberFromCluster(r.Client(), cfg); err != nil {
|
if !r.DryRun() {
|
||||||
klog.Warningf("[reset] failed to remove etcd member: %v, please manually remove this etcd member using etcdctl", err)
|
if err := etcdphase.RemoveStackedEtcdMemberFromCluster(r.Client(), cfg); err != nil {
|
||||||
|
klog.Warningf("[reset] Failed to remove etcd member: %v, please manually remove this etcd member using etcdctl", err)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Println("[reset] Would remove the etcd member on this node from the etcd cluster")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -64,6 +64,7 @@ type resetOptions struct {
|
|||||||
forceReset bool
|
forceReset bool
|
||||||
ignorePreflightErrors []string
|
ignorePreflightErrors []string
|
||||||
kubeconfigPath string
|
kubeconfigPath string
|
||||||
|
dryRun bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// resetData defines all the runtime information used when running the kubeadm reset workflow;
|
// resetData defines all the runtime information used when running the kubeadm reset workflow;
|
||||||
@ -78,6 +79,7 @@ type resetData struct {
|
|||||||
outputWriter io.Writer
|
outputWriter io.Writer
|
||||||
cfg *kubeadmapi.InitConfiguration
|
cfg *kubeadmapi.InitConfiguration
|
||||||
dirsToClean []string
|
dirsToClean []string
|
||||||
|
dryRun bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// newResetOptions returns a struct ready for being used for creating cmd join flags.
|
// newResetOptions returns a struct ready for being used for creating cmd join flags.
|
||||||
@ -134,6 +136,7 @@ func newResetData(cmd *cobra.Command, options *resetOptions, in io.Reader, out i
|
|||||||
inputReader: in,
|
inputReader: in,
|
||||||
outputWriter: out,
|
outputWriter: out,
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
|
dryRun: options.dryRun,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,6 +157,10 @@ func AddResetFlags(flagSet *flag.FlagSet, resetOptions *resetOptions) {
|
|||||||
&resetOptions.forceReset, options.ForceReset, "f", false,
|
&resetOptions.forceReset, options.ForceReset, "f", false,
|
||||||
"Reset the node without prompting for confirmation.",
|
"Reset the node without prompting for confirmation.",
|
||||||
)
|
)
|
||||||
|
flagSet.BoolVar(
|
||||||
|
&resetOptions.dryRun, options.DryRun, resetOptions.dryRun,
|
||||||
|
"Don't apply any changes; just output what would be done.",
|
||||||
|
)
|
||||||
|
|
||||||
options.AddKubeConfigFlag(flagSet, &resetOptions.kubeconfigPath)
|
options.AddKubeConfigFlag(flagSet, &resetOptions.kubeconfigPath)
|
||||||
options.AddIgnorePreflightErrorsFlag(flagSet, &resetOptions.ignorePreflightErrors)
|
options.AddIgnorePreflightErrorsFlag(flagSet, &resetOptions.ignorePreflightErrors)
|
||||||
@ -214,6 +221,11 @@ func newCmdReset(in io.Reader, out io.Writer, resetOptions *resetOptions) *cobra
|
|||||||
}
|
}
|
||||||
|
|
||||||
func cleanDirs(data *resetData) {
|
func cleanDirs(data *resetData) {
|
||||||
|
if data.DryRun() {
|
||||||
|
fmt.Printf("[reset] Would delete contents of stateful directories: %v\n", data.dirsToClean)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Printf("[reset] Deleting contents of stateful directories: %v\n", data.dirsToClean)
|
fmt.Printf("[reset] Deleting contents of stateful directories: %v\n", data.dirsToClean)
|
||||||
for _, dir := range data.dirsToClean {
|
for _, dir := range data.dirsToClean {
|
||||||
klog.V(1).Infof("[reset] Deleting contents of %s", dir)
|
klog.V(1).Infof("[reset] Deleting contents of %s", dir)
|
||||||
@ -228,6 +240,11 @@ func (r *resetData) Cfg() *kubeadmapi.InitConfiguration {
|
|||||||
return r.cfg
|
return r.cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DryRun returns the DryRun flag.
|
||||||
|
func (r *resetData) DryRun() bool {
|
||||||
|
return r.dryRun
|
||||||
|
}
|
||||||
|
|
||||||
// CertificatesDir returns the CertificatesDir.
|
// CertificatesDir returns the CertificatesDir.
|
||||||
func (r *resetData) CertificatesDir() string {
|
func (r *resetData) CertificatesDir() string {
|
||||||
return r.certificatesDir
|
return r.certificatesDir
|
||||||
|
Loading…
Reference in New Issue
Block a user