mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-29 06:27:05 +00:00
kubeadm: reset: use crictl to reset containers
Signed-off-by: Antonio Murdaca <runcom@redhat.com>
This commit is contained in:
parent
6d73f03d2b
commit
bb0cd2714b
@ -73,6 +73,7 @@ go_library(
|
|||||||
"//vendor/k8s.io/apiserver/pkg/util/flag:go_default_library",
|
"//vendor/k8s.io/apiserver/pkg/util/flag:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
|
||||||
"//vendor/k8s.io/client-go/util/cert:go_default_library",
|
"//vendor/k8s.io/client-go/util/cert:go_default_library",
|
||||||
|
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -87,6 +88,8 @@ go_test(
|
|||||||
deps = [
|
deps = [
|
||||||
"//cmd/kubeadm/app/constants:go_default_library",
|
"//cmd/kubeadm/app/constants:go_default_library",
|
||||||
"//cmd/kubeadm/app/preflight:go_default_library",
|
"//cmd/kubeadm/app/preflight:go_default_library",
|
||||||
|
"//vendor/k8s.io/utils/exec:go_default_library",
|
||||||
|
"//vendor/k8s.io/utils/exec/testing:go_default_library",
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -30,17 +30,23 @@ import (
|
|||||||
"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
|
"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
|
||||||
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
|
||||||
"k8s.io/kubernetes/pkg/util/initsystem"
|
"k8s.io/kubernetes/pkg/util/initsystem"
|
||||||
|
utilsexec "k8s.io/utils/exec"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
crictlParamsFormat = "%s -r %s sandboxes --quiet | xargs -r %s -r %s rms"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewCmdReset returns the "kubeadm reset" command
|
// NewCmdReset returns the "kubeadm reset" command
|
||||||
func NewCmdReset(out io.Writer) *cobra.Command {
|
func NewCmdReset(out io.Writer) *cobra.Command {
|
||||||
var skipPreFlight bool
|
var skipPreFlight bool
|
||||||
var certsDir string
|
var certsDir string
|
||||||
|
var criSocketPath string
|
||||||
cmd := &cobra.Command{
|
cmd := &cobra.Command{
|
||||||
Use: "reset",
|
Use: "reset",
|
||||||
Short: "Run this to revert any changes made to this host by 'kubeadm init' or 'kubeadm join'.",
|
Short: "Run this to revert any changes made to this host by 'kubeadm init' or 'kubeadm join'.",
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
r, err := NewReset(skipPreFlight, certsDir)
|
r, err := NewReset(skipPreFlight, certsDir, criSocketPath)
|
||||||
kubeadmutil.CheckErr(err)
|
kubeadmutil.CheckErr(err)
|
||||||
kubeadmutil.CheckErr(r.Run(out))
|
kubeadmutil.CheckErr(r.Run(out))
|
||||||
},
|
},
|
||||||
@ -56,16 +62,22 @@ func NewCmdReset(out io.Writer) *cobra.Command {
|
|||||||
"The path to the directory where the certificates are stored. If specified, clean this directory.",
|
"The path to the directory where the certificates are stored. If specified, clean this directory.",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
cmd.PersistentFlags().StringVar(
|
||||||
|
&criSocketPath, "cri-socket", "/var/run/dockershim.sock",
|
||||||
|
"The path to the CRI socket to use with crictl when cleaning up containers.",
|
||||||
|
)
|
||||||
|
|
||||||
return cmd
|
return cmd
|
||||||
}
|
}
|
||||||
|
|
||||||
// Reset defines struct used for kubeadm reset command
|
// Reset defines struct used for kubeadm reset command
|
||||||
type Reset struct {
|
type Reset struct {
|
||||||
certsDir string
|
certsDir string
|
||||||
|
criSocketPath string
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewReset instantiate Reset struct
|
// NewReset instantiate Reset struct
|
||||||
func NewReset(skipPreFlight bool, certsDir string) (*Reset, error) {
|
func NewReset(skipPreFlight bool, certsDir, criSocketPath string) (*Reset, error) {
|
||||||
if !skipPreFlight {
|
if !skipPreFlight {
|
||||||
fmt.Println("[preflight] Running pre-flight checks.")
|
fmt.Println("[preflight] Running pre-flight checks.")
|
||||||
|
|
||||||
@ -78,6 +90,7 @@ func NewReset(skipPreFlight bool, certsDir string) (*Reset, error) {
|
|||||||
|
|
||||||
return &Reset{
|
return &Reset{
|
||||||
certsDir: certsDir,
|
certsDir: certsDir,
|
||||||
|
criSocketPath: criSocketPath,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,15 +118,11 @@ func (r *Reset) Run(out io.Writer) error {
|
|||||||
fmt.Printf("[reset] Failed to unmount mounted directories in /var/lib/kubelet: %s\n", string(umountOutputBytes))
|
fmt.Printf("[reset] Failed to unmount mounted directories in /var/lib/kubelet: %s\n", string(umountOutputBytes))
|
||||||
}
|
}
|
||||||
|
|
||||||
dockerCheck := preflight.ServiceCheck{Service: "docker", CheckIfActive: true}
|
|
||||||
if _, errors := dockerCheck.Check(); len(errors) == 0 {
|
|
||||||
fmt.Println("[reset] Removing kubernetes-managed containers.")
|
fmt.Println("[reset] Removing kubernetes-managed containers.")
|
||||||
if err := exec.Command("sh", "-c", "docker ps -a --filter name=k8s_ -q | xargs -r docker rm --force --volumes").Run(); err != nil {
|
dockerCheck := preflight.ServiceCheck{Service: "docker", CheckIfActive: true}
|
||||||
fmt.Println("[reset] Failed to stop the running containers.")
|
execer := utilsexec.New()
|
||||||
}
|
|
||||||
} else {
|
reset(execer, dockerCheck, r.criSocketPath)
|
||||||
fmt.Println("[reset] Docker doesn't seem to be running. Skipping the removal of running Kubernetes containers.")
|
|
||||||
}
|
|
||||||
|
|
||||||
dirsToClean := []string{"/var/lib/kubelet", "/etc/cni/net.d", "/var/lib/dockershim", "/var/run/kubernetes"}
|
dirsToClean := []string{"/var/lib/kubelet", "/etc/cni/net.d", "/var/lib/dockershim", "/var/run/kubernetes"}
|
||||||
|
|
||||||
@ -141,6 +150,39 @@ func (r *Reset) Run(out io.Writer) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func reset(execer utilsexec.Interface, dockerCheck preflight.Checker, criSocketPath string) {
|
||||||
|
crictlPath, err := execer.LookPath("crictl")
|
||||||
|
if err == nil {
|
||||||
|
resetWithCrictl(execer, dockerCheck, criSocketPath, crictlPath)
|
||||||
|
} else {
|
||||||
|
resetWithDocker(execer, dockerCheck)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resetWithDocker(execer utilsexec.Interface, dockerCheck preflight.Checker) {
|
||||||
|
if _, errors := dockerCheck.Check(); len(errors) == 0 {
|
||||||
|
if err := execer.Command("sh", "-c", "docker ps -a --filter name=k8s_ -q | xargs -r docker rm --force --volumes").Run(); err != nil {
|
||||||
|
fmt.Println("[reset] Failed to stop the running containers.")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Println("[reset] Docker doesn't seem to be running. Skipping the removal of running Kubernetes containers.")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func resetWithCrictl(execer utilsexec.Interface, dockerCheck preflight.Checker, criSocketPath, crictlPath string) {
|
||||||
|
if criSocketPath != "" {
|
||||||
|
fmt.Printf("[reset] Cleaning up running containers using crictl with socket %s\n", criSocketPath)
|
||||||
|
cmd := fmt.Sprintf(crictlParamsFormat, crictlPath, criSocketPath, crictlPath, criSocketPath)
|
||||||
|
if err := execer.Command("sh", "-c", cmd).Run(); err != nil {
|
||||||
|
fmt.Println("[reset] Failed to stop the running containers using crictl. Trying using docker instead.")
|
||||||
|
resetWithDocker(execer, dockerCheck)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Println("[reset] CRI socket path not provided for crictl. Trying docker instead.")
|
||||||
|
resetWithDocker(execer, dockerCheck)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// cleanDir removes everything in a directory, but not the directory itself
|
// cleanDir removes everything in a directory, but not the directory itself
|
||||||
func cleanDir(filePath string) error {
|
func cleanDir(filePath string) error {
|
||||||
// If the directory doesn't even exist there's nothing to do, and we do
|
// If the directory doesn't even exist there's nothing to do, and we do
|
||||||
|
@ -17,13 +17,17 @@ limitations under the License.
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
kubeadmconstants "k8s.io/kubernetes/cmd/kubeadm/app/constants"
|
||||||
"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
|
"k8s.io/kubernetes/cmd/kubeadm/app/preflight"
|
||||||
|
"k8s.io/utils/exec"
|
||||||
|
fakeexec "k8s.io/utils/exec/testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func assertExists(t *testing.T, path string) {
|
func assertExists(t *testing.T, path string) {
|
||||||
@ -181,3 +185,129 @@ func TestConfigDirCleaner(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type fakeDockerChecker struct {
|
||||||
|
warnings []error
|
||||||
|
errors []error
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *fakeDockerChecker) Check() (warnings, errors []error) {
|
||||||
|
return c.warnings, c.errors
|
||||||
|
}
|
||||||
|
|
||||||
|
func newFakeDockerChecker(warnings, errors []error) preflight.Checker {
|
||||||
|
return &fakeDockerChecker{warnings: warnings, errors: errors}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResetWithDocker(t *testing.T) {
|
||||||
|
fcmd := fakeexec.FakeCmd{
|
||||||
|
RunScript: []fakeexec.FakeRunAction{
|
||||||
|
func() ([]byte, []byte, error) { return nil, nil, nil },
|
||||||
|
func() ([]byte, []byte, error) { return nil, nil, errors.New("docker error") },
|
||||||
|
func() ([]byte, []byte, error) { return nil, nil, nil },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
fexec := fakeexec.FakeExec{
|
||||||
|
CommandScript: []fakeexec.FakeCommandAction{
|
||||||
|
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||||
|
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||||
|
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
resetWithDocker(&fexec, newFakeDockerChecker(nil, nil))
|
||||||
|
if fcmd.RunCalls != 1 {
|
||||||
|
t.Errorf("expected 1 call to Run, got %d", fcmd.RunCalls)
|
||||||
|
}
|
||||||
|
resetWithDocker(&fexec, newFakeDockerChecker(nil, nil))
|
||||||
|
if fcmd.RunCalls != 2 {
|
||||||
|
t.Errorf("expected 2 calls to Run, got %d", fcmd.RunCalls)
|
||||||
|
}
|
||||||
|
resetWithDocker(&fexec, newFakeDockerChecker(nil, []error{errors.New("test error")}))
|
||||||
|
if fcmd.RunCalls != 2 {
|
||||||
|
t.Errorf("expected 2 calls to Run, got %d", fcmd.RunCalls)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestResetWithCrictl(t *testing.T) {
|
||||||
|
fcmd := fakeexec.FakeCmd{
|
||||||
|
RunScript: []fakeexec.FakeRunAction{
|
||||||
|
func() ([]byte, []byte, error) { return nil, nil, nil },
|
||||||
|
func() ([]byte, []byte, error) { return nil, nil, nil },
|
||||||
|
func() ([]byte, []byte, error) { return nil, nil, errors.New("crictl error") },
|
||||||
|
func() ([]byte, []byte, error) { return nil, nil, nil },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
fexec := fakeexec.FakeExec{
|
||||||
|
CommandScript: []fakeexec.FakeCommandAction{
|
||||||
|
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||||
|
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||||
|
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||||
|
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
resetWithCrictl(&fexec, newFakeDockerChecker(nil, nil), "", "crictl")
|
||||||
|
if fcmd.RunCalls != 1 {
|
||||||
|
t.Errorf("expected 1 call to Run, got %d", fcmd.RunCalls)
|
||||||
|
}
|
||||||
|
if !strings.Contains(fcmd.RunLog[0][2], "docker") {
|
||||||
|
t.Errorf("expected a call to docker, got %v", fcmd.RunLog[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
resetWithCrictl(&fexec, newFakeDockerChecker(nil, nil), "/test.sock", "crictl")
|
||||||
|
if fcmd.RunCalls != 2 {
|
||||||
|
t.Errorf("expected 2 calls to Run, got %d", fcmd.RunCalls)
|
||||||
|
}
|
||||||
|
if !strings.Contains(fcmd.RunLog[1][2], "crictl") {
|
||||||
|
t.Errorf("expected a call to crictl, got %v", fcmd.RunLog[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
resetWithCrictl(&fexec, newFakeDockerChecker(nil, nil), "/test.sock", "crictl")
|
||||||
|
if fcmd.RunCalls != 4 {
|
||||||
|
t.Errorf("expected 4 calls to Run, got %d", fcmd.RunCalls)
|
||||||
|
}
|
||||||
|
if !strings.Contains(fcmd.RunLog[2][2], "crictl") {
|
||||||
|
t.Errorf("expected a call to crictl, got %v", fcmd.RunLog[0])
|
||||||
|
}
|
||||||
|
if !strings.Contains(fcmd.RunLog[3][2], "docker") {
|
||||||
|
t.Errorf("expected a call to docker, got %v", fcmd.RunLog[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
resetWithCrictl(&fexec, newFakeDockerChecker(nil, []error{errors.New("test error")}), "", "crictl")
|
||||||
|
if fcmd.RunCalls != 4 {
|
||||||
|
t.Errorf("expected 4 calls to Run, got %d", fcmd.RunCalls)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestReset(t *testing.T) {
|
||||||
|
fcmd := fakeexec.FakeCmd{
|
||||||
|
RunScript: []fakeexec.FakeRunAction{
|
||||||
|
func() ([]byte, []byte, error) { return nil, nil, nil },
|
||||||
|
func() ([]byte, []byte, error) { return nil, nil, nil },
|
||||||
|
},
|
||||||
|
}
|
||||||
|
fexec := fakeexec.FakeExec{
|
||||||
|
CommandScript: []fakeexec.FakeCommandAction{
|
||||||
|
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||||
|
func(cmd string, args ...string) exec.Cmd { return fakeexec.InitFakeCmd(&fcmd, cmd, args...) },
|
||||||
|
},
|
||||||
|
LookPathFunc: func(cmd string) (string, error) { return cmd, nil },
|
||||||
|
}
|
||||||
|
|
||||||
|
reset(&fexec, newFakeDockerChecker(nil, nil), "/test.sock")
|
||||||
|
if fcmd.RunCalls != 1 {
|
||||||
|
t.Errorf("expected 1 call to Run, got %d", fcmd.RunCalls)
|
||||||
|
}
|
||||||
|
if !strings.Contains(fcmd.RunLog[0][2], "crictl") {
|
||||||
|
t.Errorf("expected a call to crictl, got %v", fcmd.RunLog[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
fexec.LookPathFunc = func(cmd string) (string, error) { return "", errors.New("no crictl") }
|
||||||
|
reset(&fexec, newFakeDockerChecker(nil, nil), "/test.sock")
|
||||||
|
if fcmd.RunCalls != 2 {
|
||||||
|
t.Errorf("expected 2 calls to Run, got %d", fcmd.RunCalls)
|
||||||
|
}
|
||||||
|
if !strings.Contains(fcmd.RunLog[1][2], "docker") {
|
||||||
|
t.Errorf("expected a call to docker, got %v", fcmd.RunLog[0])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user