如何确保我的 cronjob 作业不会在失败时重试?

How do I make sure my cronjob job does NOT retry on failure?

我有一个 Kubernetes Cronjob 运行GKE 和 运行Cucumber JVM 测试。如果 Step 由于断言失败、某些资源不可用等原因而失败,Cucumber 会正确地抛出异常,导致 Cronjob 作业失败并且 Kubernetes pod 的状态更改为 ERROR。这会导致创建一个新 pod,该 pod 再次尝试 运行 相同的 Cucumber 测试,但再次失败并再次重试。

我不希望任何这些重试发生。如果 Cronjob 作业失败,我希望它保持失败状态并且根本不重试。基于 ,我已经尝试将 backoffLimit: 0restartPolicy: Never 结合 concurrencyPolicy: Forbid 结合设置,但它仍然通过创建新的 pods 和 运行再次测试。

我错过了什么?这是我的 Cronjob 的 kube 清单:

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: quality-apatha
  namespace: default
  labels:
    app: quality-apatha
spec:
  schedule: "*/1 * * * *"
  concurrencyPolicy: Forbid
  jobTemplate:
    spec:
      backoffLimit: 0
      template:
        spec:
          containers:
            - name: quality-apatha
              image: FOO-IMAGE-PATH
              imagePullPolicy: "Always"
              resources:
                limits:
                  cpu: 500m
                  memory: 512Mi
              env:
                - name: FOO
                  value: BAR
              volumeMounts:
                - name: FOO
                  mountPath: BAR
              args:
                - java
                - -cp
                - qe_java.job.jar:qe_java-1.0-SNAPSHOT-tests.jar
                - org.junit.runner.JUnitCore
                - com.liveramp.qe_java.RunCucumberTest
          restartPolicy: Never
          volumes:
            - name: FOO
              secret:
                secretName: BAR

是否有任何其他 Kubernetes Kind 我可以用来停止重试?

谢谢!

为了让事情尽可能简单,我使用官方 kubernetes 文档中的 this 示例对其进行了测试,对其进行了微小的修改以说明在不同场景中实际发生的情况。

我可以确认当 backoffLimit 设置为 0 并且 restartPolicy 设置为 Never 一切都按预期工作并且没有重试。请注意,您的 Job 中的每个 运行 在您的示例中被安排为 运行 每隔 60 秒 (schedule: "*/1 * * * *") 不被视为重试

让我们仔细看看下面的例子(base yaml avialable here):

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/1 * * * *"
  jobTemplate:
    spec:
      backoffLimit: 0
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - non-existing-command
          restartPolicy: Never

它会根据 schedule 生成新的 cron 作业 every 60 seconds,无论它是失败还是成功 运行。在此特定示例中,它被配置为失败,因为我们正在尝试 运行 non-existing-command.

您可以通过 运行ning:

查看发生了什么
$ kubectl get pods
NAME                     READY   STATUS              RESTARTS   AGE
hello-1587558720-pgqq9   0/1     Error               0          61s
hello-1587558780-gpzxl   0/1     ContainerCreating   0          1s

如您所见,没有重试。尽管第一个 Pod 失败了,但根据我们的规范,新的 Pod 会在 60 秒后生成。我想再强调一下。 这不是重试。

另一方面,当我们修改上面的示例并设置 backoffLimit: 3 时,我们可以观察到 重试 。如您所见,现在创建新 Pods 的频率 比每 60 秒 的频率高得多。 这是重试。

$ kubectl get pods
NAME                     READY   STATUS   RESTARTS   AGE
hello-1587565260-7db6j   0/1     Error    0          106s
hello-1587565260-tcqhv   0/1     Error    0          104s
hello-1587565260-vnbcl   0/1     Error    0          94s
hello-1587565320-7nc6z   0/1     Error    0          44s
hello-1587565320-l4p8r   0/1     Error    0          14s
hello-1587565320-mjnb6   0/1     Error    0          46s
hello-1587565320-wqbm2   0/1     Error    0          34s

上面我们可以看到3次重试Pod次创建尝试),与hello-1587565260相关 job4次重试(包括原来的第一次尝试不计入backoffLimit: 3)与hello-1587565320相关工作.

如您所见,作业本身仍然运行按照时间表,以 60 秒为间隔:

kubectl get jobs
NAME               COMPLETIONS   DURATION   AGE
hello-1587565260   0/1           2m12s      2m12s
hello-1587565320   0/1           72s        72s
hello-1587565380   0/1           11s        11s

然而,由于我们的 backoffLimit 将此时间设置为 3,每次负责 运行ning 作业的 Pod 都会失败,3发生额外的重试

我希望这有助于消除关于 运行ning cronJobskubernetes.

中的任何可能的混淆

如果您对只 运行 某事感兴趣,而不是定期,请查看简单的 Job 而不是 CronJob

如果您仍想 运行 定期执行此特定工作,也可以考虑更改 Cron 配置,但假设是 24 小时一次,而不是每分钟一次。