首页 > 解决方案 > Kubernetes cronjobs `startingDeadlineSeconds` 到底是什么意思?

问题描述

在 Kubernetes cronjobs中,限制部分中指出

如果 CronJob 控制器在从 CronJob 开始时间到开始时间加上startingDeadlineSeconds 之前的一段时间内未运行或中断,或者如果跨度涵盖多个开始时间并且concurrencyPolicy 不允许并发,则作业可能无法运行。

我从中了解到的是,如果startingDeadlineSeconds设置为10并且 cronjob 在其预定时间由于某种原因无法启动,那么只要这些10秒还没有过去,它仍然可以尝试重新启动,但是,之后秒,10它肯定不会启动,这是正确的吗?

另外,如果我concurrencyPolicy设置为Forbid,如果 cronjob 尝试被调度,K8s 是否会将其视为失败,而此时已经有一个 cronjob 正在运行?

标签: kuberneteskubernetes-cronjob

解决方案


在调查了Kubernetes repo的代码库之后,这就是 CronJob 控制器的工作方式:

  1. CronJob 控制器将每 10 秒检查给定 Kubernetes 客户端中的 cronjobs 列表。

  2. lastScheduleTime对于每个 CronJob,它会检查从现在到现在的持续时间内错过了多少计划。如果有超过100 个错过的计划,那么它不会启动作业并记录事件:

    "FailedNeedsStart", "Cannot determine if job needs to be started. Too many missed start time (> 100). Set or decrease .spec.startingDeadlineSeconds or check clock skew."

需要注意的是,如果startingDeadlineSeconds设置了该字段(不是nil),它将计算从 的值startingDeadlineSeconds到现在发生了多少错过的工作。例如,如果startingDeadlineSeconds= ,它将计算在最后几秒钟内200发生了多少错过的作业。200可以在这里找到计算错过的时间表的确切实现。

  1. 如果上一步错过的计划不超过 100 个,CronJob 控制器将检查时间now是否不在其时间之后scheduledTime + startingDeadlineSeconds ,即开始工作还不算太晚(超过了最后期限)。如果还不算太晚,作业将继续尝试由 CronJob 控制器启动。但是,如果已经太晚了,那么它不会开始工作并记录事件:

    "Missed starting window for {cronjob name}. Missed scheduled time to start a job {scheduledTime}"

需要注意的是,如果startingDeadlineSeconds未设置该字段,则意味着根本没有截止日期。这意味着作业将由 CronJob 控制器尝试启动,而不检查它是否更晚。

因此要回答上述问题:

1. 如果startingDeadlineSeconds设置为10,并且由于某种原因无法在预定时间启动cronjob,那么只要这10秒还没有过去,它仍然可以尝试再次启动,但是,在10秒之后,它肯定不会启动,这是正确的吗?

CronJob 控制器将尝试启动作业,如果在其调度时间之后的 10 秒内尚未过去,它将被成功调度。但是,如果截止日期已过,则不会在此运行中启动它,并且在以后的执行中将被计为错过的时间表。

2. 如果我将 concurrencyPolicy 设置为 Forbid,如果 cronjob 尝试调度,而 K8s 是否将其视为失败,而此时已经有一个 cronjob 正在运行?

是的,这将被视为错过的时间表。由于错过的时间表是按照我在上面第 2 点中所述计算的。


推荐阅读