Skip to content

Commit 1ce30fc

Browse files
Merge pull request #593 from harche/bug_1885717
Bug 1885717: UPSTREAM: 98742: Sync completed pods until their containers have been terminated
2 parents 6f8878d + 10d0d06 commit 1ce30fc

File tree

2 files changed

+130
-2
lines changed

2 files changed

+130
-2
lines changed

pkg/kubelet/kubelet.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2018,8 +2018,9 @@ func (kl *Kubelet) dispatchWork(pod *v1.Pod, syncType kubetypes.SyncPodType, mir
20182018
}
20192019

20202020
// optimization: avoid invoking the pod worker if no further changes are possible to the pod definition
2021-
if podWorkerTerminal {
2022-
klog.V(4).Infof("Pod %q has completed, ignoring remaining sync work: %s", format.Pod(pod), syncType)
2021+
// (i.e. the pod has completed and its containers have been terminated)
2022+
if podWorkerTerminal && containersTerminal {
2023+
klog.V(4).InfoS("Pod has completed and its containers have been terminated, ignoring remaining sync work", "pod", klog.KObj(pod), "syncType", syncType)
20232024
return
20242025
}
20252026

pkg/kubelet/kubelet_test.go

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,133 @@ func TestSyncPodsDeletesWhenSourcesAreReadyPerQOS(t *testing.T) {
470470
assert.True(t, destroyCount >= 1, "Expect 1 or more destroys")
471471
}
472472

473+
func TestDispatchWorkOfCompletedPod(t *testing.T) {
474+
testKubelet := newTestKubelet(t, false /* controllerAttachDetachEnabled */)
475+
defer testKubelet.Cleanup()
476+
kubelet := testKubelet.kubelet
477+
kubelet.podWorkers = &fakePodWorkers{
478+
syncPodFn: func(options syncPodOptions) error {
479+
return fmt.Errorf("should ignore completed pod %q", options.pod.Name)
480+
},
481+
cache: kubelet.podCache,
482+
t: t,
483+
}
484+
now := metav1.NewTime(time.Now())
485+
pods := []*v1.Pod{
486+
{
487+
ObjectMeta: metav1.ObjectMeta{
488+
UID: "1",
489+
Name: "completed-pod1",
490+
Namespace: "ns",
491+
Annotations: make(map[string]string),
492+
},
493+
Status: v1.PodStatus{
494+
Phase: v1.PodFailed,
495+
ContainerStatuses: []v1.ContainerStatus{
496+
{
497+
State: v1.ContainerState{
498+
Terminated: &v1.ContainerStateTerminated{},
499+
},
500+
},
501+
},
502+
},
503+
},
504+
{
505+
ObjectMeta: metav1.ObjectMeta{
506+
UID: "2",
507+
Name: "completed-pod2",
508+
Namespace: "ns",
509+
Annotations: make(map[string]string),
510+
},
511+
Status: v1.PodStatus{
512+
Phase: v1.PodSucceeded,
513+
ContainerStatuses: []v1.ContainerStatus{
514+
{
515+
State: v1.ContainerState{
516+
Terminated: &v1.ContainerStateTerminated{},
517+
},
518+
},
519+
},
520+
},
521+
},
522+
{
523+
ObjectMeta: metav1.ObjectMeta{
524+
UID: "3",
525+
Name: "completed-pod3",
526+
Namespace: "ns",
527+
Annotations: make(map[string]string),
528+
DeletionTimestamp: &now,
529+
},
530+
Status: v1.PodStatus{
531+
ContainerStatuses: []v1.ContainerStatus{
532+
{
533+
State: v1.ContainerState{
534+
Terminated: &v1.ContainerStateTerminated{},
535+
},
536+
},
537+
},
538+
},
539+
},
540+
}
541+
for _, pod := range pods {
542+
kubelet.dispatchWork(pod, kubetypes.SyncPodSync, nil, time.Now())
543+
}
544+
}
545+
546+
func TestDispatchWorkOfActivePod(t *testing.T) {
547+
testKubelet := newTestKubelet(t, false /* controllerAttachDetachEnabled */)
548+
defer testKubelet.Cleanup()
549+
kubelet := testKubelet.kubelet
550+
var got bool
551+
kubelet.podWorkers = &fakePodWorkers{
552+
syncPodFn: func(options syncPodOptions) error {
553+
got = true
554+
return nil
555+
},
556+
cache: kubelet.podCache,
557+
t: t,
558+
}
559+
pods := []*v1.Pod{
560+
{
561+
ObjectMeta: metav1.ObjectMeta{
562+
UID: "1",
563+
Name: "active-pod1",
564+
Namespace: "ns",
565+
Annotations: make(map[string]string),
566+
},
567+
Status: v1.PodStatus{
568+
Phase: v1.PodRunning,
569+
},
570+
},
571+
{
572+
ObjectMeta: metav1.ObjectMeta{
573+
UID: "2",
574+
Name: "active-pod2",
575+
Namespace: "ns",
576+
Annotations: make(map[string]string),
577+
},
578+
Status: v1.PodStatus{
579+
Phase: v1.PodFailed,
580+
ContainerStatuses: []v1.ContainerStatus{
581+
{
582+
State: v1.ContainerState{
583+
Running: &v1.ContainerStateRunning{},
584+
},
585+
},
586+
},
587+
},
588+
},
589+
}
590+
591+
for _, pod := range pods {
592+
kubelet.dispatchWork(pod, kubetypes.SyncPodSync, nil, time.Now())
593+
if !got {
594+
t.Errorf("Should not skip active pod %q", pod.Name)
595+
}
596+
got = false
597+
}
598+
}
599+
473600
func TestSyncPodsDeletesWhenSourcesAreReady(t *testing.T) {
474601
ready := false
475602

0 commit comments

Comments
 (0)