开放问答
K8s CronJob 偶发不执行又偶发重复执行:时区、concurrencyPolicy 与错过窗口该按什么顺序排查?
该问题的正文、回答与评论。
提问者 沈砚舟-206 · 状态 open
CronJobKubernetes调度时区运维
背景
我负责一个 12 节点(16C64G,Kubernetes 1.28.9,containerd 1.7.13,cgroup v2)的生产集群,上面跑着一批用 CronJob 做的离线任务:凌晨对账、日志归档、证书续期检查,schedule 基本是 0 3 * * * 这种整点。最近一个月出现两类让人头疼的现象:
一是同一条 CronJob 偶发不执行——kubectl get cronjob -o wide 里 lastScheduleTime 直接跳过了那天,而对应时间点的 Job 列表里又没有任何失败记录,节点、apiserver、etcd 当时都没有告警;二是偶尔重复执行,同一个 schedule 在同一小时里出现了两个 Job,业务侧的对账任务直接重复跑,差点把数算错。
已尝试的排查与结果
- 时钟:所有节点
timedatectl一致,NTP 正常,chronyc tracking看 System time 误差 <50ms,基本排除节点时钟; - CronJob 字段:
concurrencyPolicy当时是默认的Allow,startingDeadlineSeconds=600,successfulJobsHistoryLimit=3; - apiserver / controller-manager 日志:翻了对应时间窗的日志,没有明显报错;
- 时区:业务镜像里
TZ=Asia/Shanghai也设了,但我不确定 CronJob 的 schedule 到底按哪个时区解析(是 apiserver 的本地时区?还是 UTC?)。
卡点 这两类现象我都定位不到根因层级——到底是 CronJob 控制器调度时机、节点时钟漂移、schedule 表达式/时区理解错了,还是并发策略导致的?我怀疑不执行和重复执行其实是同一个根因的两个面,但没证据。
期望得到的答案形态
- 一份排查顺序清单:从哪一层先查(controller-manager → apiserver → 节点时钟 → Job 对象时间戳),每层用什么关键命令 / 指标一锤定音(比如
kubectl get cronjob -o jsonpath='{.status.lastScheduleTime}'、kubectl get events、controller 的--v日志级别); - CronJob 的 schedule 到底按什么时区解析,UTC 还是 apiserver 本地时区?有没有官方说法?
startingDeadlineSeconds和concurrencyPolicy在「宁可漏跑、不可重跑」的幂等性设计上,你们一般怎么取舍?为什么?
欢迎带具体踩坑案例来聊,越具体越好。
评论
暂无评论。