From 25f2c6f330b5b74531702155b447890850cde76d Mon Sep 17 00:00:00 2001 From: Yu-Ju Hong Date: Thu, 21 Jan 2016 11:55:37 -0800 Subject: [PATCH] Improve mirror pod creation/deletion - Ignore the "not found" error on deletion. - Recognize the "already exists" error on creation and check if the existing pod meets requirement. If so, don't report an error. - Immediately create a mirror pod after a successful deletion, if needed. --- pkg/kubelet/kubelet.go | 10 ++++------ pkg/kubelet/kubelet_test.go | 4 ++-- pkg/kubelet/pod/mirror_client.go | 15 +++++++++++---- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/pkg/kubelet/kubelet.go b/pkg/kubelet/kubelet.go index c02a4345941..de50ee14cbb 100644 --- a/pkg/kubelet/kubelet.go +++ b/pkg/kubelet/kubelet.go @@ -1618,24 +1618,22 @@ func (kl *Kubelet) syncPod(pod *api.Pod, mirrorPod *api.Pod, runningPod kubecont // Create Mirror Pod for Static Pod if it doesn't already exist if kubepod.IsStaticPod(pod) { podFullName := kubecontainer.GetPodFullName(pod) + deleted := false if mirrorPod != nil && !kl.podManager.IsMirrorPodOf(mirrorPod, pod) { // The mirror pod is semantically different from the static pod. Remove // it. The mirror pod will get recreated later. glog.Errorf("Deleting mirror pod %q because it is outdated", format.Pod(mirrorPod)) if err := kl.podManager.DeleteMirrorPod(podFullName); err != nil { glog.Errorf("Failed deleting mirror pod %q: %v", format.Pod(mirrorPod), err) + } else { + deleted = true } } - if mirrorPod == nil { + if mirrorPod == nil || deleted { glog.V(3).Infof("Creating a mirror pod for static pod %q", format.Pod(pod)) if err := kl.podManager.CreateMirrorPod(pod); err != nil { glog.Errorf("Failed creating a mirror pod for %q: %v", format.Pod(pod), err) } - - _, ok := kl.podManager.GetMirrorPodByPod(pod) - if !ok { - glog.Errorf("Mirror pod not available") - } } } diff --git a/pkg/kubelet/kubelet_test.go b/pkg/kubelet/kubelet_test.go index 0831c6de6fb..2a043eaca5d 100644 --- a/pkg/kubelet/kubelet_test.go +++ b/pkg/kubelet/kubelet_test.go @@ -3399,8 +3399,8 @@ func TestDeleteOutdatedMirrorPod(t *testing.T) { } name := kubecontainer.GetPodFullName(pod) creates, deletes := manager.GetCounts(name) - if creates != 0 || deletes != 1 { - t.Errorf("expected 0 creation and 1 deletion of %q, got %d, %d", name, creates, deletes) + if creates != 1 || deletes != 1 { + t.Errorf("expected 1 creation and 1 deletion of %q, got %d, %d", name, creates, deletes) } } diff --git a/pkg/kubelet/pod/mirror_client.go b/pkg/kubelet/pod/mirror_client.go index bb215c86b5f..3eeee0794f1 100644 --- a/pkg/kubelet/pod/mirror_client.go +++ b/pkg/kubelet/pod/mirror_client.go @@ -19,6 +19,7 @@ package pod import ( "github.com/golang/glog" "k8s.io/kubernetes/pkg/api" + "k8s.io/kubernetes/pkg/api/errors" client "k8s.io/kubernetes/pkg/client/unversioned" kubecontainer "k8s.io/kubernetes/pkg/kubelet/container" kubetypes "k8s.io/kubernetes/pkg/kubelet/types" @@ -52,9 +53,15 @@ func (mc *basicMirrorClient) CreateMirrorPod(pod *api.Pod) error { for k, v := range pod.Annotations { copyPod.Annotations[k] = v } - copyPod.Annotations[kubetypes.ConfigMirrorAnnotationKey] = getPodHash(pod) - - _, err := mc.apiserverClient.Pods(copyPod.Namespace).Create(©Pod) + hash := getPodHash(pod) + copyPod.Annotations[kubetypes.ConfigMirrorAnnotationKey] = hash + apiPod, err := mc.apiserverClient.Pods(copyPod.Namespace).Create(©Pod) + if err != nil && errors.IsAlreadyExists(err) { + // Check if the existing pod is the same as the pod we want to create. + if h, ok := apiPod.Annotations[kubetypes.ConfigMirrorAnnotationKey]; ok && h == hash { + return nil + } + } return err } @@ -69,7 +76,7 @@ func (mc *basicMirrorClient) DeleteMirrorPod(podFullName string) error { return err } glog.V(4).Infof("Deleting a mirror pod %q", podFullName) - if err := mc.apiserverClient.Pods(namespace).Delete(name, api.NewDeleteOptions(0)); err != nil { + if err := mc.apiserverClient.Pods(namespace).Delete(name, api.NewDeleteOptions(0)); err != nil && !errors.IsNotFound(err) { glog.Errorf("Failed deleting a mirror pod %q: %v", podFullName, err) } return nil