mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-07-19 18:02:01 +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 {
|
type ImagePullCheck struct {
|
||||||
runtime utilruntime.ContainerRuntime
|
runtime utilruntime.ContainerRuntime
|
||||||
imageList []string
|
imageList []string
|
||||||
|
sandboxImage string
|
||||||
imagePullPolicy v1.PullPolicy
|
imagePullPolicy v1.PullPolicy
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -826,6 +827,15 @@ func (ipc ImagePullCheck) Check() (warnings, errorList []error) {
|
|||||||
policy := ipc.imagePullPolicy
|
policy := ipc.imagePullPolicy
|
||||||
klog.V(1).Infof("using image pull policy: %s", policy)
|
klog.V(1).Infof("using image pull policy: %s", policy)
|
||||||
for _, image := range ipc.imageList {
|
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 {
|
switch policy {
|
||||||
case v1.PullNever:
|
case v1.PullNever:
|
||||||
klog.V(1).Infof("skipping pull of image: %s", image)
|
klog.V(1).Infof("skipping pull of image: %s", image)
|
||||||
@ -1036,7 +1046,12 @@ func RunPullImagesCheck(execer utilsexec.Interface, cfg *kubeadmapi.InitConfigur
|
|||||||
}
|
}
|
||||||
|
|
||||||
checks := []Checker{
|
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)
|
return RunChecks(checks, os.Stderr, ignorePreflightErrors)
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@ type ContainerRuntime interface {
|
|||||||
RemoveContainers(containers []string) error
|
RemoveContainers(containers []string) error
|
||||||
PullImage(image string) error
|
PullImage(image string) error
|
||||||
ImageExists(image string) (bool, error)
|
ImageExists(image string) (bool, error)
|
||||||
|
SandboxImage() (string, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CRIRuntime is a struct that interfaces with the CRI
|
// 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) {
|
func DetectCRISocket() (string, error) {
|
||||||
return detectCRISocketImpl(isExistingSocket, defaultKnownCRISockets)
|
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) {
|
func TestRemoveContainers(t *testing.T) {
|
||||||
fakeOK := func() ([]byte, []byte, error) { return nil, nil, nil }
|
fakeOK := func() ([]byte, []byte, error) { return nil, nil, nil }
|
||||||
fakeErr := func() ([]byte, []byte, error) { return []byte("error"), nil, &fakeexec.FakeExitError{Status: 1} }
|
fakeErr := func() ([]byte, []byte, error) { return []byte("error"), nil, &fakeexec.FakeExitError{Status: 1} }
|
||||||
|
Loading…
Reference in New Issue
Block a user