如何自动删除由 CronJob 创建的已完成的 Kubernetes 作业?

How to automatically remove completed Kubernetes Jobs created by a CronJob?

除了创建 CronJob 来清理已完成的 Jobs 之外,还有什么方法可以自动删除已完成的 Jobs 吗?

K8s Job Documentation 声明已完成作业的预期行为是让它们保持已完成状态,直到被手动删除。因为我每天通过 CronJobs 运行 成千上万的工作,我不想保留已完成的工作。

如文档 "It is up to the user to delete old jobs" 中所述,请参阅 http://kubernetes.io/docs/user-guide/jobs/#job-termination-and-cleanup

我会 运行 一个 pod 来根据作业名称和某些条件进行清理,从而让 kubernetes 至少在这里处理您的进程的可用性。你可以 运行 一个重复的工作(假设你 运行 kubernetes 1.5)。

通过 运行 cron 作业删除它们的简单方法:

kubectl get jobs --all-namespaces | sed '1d' | awk '{ print , "--namespace",  }' | while read line; do kubectl delete jobs $line; done

您现在可以设置历史记录限制,或完全禁用历史记录,这样失败或成功的 CronJobs 就不会无限期地保留下来。看我的回答here. Documentation is here.

设置history limits:

The .spec.successfulJobsHistoryLimit and .spec.failedJobsHistoryLimit fields are optional. These fields specify how many completed and failed jobs should be kept. By default, they are set to 3 and 1 respectively. Setting a limit to 0 corresponds to keeping none of the corresponding kind of jobs after they finish.

限制为 0 的配置如下所示:

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  successfulJobsHistoryLimit: 0
  failedJobsHistoryLimit: 0
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure

我最近构建了一个 kubernetes-operator 来完成这个任务。

部署后,它将监视选定的命名空间并删除已完成的 jobs/pods(如果它们在没有 errors/restarts 的情况下完成)。

https://github.com/lwolf/kube-cleanup-operator

我发现以下方法有效

删除失败的作业:

kubectl delete job $(kubectl get jobs | awk ' ~ 0' | awk '{print }')

删除已完成的作业:

kubectl delete job $(kubectl get jobs | awk ' ~ 1' | awk '{print }')

使用 jsonpath:

kubectl delete job $(kubectl get job -o=jsonpath='{.items[?(@.status.succeeded==1)].metadata.name}')

从 1.12 Alpha 版 ttlSecondsAfterFinished 开始,这是可能的。来自 Clean Up Finished Jobs Automatically 的示例:

apiVersion: batch/v1
kind: Job
metadata:
  name: pi-with-ttl
spec:
  ttlSecondsAfterFinished: 100
  template:
    spec:
      containers:
      - name: pi
        image: perl
        command: ["perl",  "-Mbignum=bpi", "-wle", "print bpi(2000)"]
      restartPolicy: Never

我正在使用 wernight/kubectl 的 kubectl 镜像

安排了一个 cron 删除任何

  • completed
  • 2 - 9 days old(所以我有 2 天的时间来审查任何失败的工作)

它每 30 分钟运行一次,所以我没有考虑 10 天以上的作业

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: cleanup
spec:
  schedule: "*/30 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: kubectl-runner
            image: wernight/kubectl
            command: ["sh", "-c", "kubectl get jobs | awk ' ~ /[2-9]d$/ ||  ~ 1' | awk '{print }' | xargs kubectl delete job"]
          restartPolicy: Never

另一种方式:

kubectl delete jobs --field-selector status.successful=1 

这可以在 cronjob 中执行,类似于其他答案。

  1. 创建一个服务帐户,例如my-sa-name
  2. 为资源作业创建具有列表和删除权限的角色
  3. 在服务帐户中附加角色(角色绑定)
  4. 创建一个将使用服务帐户的 cronjob,该服务帐户将检查已完成的作业并将其删除
# 1. Create a service account

apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-sa-name
  namespace: default

---

# 2. Create a role

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
  namespace: default
  name: my-completed-jobs-cleaner-role
rules:
- apiGroups: [""]
  resources: ["jobs"]
  verbs: ["list", "delete"]

---

# 3. Attach the role to the service account

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
  name: my-completed-jobs-cleaner-rolebinding
  namespace: default
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: Role
  name: my-completed-jobs-cleaner-role
subjects:
- kind: ServiceAccount
  name: my-sa-name
  namespace: default

---

# 4. Create a cronjob (with a crontab schedule) using the service account to check for completed jobs

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: jobs-cleanup
spec:
  schedule: "*/30 * * * *"
  jobTemplate:
    spec:
      template:
        spec:
          serviceAccountName: my-sa-name
          containers:
          - name: kubectl-container
            image: bitnami/kubectl:latest
            # I'm using bitnami kubectl, because the suggested kubectl image didn't had the `field-selector` option
            command: ["sh", "-c", "kubectl delete jobs --field-selector status.successful=1"]
          restartPolicy: Never