From ee4822e47660f40d7fdc4cd51dedfdc68c740043 Mon Sep 17 00:00:00 2001 From: Ron Lai Date: Tue, 19 Jul 2016 15:42:21 -0700 Subject: [PATCH] Moving image pulling errors under kubelet/images --- pkg/kubelet/container/sync_result.go | 15 ------------ pkg/kubelet/dockertools/docker.go | 3 ++- .../dockertools/docker_manager_test.go | 5 ++-- pkg/kubelet/dockertools/docker_test.go | 3 ++- pkg/kubelet/images/parallel_image_puller.go | 10 ++++---- pkg/kubelet/images/serialized_image_puller.go | 10 ++++---- pkg/kubelet/images/types.go | 23 ++++++++++++++++++- pkg/kubelet/kubelet.go | 5 ++-- test/e2e_node/runtime_conformance_test.go | 6 ++--- 9 files changed, 45 insertions(+), 35 deletions(-) diff --git a/pkg/kubelet/container/sync_result.go b/pkg/kubelet/container/sync_result.go index 67e786b03e9..5a976115585 100644 --- a/pkg/kubelet/container/sync_result.go +++ b/pkg/kubelet/container/sync_result.go @@ -29,24 +29,9 @@ import ( var ErrCrashLoopBackOff = errors.New("CrashLoopBackOff") var ( - // Container image pull failed, kubelet is backing off image pull - ErrImagePullBackOff = errors.New("ImagePullBackOff") - - // Unable to inspect image - ErrImageInspect = errors.New("ImageInspectError") - - // General image pull error - ErrImagePull = errors.New("ErrImagePull") - - // Required Image is absent on host and PullPolicy is NeverPullImage - ErrImageNeverPull = errors.New("ErrImageNeverPull") - // ErrContainerNotFound returned when a container in the given pod with the // given container name was not found, amongst those managed by the kubelet. ErrContainerNotFound = errors.New("no matching container") - - // Get http error when pulling image from registry - RegistryUnavailable = errors.New("RegistryUnavailable") ) var ( diff --git a/pkg/kubelet/dockertools/docker.go b/pkg/kubelet/dockertools/docker.go index 5dcfd8a55e3..4a3f162de4e 100644 --- a/pkg/kubelet/dockertools/docker.go +++ b/pkg/kubelet/dockertools/docker.go @@ -33,6 +33,7 @@ import ( "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/credentialprovider" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" + "k8s.io/kubernetes/pkg/kubelet/images" "k8s.io/kubernetes/pkg/kubelet/leaky" "k8s.io/kubernetes/pkg/types" utilerrors "k8s.io/kubernetes/pkg/util/errors" @@ -142,7 +143,7 @@ func filterHTTPError(err error, image string) error { jerr.Code == http.StatusServiceUnavailable || jerr.Code == http.StatusGatewayTimeout) { glog.V(2).Infof("Pulling image %q failed: %v", image, err) - return kubecontainer.RegistryUnavailable + return images.RegistryUnavailable } else { return err } diff --git a/pkg/kubelet/dockertools/docker_manager_test.go b/pkg/kubelet/dockertools/docker_manager_test.go index c9302d2b0a1..f30fc2effcf 100644 --- a/pkg/kubelet/dockertools/docker_manager_test.go +++ b/pkg/kubelet/dockertools/docker_manager_test.go @@ -44,6 +44,7 @@ import ( "k8s.io/kubernetes/pkg/client/record" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" containertest "k8s.io/kubernetes/pkg/kubelet/container/testing" + "k8s.io/kubernetes/pkg/kubelet/images" "k8s.io/kubernetes/pkg/kubelet/network" "k8s.io/kubernetes/pkg/kubelet/network/mock_network" nettest "k8s.io/kubernetes/pkg/kubelet/network/testing" @@ -1609,7 +1610,7 @@ func TestSyncPodWithPullPolicy(t *testing.T) { {kubecontainer.StartContainer, "bar2", nil, ""}, {kubecontainer.StartContainer, "bar3", nil, ""}, {kubecontainer.StartContainer, "bar4", nil, ""}, - {kubecontainer.StartContainer, "bar5", kubecontainer.ErrImageNeverPull, + {kubecontainer.StartContainer, "bar5", images.ErrImageNeverPull, "Container image \"pull_never_image\" is not present with pull policy of Never"}, } @@ -1649,7 +1650,7 @@ func TestSyncPodWithFailure(t *testing.T) { api.Container{Name: "bar", Image: "realImage", ImagePullPolicy: api.PullAlways}, map[string]error{}, []error{fmt.Errorf("can't pull image")}, - []*kubecontainer.SyncResult{{kubecontainer.StartContainer, "bar", kubecontainer.ErrImagePull, "can't pull image"}}, + []*kubecontainer.SyncResult{{kubecontainer.StartContainer, "bar", images.ErrImagePull, "can't pull image"}}, }, "CreateContainerFailure": { api.Container{Name: "bar", Image: "alreadyPresent"}, diff --git a/pkg/kubelet/dockertools/docker_test.go b/pkg/kubelet/dockertools/docker_test.go index bb2ef8a790f..edf2ae69e58 100644 --- a/pkg/kubelet/dockertools/docker_test.go +++ b/pkg/kubelet/dockertools/docker_test.go @@ -36,6 +36,7 @@ import ( "k8s.io/kubernetes/pkg/credentialprovider" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" containertest "k8s.io/kubernetes/pkg/kubelet/container/testing" + "k8s.io/kubernetes/pkg/kubelet/images" "k8s.io/kubernetes/pkg/kubelet/network" nettest "k8s.io/kubernetes/pkg/kubelet/network/testing" "k8s.io/kubernetes/pkg/types" @@ -226,7 +227,7 @@ func TestPullWithJSONError(t *testing.T) { "Bad gateway": { "ubuntu", &jsonmessage.JSONError{Code: 502, Message: "\n\n \n \n \n

Oops, there was an error!

\n

We have been contacted of this error, feel free to check out status.docker.com\n to see if there is a bigger issue.

\n\n \n"}, - kubecontainer.RegistryUnavailable.Error(), + images.RegistryUnavailable.Error(), }, } for i, test := range tests { diff --git a/pkg/kubelet/images/parallel_image_puller.go b/pkg/kubelet/images/parallel_image_puller.go index 6e494de3416..09fd47a04f8 100644 --- a/pkg/kubelet/images/parallel_image_puller.go +++ b/pkg/kubelet/images/parallel_image_puller.go @@ -86,7 +86,7 @@ func (puller *parallelImagePuller) pullImage(pod *api.Pod, container *api.Contai if err != nil { msg := fmt.Sprintf("Failed to inspect image %q: %v", container.Image, err) puller.logIt(ref, api.EventTypeWarning, events.FailedToInspectImage, logPrefix, msg, glog.Warning) - return kubecontainer.ErrImageInspect, msg + return ErrImageInspect, msg } if !shouldPullImage(container, present) { @@ -97,7 +97,7 @@ func (puller *parallelImagePuller) pullImage(pod *api.Pod, container *api.Contai } else { msg := fmt.Sprintf("Container image %q is not present with pull policy of Never", container.Image) puller.logIt(ref, api.EventTypeWarning, events.ErrImageNeverPullPolicy, logPrefix, msg, glog.Warning) - return kubecontainer.ErrImageNeverPull, msg + return ErrImageNeverPull, msg } } @@ -105,17 +105,17 @@ func (puller *parallelImagePuller) pullImage(pod *api.Pod, container *api.Contai if puller.backOff.IsInBackOffSinceUpdate(backOffKey, puller.backOff.Clock.Now()) { msg := fmt.Sprintf("Back-off pulling image %q", container.Image) puller.logIt(ref, api.EventTypeNormal, events.BackOffPullImage, logPrefix, msg, glog.Info) - return kubecontainer.ErrImagePullBackOff, msg + return ErrImagePullBackOff, msg } puller.logIt(ref, api.EventTypeNormal, events.PullingImage, logPrefix, fmt.Sprintf("pulling image %q", container.Image), glog.Info) if err := puller.runtime.PullImage(spec, pullSecrets); err != nil { puller.logIt(ref, api.EventTypeWarning, events.FailedToPullImage, logPrefix, fmt.Sprintf("Failed to pull image %q: %v", container.Image, err), glog.Warning) puller.backOff.Next(backOffKey, puller.backOff.Clock.Now()) - if err == kubecontainer.RegistryUnavailable { + if err == RegistryUnavailable { msg := fmt.Sprintf("image pull failed for %s because the registry is unavailable.", container.Image) return err, msg } else { - return kubecontainer.ErrImagePull, err.Error() + return ErrImagePull, err.Error() } } puller.logIt(ref, api.EventTypeNormal, events.PulledImage, logPrefix, fmt.Sprintf("Successfully pulled image %q", container.Image), glog.Info) diff --git a/pkg/kubelet/images/serialized_image_puller.go b/pkg/kubelet/images/serialized_image_puller.go index f90d0d290d3..b08c43fefb5 100644 --- a/pkg/kubelet/images/serialized_image_puller.go +++ b/pkg/kubelet/images/serialized_image_puller.go @@ -88,7 +88,7 @@ func (puller *serializedImagePuller) pullImage(pod *api.Pod, container *api.Cont if err != nil { msg := fmt.Sprintf("Failed to inspect image %q: %v", container.Image, err) puller.logIt(ref, api.EventTypeWarning, events.FailedToInspectImage, logPrefix, msg, glog.Warning) - return kubecontainer.ErrImageInspect, msg + return ErrImageInspect, msg } if !shouldPullImage(container, present) { @@ -99,7 +99,7 @@ func (puller *serializedImagePuller) pullImage(pod *api.Pod, container *api.Cont } else { msg := fmt.Sprintf("Container image %q is not present with pull policy of Never", container.Image) puller.logIt(ref, api.EventTypeWarning, events.ErrImageNeverPullPolicy, logPrefix, msg, glog.Warning) - return kubecontainer.ErrImageNeverPull, msg + return ErrImageNeverPull, msg } } @@ -107,7 +107,7 @@ func (puller *serializedImagePuller) pullImage(pod *api.Pod, container *api.Cont if puller.backOff.IsInBackOffSinceUpdate(backOffKey, puller.backOff.Clock.Now()) { msg := fmt.Sprintf("Back-off pulling image %q", container.Image) puller.logIt(ref, api.EventTypeNormal, events.BackOffPullImage, logPrefix, msg, glog.Info) - return kubecontainer.ErrImagePullBackOff, msg + return ErrImagePullBackOff, msg } // enqueue image pull request and wait for response. @@ -123,11 +123,11 @@ func (puller *serializedImagePuller) pullImage(pod *api.Pod, container *api.Cont if err = <-returnChan; err != nil { puller.logIt(ref, api.EventTypeWarning, events.FailedToPullImage, logPrefix, fmt.Sprintf("Failed to pull image %q: %v", container.Image, err), glog.Warning) puller.backOff.Next(backOffKey, puller.backOff.Clock.Now()) - if err == kubecontainer.RegistryUnavailable { + if err == RegistryUnavailable { msg := fmt.Sprintf("image pull failed for %s because the registry is unavailable.", container.Image) return err, msg } else { - return kubecontainer.ErrImagePull, err.Error() + return ErrImagePull, err.Error() } } puller.logIt(ref, api.EventTypeNormal, events.PulledImage, logPrefix, fmt.Sprintf("Successfully pulled image %q", container.Image), glog.Info) diff --git a/pkg/kubelet/images/types.go b/pkg/kubelet/images/types.go index bc2334f42c2..4c79110fb65 100644 --- a/pkg/kubelet/images/types.go +++ b/pkg/kubelet/images/types.go @@ -16,7 +16,28 @@ limitations under the License. package images -import "k8s.io/kubernetes/pkg/api" +import ( + "errors" + + "k8s.io/kubernetes/pkg/api" +) + +var ( + // Container image pull failed, kubelet is backing off image pull + ErrImagePullBackOff = errors.New("ImagePullBackOff") + + // Unable to inspect image + ErrImageInspect = errors.New("ImageInspectError") + + // General image pull error + ErrImagePull = errors.New("ErrImagePull") + + // Required Image is absent on host and PullPolicy is NeverPullImage + ErrImageNeverPull = errors.New("ErrImageNeverPull") + + // Get http error when pulling image from registry + RegistryUnavailable = errors.New("RegistryUnavailable") +) // ImageManager provides an interface to manage the lifecycle of images. // Implementations of this interface are expected to deal with pulling (downloading), diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index f6cf6134fef..63e6749a30a 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -57,6 +57,7 @@ import ( "k8s.io/kubernetes/pkg/kubelet/envvars" "k8s.io/kubernetes/pkg/kubelet/events" "k8s.io/kubernetes/pkg/kubelet/eviction" + "k8s.io/kubernetes/pkg/kubelet/images" "k8s.io/kubernetes/pkg/kubelet/lifecycle" "k8s.io/kubernetes/pkg/kubelet/metrics" "k8s.io/kubernetes/pkg/kubelet/network" @@ -2586,9 +2587,9 @@ func (kl *Kubelet) validateContainerLogStatus(podName string, podStatus *api.Pod case waiting != nil: // output some info for the most common pending failures switch reason := waiting.Reason; reason { - case kubecontainer.ErrImagePull.Error(): + case images.ErrImagePull.Error(): return kubecontainer.ContainerID{}, fmt.Errorf("container %q in pod %q is waiting to start: image can't be pulled", containerName, podName) - case kubecontainer.ErrImagePullBackOff.Error(): + case images.ErrImagePullBackOff.Error(): return kubecontainer.ContainerID{}, fmt.Errorf("container %q in pod %q is waiting to start: trying and failing to pull image", containerName, podName) default: return kubecontainer.ContainerID{}, fmt.Errorf("container %q in pod %q is waiting to start: %v", containerName, podName, reason) diff --git a/test/e2e_node/runtime_conformance_test.go b/test/e2e_node/runtime_conformance_test.go index 26f33a39628..f04575b7a56 100644 --- a/test/e2e_node/runtime_conformance_test.go +++ b/test/e2e_node/runtime_conformance_test.go @@ -22,7 +22,7 @@ import ( "time" "k8s.io/kubernetes/pkg/api" - kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" + "k8s.io/kubernetes/pkg/kubelet/images" "k8s.io/kubernetes/pkg/util" "k8s.io/kubernetes/test/e2e/framework" @@ -272,8 +272,8 @@ while true; do sleep 1; done } if testCase.waiting && status.State.Waiting != nil { reason := status.State.Waiting.Reason - return reason == kubecontainer.ErrImagePull.Error() || - reason == kubecontainer.ErrImagePullBackOff.Error(), nil + return reason == images.ErrImagePull.Error() || + reason == images.ErrImagePullBackOff.Error(), nil } return false, nil