CronJob的schedule字段必须正确配置,否则任务不会触发;默认按UTC时间解析,v1.24+需显式设spec.timeZone为IANA时区名(如"Asia/Shanghai")才生效,且jobTemplate中restartPolicy仅允许OnFailure或Never。

CronJob 的 schedule 字段必须写对,否则任务根本不会触发
默认 Kubernetes 控制器使用 UTC 时间解析 schedule,不是你的本地时间。比如你写 "0 9 * * *",本意是每天上午 9 点执行,结果会在 UTC 时间 9 点(即北京时间 17 点)运行。v1.24+ 版本支持 spec.timeZone 字段,显式指定时区才能按预期生效:
-
spec.timeZone: "Asia/Shanghai"—— 必须是 IANA 时区名,不能写GMT+8或CST - 集群节点操作系统时区不影响 CronJob 解析,只看这个字段和 API Server 配置
- 低于 v1.24 的集群不支持该字段,只能手动换算 UTC 时间或在容器内自行处理时区
jobTemplate 中 restartPolicy 只能是 OnFailure 或 Never
这是硬性校验,写成 Always 会导致 kubectl apply 失败,并报错:restartPolicy must be 'OnFailure' or 'Never'。原因很直接:CronJob 每次调度生成一个 Job,而 Job 本身设计就是“完成即终止”,不该自重启。
- 用
OnFailure:容器退出码非 0 时重试(受backoffLimit控制) - 用
Never:失败后不重试,直接标记 Job 为 Failed - 别漏掉
jobTemplate.spec.template.spec.restartPolicy这层嵌套,少一层就无效
concurrencyPolicy 和 startingDeadlineSeconds 决定任务是否“准时”
评估 Kubernetes 集群安全态势,覆盖 RBAC、工作负载安全、网络策略、基础设施即代码(IaC)、运行时监控和密钥管理等 30 项控制项……
默认 concurrencyPolicy: Allow,意味着前一个 Job 还没结束,下一个调度照样创建新 Pod —— 容易引发并发冲突或资源争抢。更常见的需求其实是“跳过”或“替换”:
-
concurrencyPolicy: Forbid:正在运行的 Job 未完成,本次调度直接丢弃(适合数据库备份等有状态操作) -
concurrencyPolicy: Replace:新调度启动时,自动删除旧 Job 的 Pod(适合“取最新结果”类任务) -
startingDeadlineSeconds: 300:如果控制器卡住或高负载,导致某次调度延迟超 5 分钟,就不再补跑,标记为 MissSchedule
不设 successfulJobsHistoryLimit / failedJobsHistoryLimit 会拖慢集群
每个成功 Job 会生成一个 Pod + Job 对象,长期积累成千上万个 Job 资源,etcd 压力上升,kubectl get jobs 变慢,甚至影响调度器性能。默认值(3 个成功 + 1 个失败)对多数场景太宽松:
- 调试阶段可设为
successfulJobsHistoryLimit: 0,完全不保留成功记录 - 生产环境建议
successfulJobsHistoryLimit: 1+failedJobsHistoryLimit: 3,够查问题又不堆积 - 这两个字段必须写在
spec下,不是jobTemplate里
真正容易被忽略的是 spec.timeZone 的可用性边界——它只在 v1.24 及以上生效,而很多线上集群还在 v1.22/v1.23;此时硬写该字段会被 API Server 忽略,但不会报错,任务照常按 UTC 执行,排查时极难发现。务必先确认集群版本再决定是否依赖它。

















