1. 概述
在本篇文章中,我们将学习几种清理 Kubernetes 中已完成 Job 的方法,以避免资源堆积导致集群混乱。
2. Kubernetes Job 与 CronJob
Job 和 CronJob 是 Kubernetes 中用于声明短生命周期任务的 API。Job 用于创建 Pod 并确保其执行完成,而 CronJob 则在此基础上加入了定时调度能力。
2.1. Job
Job 是一种 Kubernetes 资源,用于创建并运行至完成的 Pod。它常用于执行一次性任务,如数据处理、清理操作等。当 Pod 成功执行完毕后,Job 即视为完成。
以下是一个简单的 Job 定义:
apiVersion: batch/v1
kind: Job
metadata:
name: hello-job
spec:
template:
spec:
containers:
- name: hello-container
image: alpine:latest
command: ["echo", "Hello, Kubernetes!"]
restartPolicy: Never
backoffLimit: 4
该 Job 使用 alpine:latest
镜像执行 echo "Hello, Kubernetes!"
命令。restartPolicy: Never
表示 Pod 失败后不会自动重启。如果 Pod 退出码非 0,则 Job 会尝试重试,最多尝试 4 次(由 backoffLimit
控制)。
2.2. CronJob
CronJob 是 Job 的高级封装,支持通过 cron 表达式定时创建 Job,并可配置保留历史执行记录。
以下是一个每分钟运行一次的 CronJob 示例:
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello-cronjob
spec:
schedule: "* * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello-job
image: alpine
command: ["echo", "Hello, Kubernetes!"]
restartPolicy: Never
其中 schedule
字段定义了任务的执行频率,jobTemplate
描述了每次执行时要创建的 Job。
3. Job 执行历史
默认情况下,Kubernetes 不会自动删除已完成的 Job,包括成功和失败的 Job。与之相关的 Pod 也会保留,状态标记为 Completed
或 Error
。
✅ 保留历史记录的好处是便于排查问题、查看日志。
❌ 但如果 Job 频繁运行,未及时清理会造成资源堆积,影响集群性能和可读性。
例如,创建一个 Job 后查看其状态:
$ kubectl apply -f standalone-job.yaml
job.batch/hello-job created
$ kubectl get jobs
NAME COMPLETIONS DURATION AGE
hello-job 1/1 17s 32s
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-job-8kspm 0/1 Completed 0 23s
4. 清理由 CronJob 创建的 Job
CronJob 提供了两个字段用于控制历史 Job 的保留数量:
successfulJobsHistoryLimit
:保留成功 Job 的数量,默认为 3failedJobsHistoryLimit
:保留失败 Job 的数量,默认为 1
我们可以在 CronJob 中设置这些字段来自动清理历史记录:
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello-cronjob
spec:
schedule: "* * * * *"
successfulJobsHistoryLimit: 2
jobTemplate:
spec:
template:
spec:
containers:
- name: hello-job
image: alpine
command: ["echo", "Hello, Kubernetes!"]
restartPolicy: Never
应用后,Kubernetes 会只保留最近两次成功执行的 Job:
$ kubectl get jobs
NAME COMPLETIONS DURATION AGE
hello-cronjob-28761583 1/1 6s 67s
hello-cronjob-28761584 1/1 5s 7s
5. 清理非 CronJob 管理的 Job
对于非 CronJob 创建的 Job,我们可以使用 kubectl delete job
命令手动删除:
$ kubectl delete job hello-job
job.batch "hello-job" deleted
也可以通过 --field-selector
指定条件删除,例如删除所有已完成的 Job:
$ kubectl delete jobs --field-selector status.successful=1
还可以结合标签进行筛选:
$ kubectl delete jobs -l job-type=cleanup-after-done --field-selector status.successful=1
⚠️ 删除操作是不可逆的,请确保已无保留必要后再执行。
6. 总结
- Job 用于运行一次性任务,CronJob 在此基础上支持定时调度
- Kubernetes 默认不会自动清理已完成的 Job,需手动或通过 CronJob 配置历史保留策略
- 对于非 CronJob 管理的 Job,可使用
kubectl delete
命令结合标签或字段选择器进行批量清理
合理配置清理策略有助于保持集群整洁,避免资源浪费和管理混乱。在实际生产环境中,建议为 CronJob 设置合适的 successfulJobsHistoryLimit
和 failedJobsHistoryLimit
,并定期清理手动创建的 Job。