diff --git a/clients/clientset/versioned/fake/register.go b/clients/clientset/versioned/fake/register.go index 17efe1d9..06bd088b 100644 --- a/clients/clientset/versioned/fake/register.go +++ b/clients/clientset/versioned/fake/register.go @@ -38,14 +38,14 @@ var localSchemeBuilder = runtime.SchemeBuilder{ // AddToScheme adds all types of this clientset into the given scheme. This allows composition // of clientsets, like in: // -// import ( -// "k8s.io/client-go/kubernetes" -// clientsetscheme "k8s.io/client-go/kubernetes/scheme" -// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" -// ) +// import ( +// "k8s.io/client-go/kubernetes" +// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" +// ) // -// kclientset, _ := kubernetes.NewForConfig(c) -// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) +// kclientset, _ := kubernetes.NewForConfig(c) +// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) // // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types // correctly. diff --git a/clients/clientset/versioned/scheme/register.go b/clients/clientset/versioned/scheme/register.go index 42d22e32..a8226fd7 100644 --- a/clients/clientset/versioned/scheme/register.go +++ b/clients/clientset/versioned/scheme/register.go @@ -38,14 +38,14 @@ var localSchemeBuilder = runtime.SchemeBuilder{ // AddToScheme adds all types of this clientset into the given scheme. This allows composition // of clientsets, like in: // -// import ( -// "k8s.io/client-go/kubernetes" -// clientsetscheme "k8s.io/client-go/kubernetes/scheme" -// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" -// ) +// import ( +// "k8s.io/client-go/kubernetes" +// clientsetscheme "k8s.io/client-go/kubernetes/scheme" +// aggregatorclientsetscheme "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset/scheme" +// ) // -// kclientset, _ := kubernetes.NewForConfig(c) -// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) +// kclientset, _ := kubernetes.NewForConfig(c) +// _ = aggregatorclientsetscheme.AddToScheme(clientsetscheme.Scheme) // // After this, RawExtensions in Kubernetes types will serialize kube-aggregator types // correctly. diff --git a/cmd/ctl/delete/delete_cluster.go b/cmd/ctl/delete/delete_cluster.go index 62d8136d..3285c557 100644 --- a/cmd/ctl/delete/delete_cluster.go +++ b/cmd/ctl/delete/delete_cluster.go @@ -28,6 +28,7 @@ type DeleteClusterOptions struct { CommonOptions *options.CommonOptions ClusterCfgFile string Kubernetes string + DeleteCRI bool } func NewDeleteClusterOptions() *DeleteClusterOptions { @@ -57,6 +58,7 @@ func (o *DeleteClusterOptions) Run() error { FilePath: o.ClusterCfgFile, Debug: o.CommonOptions.Verbose, KubernetesVersion: o.Kubernetes, + DeleteCRI: o.DeleteCRI, } return pipelines.DeleteCluster(arg) } @@ -64,4 +66,5 @@ func (o *DeleteClusterOptions) Run() error { func (o *DeleteClusterOptions) AddFlags(cmd *cobra.Command) { cmd.Flags().StringVarP(&o.ClusterCfgFile, "filename", "f", "", "Path to a configuration file") cmd.Flags().StringVarP(&o.Kubernetes, "with-kubernetes", "", "", "Specify a supported version of kubernetes") + cmd.Flags().BoolVarP(&o.DeleteCRI, "all", "A", false, "Delete total cri conficutation and data directories") } diff --git a/docs/commands/kk-delete-cluster.md b/docs/commands/kk-delete-cluster.md index 8c4212c0..fa705378 100644 --- a/docs/commands/kk-delete-cluster.md +++ b/docs/commands/kk-delete-cluster.md @@ -12,6 +12,9 @@ Print detailed information. The default is `false`. ## **--filename, -f** Path to a configuration file. +## **--all, -A** +Delete all CRI(docker/containerd) related files and directories. + # EXAMPLES Delete an `all-in-one` cluster. ``` @@ -21,4 +24,9 @@ Delete a cluster from a specified configuration file. ``` $ kk delete cluster -f config-example.yaml ``` +Delete a cluster included CRI related files and directories from a specified configuraion file. +``` +$ kk delete cluster -f config-example.yaml --all +$ kk delete cluster -f config-example.yaml -A +``` diff --git a/pkg/common/kube_runtime.go b/pkg/common/kube_runtime.go index ab648341..ad6fbd80 100644 --- a/pkg/common/kube_runtime.go +++ b/pkg/common/kube_runtime.go @@ -52,6 +52,7 @@ type Argument struct { InstallPackages bool ImagesDir string Namespace string + DeleteCRI bool } func NewKubeRuntime(flag string, arg Argument) (*KubeRuntime, error) { diff --git a/pkg/container/containerd.go b/pkg/container/containerd.go index 10f92b16..7648061e 100644 --- a/pkg/container/containerd.go +++ b/pkg/container/containerd.go @@ -18,12 +18,14 @@ package container import ( "fmt" + "path/filepath" + "github.com/kubesphere/kubekey/pkg/common" + "github.com/kubesphere/kubekey/pkg/container/templates" "github.com/kubesphere/kubekey/pkg/core/connector" "github.com/kubesphere/kubekey/pkg/files" "github.com/kubesphere/kubekey/pkg/utils" "github.com/pkg/errors" - "path/filepath" ) type SyncContainerd struct { @@ -132,3 +134,35 @@ func (e *EnableContainerd) Execute(runtime connector.Runtime) error { } return nil } + +type DisableContainerd struct { + common.KubeAction +} + +func (d *DisableContainerd) Execute(runtime connector.Runtime) error { + if _, err := runtime.GetRunner().SudoCmd( + "systemctl disable containerd && systemctl stop containerd", true); err != nil { + return errors.Wrap(errors.WithStack(err), fmt.Sprintf("disable and stop containerd failed")) + } + + // remove containerd related files + files := []string{ + "/usr/local/sbin/runc", + "/usr/bin/crictl", + "/usr/bin/containerd*", + "/usr/bin/ctr", + filepath.Join("/etc/systemd/system", templates.ContainerdService.Name()), + filepath.Join("/etc/containerd", templates.ContainerdConfig.Name()), + filepath.Join("/etc", templates.CrictlConfig.Name()), + } + if d.KubeConf.Cluster.Registry.DataRoot != "" { + files = append(files, d.KubeConf.Cluster.Registry.DataRoot) + } else { + files = append(files, "/var/lib/containerd") + } + + for _, file := range files { + _, _ = runtime.GetRunner().SudoCmd(fmt.Sprintf("rm -rf %s", file), true) + } + return nil +} diff --git a/pkg/container/docker.go b/pkg/container/docker.go index f02a20ac..e399b53a 100644 --- a/pkg/container/docker.go +++ b/pkg/container/docker.go @@ -18,10 +18,12 @@ package container import ( "fmt" - "github.com/kubesphere/kubekey/pkg/registry" "path/filepath" "strings" + "github.com/kubesphere/kubekey/pkg/container/templates" + "github.com/kubesphere/kubekey/pkg/registry" + "github.com/kubesphere/kubekey/pkg/common" "github.com/kubesphere/kubekey/pkg/core/connector" "github.com/kubesphere/kubekey/pkg/files" @@ -106,3 +108,34 @@ func (p *DockerLoginRegistry) Execute(runtime connector.Runtime) error { return nil } + +type DisableDocker struct { + common.KubeAction +} + +func (d *DisableDocker) Execute(runtime connector.Runtime) error { + if _, err := runtime.GetRunner().SudoCmd("systemctl disable docker && systemctl stop docker", + false); err != nil { + return errors.Wrap(errors.WithStack(err), fmt.Sprintf("disable and stop docker failed")) + } + + // remove docker related files + files := []string{ + "/usr/bin/runc", + "/usr/bin/ctr", + "/usr/bin/docker*", + "/usr/bin/containerd*", + filepath.Join("/etc/systemd/system", templates.DockerService.Name()), + filepath.Join("/etc/docker", templates.DockerConfig.Name()), + } + if d.KubeConf.Cluster.Registry.DataRoot != "" { + files = append(files, d.KubeConf.Cluster.Registry.DataRoot) + } else { + files = append(files, "/var/lib/docker") + } + + for _, file := range files { + _, _ = runtime.GetRunner().SudoCmd(fmt.Sprintf("rm -rf %s", file), true) + } + return nil +} diff --git a/pkg/container/module.go b/pkg/container/module.go index e88f478c..9a481553 100644 --- a/pkg/container/module.go +++ b/pkg/container/module.go @@ -17,10 +17,11 @@ package container import ( - "github.com/kubesphere/kubekey/pkg/registry" "path/filepath" "strings" + "github.com/kubesphere/kubekey/pkg/registry" + "github.com/kubesphere/kubekey/pkg/common" "github.com/kubesphere/kubekey/pkg/container/templates" "github.com/kubesphere/kubekey/pkg/core/action" @@ -244,3 +245,65 @@ func InstallContainerd(m *InstallContainerModule) []task.Interface { enableContainerd, } } + +type UninstallContainerModule struct { + common.KubeModule + Skip bool +} + +func (i *UninstallContainerModule) IsSkip() bool { + return i.Skip +} + +func (i *UninstallContainerModule) Init() { + i.Name = "UninstallContainerModule" + i.Desc = "Uninstall container manager" + + switch i.KubeConf.Cluster.Kubernetes.ContainerManager { + case common.Docker: + i.Tasks = UninstallDocker(i) + case common.Conatinerd: + i.Tasks = UninstallContainerd(i) + case common.Crio: + // TODO: Add the steps of cri-o's installation. + case common.Isula: + // TODO: Add the steps of iSula's installation. + default: + logger.Log.Fatalf("Unsupported container runtime: %s", strings.TrimSpace(i.KubeConf.Cluster.Kubernetes.ContainerManager)) + } +} + +func UninstallDocker(m *UninstallContainerModule) []task.Interface { + + disableDocker := &task.RemoteTask{ + Name: "DisableDocker", + Desc: "Disable docker", + Hosts: m.Runtime.GetHostsByRole(common.K8s), + Prepare: &prepare.PrepareCollection{ + &DockerExist{Not: false}, + }, + Action: new(DisableDocker), + Parallel: true, + } + + return []task.Interface{ + disableDocker, + } +} + +func UninstallContainerd(m *UninstallContainerModule) []task.Interface { + disableContainerd := &task.RemoteTask{ + Name: "UninstallContainerd", + Desc: "Uninstall containerd", + Hosts: m.Runtime.GetHostsByRole(common.K8s), + Prepare: &prepare.PrepareCollection{ + &ContainerdExist{Not: false}, + }, + Action: new(DisableContainerd), + Parallel: true, + } + + return []task.Interface{ + disableContainerd, + } +} diff --git a/pkg/core/util/file.go b/pkg/core/util/file.go index be0c5fb1..433adeb9 100644 --- a/pkg/core/util/file.go +++ b/pkg/core/util/file.go @@ -82,7 +82,7 @@ func CountDirFiles(dirName string) int { return count } -//FileMD5 count file md5 +// FileMD5 count file md5 func FileMD5(path string) (string, error) { file, err := os.Open(path) if err != nil { diff --git a/pkg/images/utils.go b/pkg/images/utils.go index 6f4ca4a6..4bb41c0d 100644 --- a/pkg/images/utils.go +++ b/pkg/images/utils.go @@ -139,7 +139,8 @@ func isKnownArch(arch string) bool { // ParseImageTag // Get a repos name and returns the right reposName + tag // The tag can be confusing because of a port in a repository name. -// Ex: localhost.localdomain:5000/samalba/hipache:latest +// +// Ex: localhost.localdomain:5000/samalba/hipache:latest func ParseImageTag(repos string) (string, string) { n := strings.LastIndex(repos, ":") if n < 0 { diff --git a/pkg/pipelines/delete_cluster.go b/pkg/pipelines/delete_cluster.go index 0d92a849..8459f09f 100644 --- a/pkg/pipelines/delete_cluster.go +++ b/pkg/pipelines/delete_cluster.go @@ -22,6 +22,7 @@ import ( "github.com/kubesphere/kubekey/pkg/bootstrap/precheck" "github.com/kubesphere/kubekey/pkg/certs" "github.com/kubesphere/kubekey/pkg/common" + "github.com/kubesphere/kubekey/pkg/container" "github.com/kubesphere/kubekey/pkg/core/module" "github.com/kubesphere/kubekey/pkg/core/pipeline" "github.com/kubesphere/kubekey/pkg/k3s" @@ -33,6 +34,7 @@ func NewDeleteClusterPipeline(runtime *common.KubeRuntime) error { &precheck.GreetingsModule{}, &confirm.DeleteClusterConfirmModule{}, &kubernetes.ResetClusterModule{}, + &container.UninstallContainerModule{Skip: !runtime.Arg.DeleteCRI}, &os.ClearOSEnvironmentModule{}, &certs.UninstallAutoRenewCertsModule{}, }