Skip to content

Commit 0cbb4d0

Browse files
authored
Merge pull request #39809 from mimowo/update-docs-about-handling-deleted-pods
Update docs for KEP3329: "Retriable and non-retriable Pod failures for jobs
2 parents 4dfee46 + 801b556 commit 0cbb4d0

File tree

5 files changed

+149
-5
lines changed

5 files changed

+149
-5
lines changed

content/en/docs/concepts/workloads/controllers/job.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -807,6 +807,17 @@ These are some requirements and semantics of the API:
807807
- `Count`: use to indicate that the Pod should be handled in the default way.
808808
The counter towards the `.spec.backoffLimit` should be incremented.
809809

810+
{{< note >}}
811+
When you use a `podFailurePolicy`, the job controller only matches Pods in the
812+
`Failed` phase. Pods with a deletion timestamp that are not in a terminal phase
813+
(`Failed` or `Succeeded`) are considered still terminating. This implies that
814+
terminating pods retain a [tracking finalizer](#job-tracking-with-finalizers)
815+
until they reach a terminal phase.
816+
Since Kubernetes 1.27, Kubelet transitions deleted pods to a terminal phase
817+
(see: [Pod Phase](/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase)). This
818+
ensures that deleted pods have their finalizers removed by the Job controller.
819+
{{< /note >}}
820+
810821
### Job tracking with finalizers
811822

812823
{{< feature-state for_k8s_version="v1.26" state="stable" >}}

content/en/docs/concepts/workloads/pods/disruptions.md

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -231,11 +231,6 @@ can happen, according to:
231231

232232
{{< feature-state for_k8s_version="v1.26" state="beta" >}}
233233

234-
{{< note >}}
235-
If you are using an older version of Kubernetes than {{< skew currentVersion >}}
236-
please refer to the corresponding version of the documentation.
237-
{{< /note >}}
238-
239234
{{< note >}}
240235
In order to use this behavior, you must have the `PodDisruptionConditions`
241236
[feature gate](/docs/reference/command-line-tools-reference/feature-gates/)

content/en/docs/concepts/workloads/pods/pod-lifecycle.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,12 @@ A Pod is granted a term to terminate gracefully, which defaults to 30 seconds.
9191
You can use the flag `--force` to [terminate a Pod by force](/docs/concepts/workloads/pods/pod-lifecycle/#pod-termination-forced).
9292
{{< /note >}}
9393

94+
Since Kubernetes 1.27, the kubelet transitions deleted pods, except for
95+
[static pods](/docs/tasks/configure-pod-container/static-pod/) and
96+
[force-deleted pods](/docs/concepts/workloads/pods/pod-lifecycle/#pod-termination-forced)
97+
without a finalizer, to a terminal phase (`Failed` or `Succeeded` depending on
98+
the exit statuses of the pod containers) before their deletion from the API server.
99+
94100
If a node dies or is disconnected from the rest of the cluster, Kubernetes
95101
applies a policy for setting the `phase` of all Pods on the lost node to Failed.
96102

@@ -494,6 +500,8 @@ feature gate `EndpointSliceTerminatingCondition` is enabled.
494500
1. When the grace period expires, the kubelet triggers forcible shutdown. The container runtime sends
495501
`SIGKILL` to any processes still running in any container in the Pod.
496502
The kubelet also cleans up a hidden `pause` container if that container runtime uses one.
503+
1. The kubelet transitions the pod into a terminal phase (`Failed` or `Succeeded` depending on
504+
the end state of its containers). This step is guaranteed since version 1.27.
497505
1. The kubelet triggers forcible removal of Pod object from the API server, by setting grace period
498506
to 0 (immediate deletion).
499507
1. The API server deletes the Pod's API object, which is then no longer visible from any client.

content/en/docs/tasks/job/pod-failure-policy.md

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@ You should already be familiar with the basic use of [Job](/docs/concepts/worklo
2828

2929
{{< include "task-tutorial-prereqs.md" >}} {{< version-check >}}
3030

31+
Ensure that the [feature gates](/docs/reference/command-line-tools-reference/feature-gates/)
32+
`PodDisruptionConditions` and `JobPodFailurePolicy` are both enabled in your cluster.
33+
3134
## Using Pod failure policy to avoid unnecessary Pod retries
3235

3336
With the following example, you can learn how to use Pod failure policy to
@@ -129,6 +132,114 @@ kubectl delete jobs/job-pod-failure-policy-ignore
129132

130133
The cluster automatically cleans up the Pods.
131134

135+
## Using Pod failure policy to avoid unnecessary Pod retries based on custom Pod Conditions
136+
137+
With the following example, you can learn how to use Pod failure policy to
138+
avoid unnecessary Pod restarts based on custom Pod Conditions.
139+
140+
{{< note >}}
141+
The example below works since version 1.27 as it relies on transitioning of
142+
deleted pods, in the `Pending` phase, to a terminal phase
143+
(see: [Pod Phase](/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase)).
144+
{{< /note >}}
145+
146+
1. First, create a Job based on the config:
147+
148+
{{< codenew file="/controllers/job-pod-failure-policy-config-issue.yaml" >}}
149+
150+
by running:
151+
152+
```sh
153+
kubectl create -f job-pod-failure-policy-config-issue.yaml
154+
```
155+
156+
Note that, the image is misconfigured, as it does not exist.
157+
158+
2. Inspect the status of the job's Pods by running:
159+
160+
```sh
161+
kubectl get pods -l job-name=job-pod-failure-policy-config-issue -o yaml
162+
```
163+
164+
You will see output similar to this:
165+
```yaml
166+
containerStatuses:
167+
- image: non-existing-repo/non-existing-image:example
168+
...
169+
state:
170+
waiting:
171+
message: Back-off pulling image "non-existing-repo/non-existing-image:example"
172+
reason: ImagePullBackOff
173+
...
174+
phase: Pending
175+
```
176+
177+
Note that the pod remains in the `Pending` phase as it fails to pull the
178+
misconfigured image. This, in principle, could be a transient issue and the
179+
image could get pulled. However, in this case, the image does not exist so
180+
we indicate this fact by a custom condition.
181+
182+
3. Add the custom condition. First prepare the patch by running:
183+
184+
```sh
185+
cat <<EOF > patch.yaml
186+
status:
187+
conditions:
188+
- type: ConfigIssue
189+
status: "True"
190+
reason: "NonExistingImage"
191+
lastTransitionTime: "$(date -u +"%Y-%m-%dT%H:%M:%SZ")"
192+
EOF
193+
```
194+
Second, select one of the pods created by the job by running:
195+
```
196+
podName=$(kubectl get pods -l job-name=job-pod-failure-policy-config-issue -o jsonpath='{.items[0].metadata.name}')
197+
```
198+
199+
Then, apply the patch on one of the pods by running the following command:
200+
201+
```sh
202+
kubectl patch pod $podName --subresource=status --patch-file=patch.yaml
203+
```
204+
205+
If applied successfully, you will get a notification like this:
206+
207+
```sh
208+
pod/job-pod-failure-policy-config-issue-k6pvp patched
209+
```
210+
211+
4. Delete the pod to transition it to `Failed` phase, by running the command:
212+
213+
```sh
214+
kubectl delete pods/$podName
215+
```
216+
217+
5. Inspect the status of the Job by running:
218+
219+
```sh
220+
kubectl get jobs -l job-name=job-pod-failure-policy-config-issue -o yaml
221+
```
222+
223+
In the Job status, see a job `Failed` condition with the field `reason`
224+
equal `PodFailurePolicy`. Additionally, the `message` field contains a
225+
more detailed information about the Job termination, such as:
226+
`Pod default/job-pod-failure-policy-config-issue-k6pvp has condition ConfigIssue matching FailJob rule at index 0`.
227+
228+
{{< note >}}
229+
In a production environment, the steps 3 and 4 should be automated by a
230+
user-provided controller.
231+
{{< /note >}}
232+
233+
### Cleaning up
234+
235+
Delete the Job you created:
236+
237+
```sh
238+
kubectl delete jobs/job-pod-failure-policy-config-issue
239+
```
240+
241+
The cluster automatically cleans up the Pods.
242+
132243
## Alternatives
133244

134245
You could rely solely on the
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
apiVersion: batch/v1
2+
kind: Job
3+
metadata:
4+
name: job-pod-failure-policy-config-issue
5+
spec:
6+
completions: 8
7+
parallelism: 2
8+
template:
9+
spec:
10+
restartPolicy: Never
11+
containers:
12+
- name: main
13+
image: "non-existing-repo/non-existing-image:example"
14+
backoffLimit: 6
15+
podFailurePolicy:
16+
rules:
17+
- action: FailJob
18+
onPodConditions:
19+
- type: ConfigIssue

0 commit comments

Comments
 (0)