0

语境

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

设想

用户可以选择用于作业的 docker 镜像的版本,例如 1.0.0、1.1.0,甚至是在测试环境中构建镜像的代码的提交哈希。

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

问题

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

可能性

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

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

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

任何其他?

4

3 回答 3

2

在查看了您的设计之后,我建议将InitContainer添加到作业规范中,以检查是否存在具有给定标签的 docker 映像。

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

之后 Job 的 Pod 将重新启动。经过一定数量的尝试后,Job 将获得Failed状态。通过配置.spec.ttlSecondsAfterFinished选项,可以清除失败的作业。

如果 Pod 的 init 容器失败,Kubernetes 会反复重启 Pod,直到 init 容器成功。但是,如果 Pod 的 restartPolicy 为 Never,Kubernetes 不会重启 Pod。

如果镜像存在,则 InitContainer 脚本以零退出代码退出,主 Job 容器镜像将被拉出并启动容器。

于 2019-11-01T19:55:19.520 回答
0

当 Job 完成时,不会再创建 Pod,但也不会删除 Pod。

默认情况下,除非 Pod 失败(restartPolicy=Never)或 Container 错误退出(restartPolicy=OnFailure),否则 Job 将不间断运行,此时 Job 将遵循上述.spec.backoffLimit 。一旦达到 .spec.backoffLimit,Job 将被标记为失败,并且任何正在运行的 Pod 都将被终止。

终止作业的另一种方法是设置活动截止日期。通过将 Job 的.spec.activeDeadlineSeconds字段设置为秒数来执行此操作。无论创建了多少 Pod,activeDeadlineSeconds 都适用于作业的持续时间一旦 Job 达到 activeDeadlineSeconds,其所有正在运行的 Pod 都将终止,并且 Job 状态将变为 type: Failed with reason: DeadlineExceeded。

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

这里有更多信息:工作

您还可以设置cronjobconcurrencyPolicy替换当前正在运行的作业并用新作业替换。

这是一个例子:

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标志设置替换值意味着如果是新作业运行的时间并且之前的作业运行尚未完成,则 cron 作业将当前正在运行的作业运行替换为新的作业运行。

无论这种解决方案如何,您的问题都在于错误的图像,因此自动删除 pod 或作业并不能解决问题。因为如果您不更改作业和图像的定义中的任何内容,您的 pod 在再次创建作业后仍然会失败。

以下是 Error: ImagePullBackOff Normal BackOff: ImagePullBackOff的故障排除示例。

于 2019-10-25T08:27:50.960 回答
0

您可以failedJobsHistoryLimit用于失败的工作和successfulJobsHistoryLimit成功的工作

使用这两个参数,你可以保持你的工作历史干净

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

于 2019-10-24T10:16:07.273 回答