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

Cor*_*ped 2 cucumber-jvm kubernetes google-kubernetes-engine kubernetes-pod kubernetes-cronjob

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

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

我错过了什么?这是我的 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
Run Code Online (Sandbox Code Playgroud)

Kind我可以使用其他任何 Kubernetes来停止重试吗?

谢谢!

mar*_*rio 8

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

我可以确认 whenbackoffLimit设置为0restartPolicytoNever 一切都按预期工作,并且没有重试。请注意,Job在您的示例中,您的每一次运行都计划以60 秒( schedule: "*/1 * * * *") 的间隔运行,这不被视为重试

让我们仔细看看下面的例子(基本yaml可用在这里):

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
Run Code Online (Sandbox Code Playgroud)

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

您可以通过运行来检查发生了什么:

$ kubectl get pods
NAME                     READY   STATUS              RESTARTS   AGE
hello-1587558720-pgqq9   0/1     Error               0          61s
hello-1587558780-gpzxl   0/1     ContainerCreating   0          1s
Run Code Online (Sandbox Code Playgroud)

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

另一方面,当我们修改上面的例子并设置时backoffLimit: 3,我们可以观察到重试。如您所见,现在 newPods的创建频率远高于每 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
Run Code Online (Sandbox Code Playgroud)

我们可以看到上面有3个重Pod创作尝试),具有相关hello-1587565260 工作4重试(包括一部开拓创新的第一次尝试在不计算在内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
Run Code Online (Sandbox Code Playgroud)

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

我希望这有助于消除有关cronJobskubernetes 中运行的任何可能的混淆。

如果您对只运行一次而不是定期运行某事很感兴趣,请查看 simple Job而不是CronJob.

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