为无法拉取图像的 kubernetes 作业释放 kubernetes 资源的正确方法是什么?

What is the right way to free up kubernetes resources for a kubernetes job that fails pulling the image?

上下文

我们有长期 运行 基于 docker 容器的 kubernetes 作业。 容器需要资源(例如 15gb 内存,2 cpu),我们使用自动缩放器根据请求扩展新的工作节点。

场景

用户可以 select 用于作业的 docker 映像的版本,例如 1.0.0、1.1.0,甚至是构建映像的代码的提交哈希来自测试环境。

由于我们将 docker 标签保留为自由文本,因此用户可以键入不存在的 docker 标签。因此,作业 pod 进入 ImagePullBackOff 状态。 pod 保持此状态并保持资源锁定,以便它们不能被任何其他作业重用。

问题

什么是正确的解决方案,可以应用于 kubernetes 本身,如果由于不存在的拉取失败 docker image:tag,立即或至少快速使 pod 失败?

可能性

我调查了 backofflimit。我已将其设置为 0,但这不会失败或删除作业。资源当然也要保留。

也许他们可以被 cron 作业杀死。不知道该怎么做。

理想情况下,甚至不应该为具有不存在的 docker 图像的作业分配资源。但我不确定是否有可能轻松实现这一目标。

还有其他吗?

您可以将 failedJobsHistoryLimit 用于失败的作业,将 successfulJobsHistoryLimit 用于成功的作业

使用这两个参数,您可以保持工作历史的清洁

.spec.backoffLimit 指定在将作业视为失败之前的重试次数。

作业完成后,不再创建 Pods,但也不会删除 Pods。

默认情况下,Job 将 运行 不间断,除非 Pod 失败(restartPolicy=Never)或 Container 错误退出(restartPolicy=OnFailure),此时 Job 会延迟到 .spec.backoffLimit 如上所述。一旦达到 .spec.backoffLimit 作业将被标记为失败并且任何 运行ning Pods 将被终止。

终止作业的另一种方法是设置有效截止日期。通过将作业的 .spec.activeDeadlineSeconds 字段设置为秒数来执行此操作。 activeDeadlineSeconds 适用于作业的持续时间,无论创建了多少 Pods。一旦作业达到 activeDeadlineSeconds,其所有 运行ning Pods 将被终止,作业状态将变为类型:失败,原因:DeadlineExceeded。

请注意,作业的 .spec.activeDeadlineSeconds 优先于其 .spec.backoffLimit。因此,重试一个或多个失败的作业 Pods 一旦达到 activeDeadlineSeconds 指定的时间限制,将不会部署额外的 Pods,即使 backoffLimit 是还没到。

这里有更多信息:jobs

您还可以将 concurrencyPolicy of cronjob 设置为 Replace 并用新作业替换当前 运行ning 作业。

这是一个例子:

apiVersion: batch/v1beta1
kind: CronJob
metadata:
  name: hello
spec:
  schedule: "*/2 * * * *"
  concurrencyPolicy: Replace
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: hello
            image: busybox
            args:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster && sleep 420
          restartPolicy: Never

concurrencyPolicy 标志设置 Replace 值意味着是否是新作业 运行 和上一个作业 运行 还没有完成,cron 作业用新作业 运行.

替换当前 运行ning 作业 运行

无论采用何种解决方案,您的问题都出在错误的图像上,因此自动删除 pods 或作业无法解决问题。因为如果您不更改作业和图像的定义,您的 pods 在再次创建作业后仍然会失败。

以下是错误的故障排除示例:ImagePullBackOff 正常退避:ImagePullBackOff

在查看您的设计后,我建议添加 InitContainer to Job specification to 张带有给定标签的 docker 张图片。

如果注册表中不存在带有标签的图像,InitContainer 可以报告错误并通过使用非零退出代码退出来使 Job 的 Pod 失败。

之后Job's Pod 将是restarted. After certain amount of attempts Job will get Failed state. By configuring .spec.ttlSecondsAfterFinished 选项,失败的jobs 可以被清除。

If a Pod’s init container fails, Kubernetes repeatedly restarts the Pod until the init container succeeds. However, if the Pod has a restartPolicy of Never, Kubernetes does not restart the Pod.

如果映像存在,InitContainer 脚本将以零退出代码退出,并且将拉取主作业容器映像并启动容器。