前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Kubernetes 1.28:改进了作业的故障处理

Kubernetes 1.28:改进了作业的故障处理

作者头像
灵雀云
发布2023-09-07 19:03:32
1720
发布2023-09-07 19:03:32
举报

作者:Kevin Hannon (G-Research), Michał Woźniak (Google)

本篇文章讨论了 Kubernetes 1.28 版本中为了改进批量用户的作业而引入的两个新功能:Pod 替换策略和每个索引的退避限制。

这些功能延续了由 Pod 失败策略发起的努力,以改进作业中 Pod 故障的处理。

Pod 替换策略

默认情况下,当一个 Pod 进入终止状态(例如由于抢占或驱逐),Kubernetes 会立即创建一个替代的 Pod。因此,这两个 Pod 同时运行。从 API 的角度来看,当一个 Pod 拥有 .deletionTimestampPendingRunning 时,它被认为是处于终止状态。

对于一些流行的机器学习框架(例如 TensorFlow 和 JAX),在同一时刻最多只允许一个特定索引的 Pod 运行,这种情况会带来问题。如果同一索引有两个 Pod 在运行,TensorFlow 将会报错如下:

代码语言:javascript
复制
/job:worker/task:4: Duplicate task registration with task_name=/job:worker/replica:0/task:4

在前一个 Pod 完全终止之前创建替代 Pod 也可能会在资源稀缺或预算紧张的集群中引发问题,例如:

1. 集群资源可能难以获取,因为待调度的 Pod 可能需要很长时间才能找到可用的节点,直到现有的 Pod 完全终止。

2. 如果启用了集群自动缩放器,替代的 Pod 可能会导致不必要的扩容。

如何使用这些功能呢?

这是一个 alpha 功能,您可以通过在集群中启用功能开关 JobPodReplacementPolicy 来开启。

一旦在您的集群中启用了该功能,您可以通过创建一个新的 Job,并指定一个字段,如下所示,来使用它:podReplacementPolicy

代码语言:javascript
复制
kind: Job
metadata:
  name: new
  ...
spec:
  podReplacementPolicy: Failed
  ...

在该作业中,只有当 Pod 达到阶段时才会进行替换,而不是在其处于终止状态时进行替换。

此外,您可以检查作业的一个字段。该字段的值是由该作业拥有且当前正在终止的 Pod 数量。.status.terminating

代码语言:javascript
复制
kubectl get jobs/myjob -o=jsonpath='{.items[*].status.terminating}'
代码语言:javascript
复制
3 # three Pods are terminating and have not yet reached the Failed phase

对于外部排队控制器(如 Kueue),此功能可能特别有用,它会追踪作业中运行的 Pod 的配额,直到资源从当前正在终止的作业中回收。

请注意,当使用自定义的 Pod 失败策略时,默认为 podReplacementPolicy: Failed。

索引的重试限制

默认情况下,对于索引作业的 Pod 失败会计入全局的重试限制,由 .spec.backoffLimit 表示。这意味着,如果某个索引持续失败,它会被重复重新启动,直到达到限制。一旦达到限制,整个作业将被标记为失败,某些索引可能甚至永远不会启动。

对于需要独立处理每个索引的 Pod 失败的用例,这是有问题的。例如,如果您使用索引作业来运行集成测试,其中每个索引对应一个测试套件。在这种情况下,您可能希望考虑可能出现的测试不稳定性,每个套件允许重试 1 次或 2 次。可能会有一些有问题的套件,导致相应的索引始终失败。在这种情况下,您可能更喜欢限制有问题的套件的重试次数,但允许其他套件完成。

此功能允许您:

  • 尽管某些索引失败,但完成所有索引的执行。
  • 通过避免不必要的持续失败索引重试,更有效地利用计算资源。

如何使用这个功能?

这是一个alpha版功能,您可以通过在集群中打开功能开关 JobBackoffLimitPerIndex 来启用它。

一旦在您的集群中启用了该功能,您可以创建一个带有指定字段的索引作业.spec.backoffLimitPerIndex

示例

以下示例演示了如何使用此功能来确保作业执行所有索引(前提是没有其他导致作业提前终止的原因,比如达到超时时间,或被用户手动删除),并且每个索引的失败次数受到.activeDeadlineSeconds控制。

代码语言:javascript
复制
apiVersion: batch/v1
kind: Job
metadata:
  name: job-backoff-limit-per-index-execute-all
spec:
  completions: 8
  parallelism: 2
  completionMode: Indexed
  backoffLimitPerIndex: 1
  template:
    spec:
      restartPolicy: Never
      containers:
      - name: example # this example container returns an error, and fails,
                      # when it is run as the second or third index in any Job
                      # (even after a retry)        
        image: python
        command:
        - python3
        - -c
        - |
          import os, sys, time
          id = int(os.environ.get("JOB_COMPLETION_INDEX"))
          if id == 1 or id == 2:
            sys.exit(1)
          time.sleep(1)          

现在,在作业完成后检查Pod:

代码语言:javascript
复制
kubectl get pods -l job-name=job-backoff-limit-per-index-execute-all

返回类似以下的输出:

代码语言:javascript
复制
NAME                                              READY   STATUS      RESTARTS   AGE
job-backoff-limit-per-index-execute-all-0-b26vc   0/1     Completed   0          49s
job-backoff-limit-per-index-execute-all-1-6j5gd   0/1     Error       0          49s
job-backoff-limit-per-index-execute-all-1-6wd82   0/1     Error       0          37s
job-backoff-limit-per-index-execute-all-2-c66hg   0/1     Error       0          32s
job-backoff-limit-per-index-execute-all-2-nf982   0/1     Error       0          43s
job-backoff-limit-per-index-execute-all-3-cxmhf   0/1     Completed   0          33s
job-backoff-limit-per-index-execute-all-4-9q6kq   0/1     Completed   0          28s
job-backoff-limit-per-index-execute-all-5-z9hqf   0/1     Completed   0          28s
job-backoff-limit-per-index-execute-all-6-tbkr8   0/1     Completed   0          23s
job-backoff-limit-per-index-execute-all-7-hxjsq   0/1     Completed   0          22s

此外,您还可以查看该作业的状态:

代码语言:javascript
复制
kubectl get jobs job-backoff-limit-per-index-fail-index -o yaml

输出的末尾类似于:status

代码语言:javascript
复制
  status:
    completedIndexes: 0,3-7
    failedIndexes: 1,2
    succeeded: 6
    failed: 4
    conditions:
    - message: Job has failed indexes
      reason: FailedIndexes
      status: "True"
      type: Failed

在这里,索引都重新尝试了一次。在每个索引的第二次失败中,都超过了指定的 backoffLimitPerIndex,因此重试被停止。相比之下,如果禁用了每个索引的退避限制,那么有问题的索引会一直重试,直到全局 backoffLimit 被超过,然后整个作业会被标记为失败,而一些较高的索引在开始之前就会失败。

如何获取更多信息?

阅读有关 Pod 替换策略、每个索引的退避限制和 Pod 失败策略的用户文档。

阅读 Pod 替换策略、每个索引的退避限制和 Pod 失败策略的 KEP(Kubernetes Enhancement Proposal)。

参与其中

这些功能由 SIG Apps 赞助。批处理工作组正在为 Kubernetes 用户积极改进批处理用例。工作组是专注于特定目标的相对短期的倡议。批处理工作组的目标是改善批处理工作负载用户的体验,为批处理用例提供支持,并针对常见用例增强作业 API。如果您对此感兴趣,请通过订阅我们的邮件列表或在 Slack 上加入工作组。

致谢

与 Kubernetes 的任何功能一样,从测试、提交错误到审查代码,许多人都为完成这项工作做出了贡献。

如果没有 Aldo Culquicondor(谷歌)在整个 Kubernetes 生态系统中提供的出色领域知识和专业知识,我们不可能实现这些功能。

本文翻译自Kubernetes.io

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-08-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 云原生技术社区 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档