mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-19 09:52:49 +00:00
Merge pull request #115610 from SataQiu/detect-sandbox-20230208
kubeadm: show a warning message when detecting that the sandbox image of the container runtime is inconsistent with that used by kubeadm
This commit is contained in:
commit
f545ff3ba8
@ -813,6 +813,7 @@ func getEtcdVersionResponse(client *http.Client, url string, target interface{})
|
||||
type ImagePullCheck struct {
|
||||
runtime utilruntime.ContainerRuntime
|
||||
imageList []string
|
||||
sandboxImage string
|
||||
imagePullPolicy v1.PullPolicy
|
||||
}
|
||||
|
||||
@ -826,6 +827,15 @@ func (ipc ImagePullCheck) Check() (warnings, errorList []error) {
|
||||
policy := ipc.imagePullPolicy
|
||||
klog.V(1).Infof("using image pull policy: %s", policy)
|
||||
for _, image := range ipc.imageList {
|
||||
if image == ipc.sandboxImage {
|
||||
criSandboxImage, err := ipc.runtime.SandboxImage()
|
||||
if err != nil {
|
||||
klog.V(4).Infof("failed to detect the sandbox image for local container runtime, %v", err)
|
||||
} else if criSandboxImage != ipc.sandboxImage {
|
||||
klog.Warningf("detected that the sandbox image %q of the container runtime is inconsistent with that used by kubeadm. It is recommended that using %q as the CRI sandbox image.",
|
||||
criSandboxImage, ipc.sandboxImage)
|
||||
}
|
||||
}
|
||||
switch policy {
|
||||
case v1.PullNever:
|
||||
klog.V(1).Infof("skipping pull of image: %s", image)
|
||||
@ -1036,7 +1046,12 @@ func RunPullImagesCheck(execer utilsexec.Interface, cfg *kubeadmapi.InitConfigur
|
||||
}
|
||||
|
||||
checks := []Checker{
|
||||
ImagePullCheck{runtime: containerRuntime, imageList: images.GetControlPlaneImages(&cfg.ClusterConfiguration), imagePullPolicy: cfg.NodeRegistration.ImagePullPolicy},
|
||||
ImagePullCheck{
|
||||
runtime: containerRuntime,
|
||||
imageList: images.GetControlPlaneImages(&cfg.ClusterConfiguration),
|
||||
sandboxImage: images.GetPauseImage(&cfg.ClusterConfiguration),
|
||||
imagePullPolicy: cfg.NodeRegistration.ImagePullPolicy,
|
||||
},
|
||||
}
|
||||
return RunChecks(checks, os.Stderr, ignorePreflightErrors)
|
||||
}
|
||||
|
@ -44,6 +44,7 @@ type ContainerRuntime interface {
|
||||
RemoveContainers(containers []string) error
|
||||
PullImage(image string) error
|
||||
ImageExists(image string) (bool, error)
|
||||
SandboxImage() (string, error)
|
||||
}
|
||||
|
||||
// CRIRuntime is a struct that interfaces with the CRI
|
||||
@ -173,3 +174,19 @@ func detectCRISocketImpl(isSocket func(string) bool, knownCRISockets []string) (
|
||||
func DetectCRISocket() (string, error) {
|
||||
return detectCRISocketImpl(isExistingSocket, defaultKnownCRISockets)
|
||||
}
|
||||
|
||||
// SandboxImage returns the sandbox image used by the container runtime
|
||||
func (runtime *CRIRuntime) SandboxImage() (string, error) {
|
||||
args := []string{"-D=false", "info", "-o", "go-template", "--template", "{{.config.sandboxImage}}"}
|
||||
out, err := runtime.crictl(args...).CombinedOutput()
|
||||
if err != nil {
|
||||
return "", errors.Wrapf(err, "output: %s, error", string(out))
|
||||
}
|
||||
|
||||
sandboxImage := strings.TrimSpace(string(out))
|
||||
if len(sandboxImage) > 0 {
|
||||
return sandboxImage, nil
|
||||
}
|
||||
|
||||
return "", errors.Errorf("the detected sandbox image is empty")
|
||||
}
|
||||
|
@ -161,6 +161,56 @@ func TestListKubeContainers(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSandboxImage(t *testing.T) {
|
||||
fcmd := fakeexec.FakeCmd{
|
||||
CombinedOutputScript: []fakeexec.FakeAction{
|
||||
func() ([]byte, []byte, error) { return []byte("registry.k8s.io/pause:3.9"), nil, nil },
|
||||
func() ([]byte, []byte, error) { return []byte("registry.k8s.io/pause:3.9\n"), nil, nil },
|
||||
func() ([]byte, []byte, error) { return nil, nil, nil },
|
||||
func() ([]byte, []byte, error) { return nil, nil, &fakeexec.FakeExitError{Status: 1} },
|
||||
},
|
||||
}
|
||||
|
||||
execer := &fakeexec.FakeExec{
|
||||
CommandScript: genFakeActions(&fcmd, len(fcmd.CombinedOutputScript)),
|
||||
LookPathFunc: func(cmd string) (string, error) { return "/usr/bin/crictl", nil },
|
||||
}
|
||||
|
||||
cases := []struct {
|
||||
name string
|
||||
expected string
|
||||
isError bool
|
||||
}{
|
||||
{"valid: read sandbox image normally", "registry.k8s.io/pause:3.9", false},
|
||||
{"valid: read sandbox image with leading/trailing white spaces", "registry.k8s.io/pause:3.9", false},
|
||||
{"invalid: read empty sandbox image", "", true},
|
||||
{"invalid: failed to read sandbox image", "", true},
|
||||
}
|
||||
|
||||
for _, tc := range cases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
runtime, err := NewContainerRuntime(execer, "unix:///some/socket.sock")
|
||||
if err != nil {
|
||||
t.Fatalf("unexpected NewContainerRuntime error: %v", err)
|
||||
}
|
||||
|
||||
sandboxImage, err := runtime.SandboxImage()
|
||||
if tc.isError {
|
||||
if err == nil {
|
||||
t.Errorf("unexpected SandboxImage success")
|
||||
}
|
||||
return
|
||||
} else if err != nil {
|
||||
t.Errorf("unexpected SandboxImage error: %v", err)
|
||||
}
|
||||
|
||||
if sandboxImage != tc.expected {
|
||||
t.Errorf("expected sandbox image %v, but got %v", tc.expected, sandboxImage)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoveContainers(t *testing.T) {
|
||||
fakeOK := func() ([]byte, []byte, error) { return nil, nil, nil }
|
||||
fakeErr := func() ([]byte, []byte, error) { return []byte("error"), nil, &fakeexec.FakeExitError{Status: 1} }
|
||||
|
Loading…
Reference in New Issue
Block a user