DEBUG.WIKI
京东云;让 AI 进入真实业务;零售 · 物流 · 客服 · 硬件;查看方案 →
ZgoCloud:多地区部署,按需选节点;日本、美国、香港、德国
Evoxt;最高 6.0GHz CPU;高频云服务器 · 免费每周备份;查看配置 →

CronJob 提示 too many missed start times:区分历史补跑与后续调度

CronJob 出现漏调警告时,区分历史补跑与后续调度,检查控制器版本、启动截止窗口、暂停及并发策略,再核对实际 Job 与业务结果。

CronJob 的事件或控制器日志出现 too many missed start times,长时间没有新任务。先确认缺的是以前漏掉的执行,还是接下来的计划也没有创建 Job。这个警告涉及漏调统计窗口,不能直接解释成“运行失败超过 100 次”或“CronJob 永久停止”。

以下针对 Kubernetes 原生 CronJob。旧控制器与较新的控制器处理超量漏调的方式不同:1.19 的实现会在超过 100 次时返回错误;1.34 的控制器会记录 TooManyMissedTimes 警告并继续返回最近的计划时间,后面仍要检查截止时间、并发策略等条件。不能仅凭同一句警告判断所有版本的调度结果。

先看 Job 有没有创建,再看 Pod

在正确的集群和命名空间做只读检查。下面的 ops、nightly-report 是占位示例:

kubectl -n ops get cronjob nightly-report -o yaml
kubectl -n ops describe cronjob nightly-report
kubectl -n ops get jobs

核对 schedule、suspend、startingDeadlineSeconds、concurrencyPolicy,以及 status.lastScheduleTime 和 status.active。列表里的其他 Job 不证明这个 CronJob 已执行,需检查 Job 的 ownerReferences 是否指向它的 UID。历史 Job 也可能已经被清理,列表为空不能单独证明从未调度。

如果新 Job 已创建,但 Pod 处于 Pending、拉取镜像失败或执行出错,应检查该 Job 与 Pod;缩短漏调窗口不会修复这些运行阶段的故障。CronJob 负责按计划创建 Job,Job 再负责管理 Pod。

Kubernetes 1.32 起创建的 Job 可带 batch.kubernetes.io/cronjob-scheduled-timestamp 注解,用于核对原计划时刻。旧集群没有这个注解不能当作异常,且创建时间与业务真正开始工作的时间可能不同。

漏调次数从哪个时间开始计算

没有设置 startingDeadlineSeconds 时,统计通常从最近调度时间开始;没有记录时则参考 CronJob 创建时间。控制器停机很久、暂停后恢复,或 Forbid 策略遇到长任务,都可能扩大这个窗口。

设置了 startingDeadlineSeconds 后,窗口的起点不会早于“现在减去该秒数”。例如每分钟运行一次、只允许晚启动 200 秒,就不再把几天前的全部漏调都算入当前补跑窗口。它同时是启动截止时间:超过允许延迟的那次执行会被跳过。

这个字段不是“最多运行 200 秒”,也不是补跑数量。调整它会改变哪些迟到任务仍有资格启动,必须由业务决定可以放弃多旧的执行。历史遗漏需要单独核对,不能靠当前任务成功就宣布已经补齐。

下面是字段关系示例,只展示现有 CronJob 的 spec 片段,不是可独立部署的完整资源:

spec:
  schedule: "* * * * *"
  startingDeadlineSeconds: 200
  concurrencyPolicy: Forbid
  suspend: false

200 秒只适合允许这种延迟的业务;不要为消除警告照抄。设置小于 10 秒的窗口可能使任务无法调度,因为控制器检查有时间间隔。

后续仍没有新 Job,继续核对阻挡条件

suspend 为 true 时不会启动后续任务,已开始的 Job 不受影响。暂停期间的计划仍会计为漏调;恢复前应评估积累的任务和截止窗口,避免一边恢复调度,一边无审核地手工补跑。

Forbid 会在同一个 CronJob 的上一轮仍运行时跳过新一轮。查看 active 对应的 Job 是否真的还在运行、是否卡住,以及任务耗时是否超过计划间隔。上一轮完成后仍需符合启动截止条件;直接切成 Allow 会引入并发,切成 Replace 则可能终止正在运行的工作,二者都不是无影响的修复。

若计划时刻与预期不符,核对控制平面时间、时区与 schedule。Kubernetes 1.27 起可使用 spec.timeZone;没有设置时按控制器本地时区解释。不要把 TZ 或 CRON_TZ 塞进 schedule 代替受支持的时区字段。托管集群的控制器日志和时钟检查应通过提供方允许的管理入口完成。

已经超出窗口的历史任务、旧控制器返回错误,以及近期有资格调度却没有创建 Job,是不同结果。检查集群实际版本和控制器事件,别通过删除重建 CronJob 清空判断依据,也别直接修改 status.lastScheduleTime 伪造进度。

调整后验证后续计划与业务结果

修改前保存资源配置及相关事件,确认旧任务状态和允许的补跑范围。更新 CronJob 只影响随后创建的 Job,已经运行的任务不会随模板自动改变。

至少观察一个符合新窗口的计划时刻,确认创建了属于该 CronJob 的新 Job,再检查 Pod 完成情况和业务产物。警告消失不是唯一标准;CronJob 的调度也不保证严格只执行一次,任务应具备幂等或去重能力。

需要回退时恢复原配置,并核对调整期间已创建的 Job。配置回退不会取消已开始的工作,也不会撤销已经提交的报表、备份或业务写入。缺失的历史执行是否补做,应按业务清单单独处理。