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 也会保留,状态标记为 CompletedError

✅ 保留历史记录的好处是便于排查问题、查看日志。
❌ 但如果 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 的数量,默认为 3
  • failedJobsHistoryLimit:保留失败 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 设置合适的 successfulJobsHistoryLimitfailedJobsHistoryLimit,并定期清理手动创建的 Job。


原始标题:Automatically Remove Completed Kubernetes Jobs