在调查了Kubernetes repo的代码库之后,这就是 CronJob 控制器的工作方式:
CronJob 控制器将每 10 秒检查给定 Kubernetes 客户端中的 cronjobs 列表。
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
可以在这里找到计算错过的时间表的确切实现。
如果上一步错过的计划不超过 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 点中所述计算的。