1
16
17 package e2enode
18
19 import (
20 "context"
21 "os"
22
23 "github.com/onsi/ginkgo/v2"
24 "github.com/onsi/gomega"
25 v1 "k8s.io/api/core/v1"
26 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
27 "k8s.io/apimachinery/pkg/util/uuid"
28 "k8s.io/kubernetes/test/e2e/framework"
29 e2epod "k8s.io/kubernetes/test/e2e/framework/pod"
30 imageutils "k8s.io/kubernetes/test/utils/image"
31 admissionapi "k8s.io/pod-security-admission/api"
32 )
33
34
47 var _ = SIGDescribe("Unknown Pods", framework.WithSerial(), framework.WithDisruptive(), func() {
48 f := framework.NewDefaultFramework("unknown-pods")
49 f.NamespacePodSecurityLevel = admissionapi.LevelBaseline
50
51 ginkgo.Context("when creating a mirror pod", func() {
52 var ns, podPath, staticPodName, mirrorPodName string
53 ginkgo.BeforeEach(func(ctx context.Context) {
54 ns = f.Namespace.Name
55 staticPodName = "unknown-test-pod-" + string(uuid.NewUUID())
56 mirrorPodName = staticPodName + "-" + framework.TestContext.NodeName
57
58 podPath = kubeletCfg.StaticPodPath
59
60 framework.Logf("create the static pod %v", staticPodName)
61 err := createStaticPodWithGracePeriod(podPath, staticPodName, ns)
62 framework.ExpectNoError(err)
63
64 framework.Logf("wait for the mirror pod %v to be running", mirrorPodName)
65 gomega.Eventually(ctx, func(ctx context.Context) error {
66 return checkMirrorPodRunning(ctx, f.ClientSet, mirrorPodName, ns)
67 }, f.Timeouts.PodStart, f.Timeouts.Poll).Should(gomega.BeNil())
68 })
69
70 ginkgo.It("the static pod should be terminated and cleaned up due to becoming a unknown pod due to being force deleted while kubelet is not running", func(ctx context.Context) {
71 framework.Logf("Stopping the kubelet")
72 startKubelet := stopKubelet()
73
74 pod, err := f.ClientSet.CoreV1().Pods(ns).Get(ctx, mirrorPodName, metav1.GetOptions{})
75 framework.ExpectNoError(err)
76
77
78 gomega.Eventually(ctx, func() bool {
79 return kubeletHealthCheck(kubeletHealthCheckURL)
80 }, f.Timeouts.PodStart, f.Timeouts.Poll).Should(gomega.BeFalse())
81
82 framework.Logf("Delete the static pod manifest while the kubelet is not running")
83 file := staticPodPath(podPath, staticPodName, ns)
84 framework.Logf("deleting static pod manifest %q", file)
85 err = os.Remove(file)
86 framework.ExpectNoError(err)
87
88 framework.Logf("Starting the kubelet")
89 startKubelet()
90
91
92 gomega.Eventually(ctx, func() bool {
93 return kubeletHealthCheck(kubeletHealthCheckURL)
94 }, f.Timeouts.PodStart, f.Timeouts.Poll).Should(gomega.BeTrue())
95
96 framework.Logf("wait for the mirror pod %v to disappear", mirrorPodName)
97 gomega.Eventually(ctx, func(ctx context.Context) error {
98 return checkMirrorPodDisappear(ctx, f.ClientSet, mirrorPodName, ns)
99 }, f.Timeouts.PodDelete, f.Timeouts.Poll).Should(gomega.BeNil())
100
101 waitForAllContainerRemoval(ctx, pod.Name, pod.Namespace)
102 })
103
104 ginkgo.AfterEach(func(ctx context.Context) {
105 framework.Logf("deleting the static pod %v", staticPodName)
106 err := deleteStaticPod(podPath, staticPodName, ns)
107 if !os.IsNotExist(err) {
108 framework.ExpectNoError(err)
109 }
110
111 framework.Logf("wait for the mirror pod to disappear")
112 gomega.Eventually(ctx, func(ctx context.Context) error {
113 return checkMirrorPodDisappear(ctx, f.ClientSet, mirrorPodName, ns)
114 }, f.Timeouts.PodDelete, f.Timeouts.Poll).Should(gomega.BeNil())
115 })
116 })
117
118 ginkgo.Context("when creating a API pod", func() {
119 var ns, podName string
120
121 ginkgo.BeforeEach(func(ctx context.Context) {
122 ns = f.Namespace.Name
123 podName = "unknown-test-pause-pod-" + string(uuid.NewUUID())
124 pod := &v1.Pod{
125 ObjectMeta: metav1.ObjectMeta{
126 Name: podName,
127 },
128 Spec: v1.PodSpec{
129 Containers: []v1.Container{
130 {
131 Name: "pause",
132 Image: imageutils.GetPauseImageName(),
133 },
134 },
135 },
136 }
137
138 e2epod.NewPodClient(f).CreateSync(ctx, pod)
139 })
140
141 ginkgo.It("the api pod should be terminated and cleaned up due to becoming a unknown pod due to being force deleted while kubelet is not running", func(ctx context.Context) {
142 framework.Logf("Stopping the kubelet")
143 startKubelet := stopKubelet()
144
145 pod, err := f.ClientSet.CoreV1().Pods(ns).Get(ctx, podName, metav1.GetOptions{})
146 framework.ExpectNoError(err)
147
148
149 gomega.Eventually(ctx, func() bool {
150 return kubeletHealthCheck(kubeletHealthCheckURL)
151 }, f.Timeouts.PodStart, f.Timeouts.Poll).Should(gomega.BeFalse())
152
153 framework.Logf("Delete the pod while the kubelet is not running")
154
155 deletePodSyncByName(ctx, f, podName)
156
157 framework.Logf("Starting the kubelet")
158 startKubelet()
159
160
161 gomega.Eventually(ctx, func() bool {
162 return kubeletHealthCheck(kubeletHealthCheckURL)
163 }, f.Timeouts.PodStart, f.Timeouts.Poll).Should(gomega.BeTrue())
164
165 framework.Logf("wait for the pod %v to disappear", podName)
166 gomega.Eventually(ctx, func(ctx context.Context) error {
167 return checkMirrorPodDisappear(ctx, f.ClientSet, podName, ns)
168 }, f.Timeouts.PodDelete, f.Timeouts.Poll).Should(gomega.BeNil())
169
170 waitForAllContainerRemoval(ctx, pod.Name, pod.Namespace)
171 })
172 })
173 })
174
View as plain text