Skip to content

Commit 9125473

Browse files
authored
Merge pull request kubernetes#124445 from chengjoey/e2e/kubelet-restart
add e2e test for restart kubelet
2 parents f0f7ff9 + 40dd01f commit 9125473

File tree

1 file changed

+76
-0
lines changed

1 file changed

+76
-0
lines changed

test/e2e_node/restart_test.go

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -474,6 +474,82 @@ var _ = SIGDescribe("Restart", framework.WithSerial(), framework.WithSlow(), fra
474474
return checkMirrorPodDisappear(ctx, f.ClientSet, pod.Name, pod.Namespace)
475475
}, f.Timeouts.PodDelete, f.Timeouts.Poll).Should(gomega.BeNil())
476476
})
477+
// Regression test for an extended scenario for https://issues.k8s.io/123980
478+
ginkgo.It("should evict running pods that do not meet the affinity after the kubelet restart", func(ctx context.Context) {
479+
nodeLabelKey := string(uuid.NewUUID())
480+
nodeLabelValueRequired := string(uuid.NewUUID())
481+
podName := "affinity-pod" + string(uuid.NewUUID())
482+
nodeName := getNodeName(ctx, f)
483+
484+
ginkgo.By(fmt.Sprintf("Adding node label for node (%s) to satisify pod (%s/%s) affinity", nodeName, f.Namespace.Name, podName))
485+
e2enode.AddOrUpdateLabelOnNode(f.ClientSet, nodeName, nodeLabelKey, nodeLabelValueRequired)
486+
ginkgo.DeferCleanup(func() { e2enode.RemoveLabelOffNode(f.ClientSet, nodeName, nodeLabelKey) })
487+
488+
pod := e2epod.MustMixinRestrictedPodSecurity(&v1.Pod{
489+
ObjectMeta: metav1.ObjectMeta{
490+
Name: podName,
491+
Namespace: f.Namespace.Name,
492+
},
493+
Spec: v1.PodSpec{
494+
Affinity: &v1.Affinity{
495+
NodeAffinity: &v1.NodeAffinity{
496+
RequiredDuringSchedulingIgnoredDuringExecution: &v1.NodeSelector{
497+
NodeSelectorTerms: []v1.NodeSelectorTerm{
498+
{
499+
MatchExpressions: []v1.NodeSelectorRequirement{
500+
{
501+
Key: nodeLabelKey,
502+
Operator: v1.NodeSelectorOpIn,
503+
Values: []string{nodeLabelValueRequired},
504+
},
505+
},
506+
},
507+
},
508+
},
509+
},
510+
},
511+
Containers: []v1.Container{
512+
{
513+
Name: podName,
514+
Image: imageutils.GetPauseImageName(),
515+
},
516+
},
517+
},
518+
})
519+
520+
// Create the pod bound to the node. It will start, but will be rejected after kubelet restart.
521+
ginkgo.By(fmt.Sprintf("Creating a pod (%s/%s)", f.Namespace.Name, podName))
522+
e2epod.NewPodClient(f).Create(ctx, pod)
523+
524+
ginkgo.By(fmt.Sprintf("Waiting for the pod (%s/%s) to be running", f.Namespace.Name, pod.Name))
525+
err := e2epod.WaitForPodNameRunningInNamespace(ctx, f.ClientSet, pod.Name, f.Namespace.Name)
526+
framework.ExpectNoError(err, "Failed to await for the pod to be running: (%v/%v)", f.Namespace.Name, pod.Name)
527+
528+
// Remove node label
529+
e2enode.RemoveLabelOffNode(f.ClientSet, nodeName, nodeLabelKey)
530+
531+
ginkgo.By("Restart the kubelet")
532+
restartKubelet(true)
533+
gomega.Eventually(ctx, func() bool {
534+
return kubeletHealthCheck(kubeletHealthCheckURL)
535+
}, recoverTimeout, f.Timeouts.Poll).
536+
Should(gomega.BeTrueBecause("kubelet should be healthy after restart"))
537+
538+
// Pod should be terminated, maybe not immediately, should allow a few seconds for the kubelet to kill the pod
539+
// after kubelet restart, pod admission denied, kubelet will reject the pod and kill container.
540+
gomega.Eventually(ctx, func() bool {
541+
pod, err = e2epod.NewPodClient(f).Get(ctx, podName, metav1.GetOptions{})
542+
framework.ExpectNoError(err)
543+
// pod is in a final state, the following are the behaviors of pods after kubelet restarted:
544+
// 1. kubelet `canAdmitPod` reject pod by reason Pod admission denied by nodeAffinity
545+
// 2. kubelet stop/kill container
546+
// the final state of the pod is related to the kill container.
547+
// if an error occurs in the preStop of the container or the exitCode is not 0,
548+
// the phase is PodFailed. if the exitCode of the StopContainer is 0, the phase is PodSucceeded.
549+
// in this case, stop and kill container is successful(exitCode 0), the pod phase should be PodSucceeded.
550+
return pod.Status.Phase == v1.PodSucceeded
551+
}, recoverTimeout, f.Timeouts.Poll).Should(gomega.BeTrueBecause("Pod %s not terminated: %s", pod.Name, pod.Status.Phase))
552+
})
477553
})
478554

479555
})

0 commit comments

Comments
 (0)