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

CronJob 固定晚八小时:Pod 的 TZ 不会改变控制器调度时区

CronJob 稳定偏差八小时,Pod 的 TZ 无法改变控制器计划。核对 Job 计划时间,Kubernetes 1.27 起在 spec.timeZone 指定时区,保留旧集群与夏令时边界。

CronJob 每天都会创建 Job,但执行时刻与预期固定差八小时。给 Pod 设置 TZ=Asia/Shanghai,容器里的 date 已显示本地时间,调度却没有改变。CronJob 的 schedule 由控制器解释,Pod 内的时区不会回头改变控制器何时创建 Job。

对于 Kubernetes 1.27 起的原生 CronJob,可以通过 spec.timeZone 明确调度时区。未设置这个字段时,控制器按自己的本地时区解释 schedule;不能仅凭 Pod、工作节点或本地 kubectl 的时间,就断言控制器使用 UTC。

先确认偏差来自计划时刻

在实际集群与命名空间查看资源。以下名称是示例:

kubectl version
kubectl -n ops get cronjob daily-report -o yaml
kubectl -n ops describe cronjob daily-report
kubectl -n ops get jobs

核对服务端版本、最终 schedule、timeZone、suspend,以及最近创建的 Job 是否确实由该 CronJob 的 UID 管理。不要用另一个同名集群的输出,也不要把任意一条报表日志当作 Job 创建时间。

Kubernetes 1.32 起的 Job 可以有 batch.kubernetes.io/cronjob-scheduled-timestamp 注解,用于核对原定计划时刻。创建时间、Pod 真正开始运行和业务处理完成是不同的时间;Pending、镜像拉取或上轮长任务造成的延迟,不能靠改时区解决。

若每次计划本身就固定偏移,再检查控制器的时区和资源字段。托管集群通过提供方允许的管理入口确认,不为了一个 CronJob 去修改所有节点的时区或重建控制平面。

在 CronJob 的 spec 中设置 timeZone

下面是现有 CronJob 的配置片段,用当地时区安排每天 10、14、18 点执行,不是可单独提交的完整资源:

spec:
  schedule: "0 10,14,18 * * *"
  timeZone: "Asia/Shanghai"

timeZone 与 schedule 同属 CronJob 的 spec;不是 jobTemplate 内 Pod 的 spec,也不是容器环境变量。该字段使用有效的时区名称,不用 UTC+8 一类未经支持的自造字符串。

原生 CronJob 的计划表达式使用五个时间字段。不要从另一个 cron 库复制带秒的六字段表达式,也不要在 schedule 中写 TZ=Asia/Shanghai 或 CRON_TZ=Asia/Shanghai;这些做法不能代替受支持的 timeZone 字段,当前 Kubernetes 会拒绝这样的时区写法。

采用地区时区后,夏令时转换可能使某些当地时刻缺失或重复。任务涉及夏令时地区时,先决定业务要遵循当地钟表还是固定 UTC,再按该时区规则验证边界日期;不能对所有地区永远加减同一个小时数。

旧集群没有这个字段怎么办

本文按 1.27 起正式支持的字段说明。较旧集群需要按实际版本和功能配置确认能力;直接把当前清单提交给旧 API,可能被拒绝或不能达到预期。升级和功能配置应走原集群维护流程,不根据网上一段旧特性门配置临时改控制器。

确实只能保留旧集群时,先确认控制器的实际时区,再将业务计划换算成它采用的时间。例如,只有确认控制器按 UTC、业务固定采用 UTC+8 时,当地 10、14、18 点才对应 UTC 的 2、6、10 点。对有夏令时的地区,这种固定换算不能全年使用。

挂载宿主 /etc/localtime 到业务 Pod、在容器安装 tzdata,改变的是业务进程显示或解释时间的方式。它们可以是应用需要的配置,但不会把 CronJob 控制器变成相同时区。云服务器所在区域也不能替代实际控制器时区的检查。

修改后看下一次计划,不重复补跑

变更前保存资源和最近执行记录,确认没有人工补跑任务与计划任务同时处理同一份数据。通过项目原有发布入口只改需要的字段,保留并发策略、截止时间、模板与权限。

更新 CronJob 影响随后创建的 Job,已经运行的 Job 和 Pod 不会因此更换配置。至少观察下一次目标时刻,核对计划、Job 创建、Pod 完成和业务产物,而不是只在 Pod 中再运行一次 date。

CronJob 不保证业务严格只执行一次;时间设置正确后仍需保留幂等或去重机制。若要回退,恢复原计划与时区字段,并检查变更期间已经创建的任务。配置回退不会取消已开始的 Job,也不会撤销已提交的报表或业务写入。