2.7.4 CronJob调度时区

2.7.4.1 CronJob调度时区介绍

如果采用具体的时间调度任务,需要注意调度的时区问题。

如果 CronJob 未标注调度时区,Kubernetes 会以 kube-controller-manager 组件的时区进行调度,如果该组件运行的时区和本地时区不一样,会导致无法按照规定时间进行调度。

比如创建一个每天凌晨一点开始执行的任务,此时配置的调度表达式可能如下:

schedule: '00 01 * * *'

但是如果未指定时区,当 kube-controller-manager 组件的时区和本地时区有差别时,可能会在每天的九点进行调度(本地时区为 Shanghai 时区,kube-controller-manager 采用 UTC 时间)

在 Kubernetes 1.25 版本时,CronJob 增加了.spec.timeZone 的字段用于配置 CronJob 的调度时区,在 1.27 版本达到稳定,可以直接使用。

1.25版本之前(不包含1.25版本)需要自己计算,将本机的CST时区时间调整为UTC时区时区

# CST时间
[root@k8s-master01 ~]# date 
2025年 03月 21日 星期五 16:17:08 CST

# UTC时间
[root@k8s-master01 ~]# date -u
2025年 03月 21日 星期五 08:17:11 UTC

1.25~1.27 版本(不包含1.27版本)之间需要打开 kube-apiserver 的featuregates 特性,比如:

--feature-gates=CronJobTimeZone=true

1.27版本及1.27版本以后配置时区只需要添加timeZone即可:

关键配置

  timeZone: "Asia/Shanghai"

完整配置文件示例

apiVersion: batch/v1
kind: CronJob
metadata:
  name: hello
spec:
  timeZone: "Asia/Shanghai"
  schedule: '*/1 * * * *'
  jobTemplate:
    metadata:
      name: hello
    spec:
      template:
        metadata:
        spec:
          containers:
          - command:
            - sh
            - -c
            - echo "Hello,Job"
            image: registry.cn-hangzhou.aliyuncs.com/abroad_images/busybox:1.28
            name: hello
            resources: {}
          restartPolicy: OnFailure

2.7.4.2 CronJob调度时区实践

说明:CronJob 是内置资源,由 kube-controller-manager 管理。

1、查看kube-controller-manager时区,观察到为UTC时区

# 查看kube-controller-manager的pod
[root@k8s-master01 ~]# kgp -A | grep manager
kube-system            kube-controller-manager-k8s-master01         1/1     Running   2 (8h ago)      7d7h

# 查看kube-controller-manager的日志信息,对比主机和kube-controller-manager时间,观察到kube-controller-manager-k8s-master01时区为UTC时区
[root@k8s-master01 ~]# date
2025年 03月 21日 星期五 16:37:51 CST

[root@k8s-master01 ~]# k logs -f -n kube-system  kube-controller-manager-k8s-master01 --tail 5
I0321 08:28:27.027944       1 job_controller.go:598] "enqueueing job" logger="job-controller" key="default/hello-29042426" delay="0s"
I0321 08:28:27.028012       1 job_controller.go:598] "enqueueing job" logger="job-controller" key="default/hello-29042427" delay="0s"
I0321 08:28:27.028135       1 job_controller.go:598] "enqueueing job" logger="job-controller" key="default/hello-29042424" delay="0s"
I0321 08:28:27.028174       1 job_controller.go:598] "enqueueing job" logger="job-controller" key="default/hello-29042425" delay="0s"
I0321 08:28:27.028255       1 job_controller.go:598] "enqueueing job" logger="job-controller" key="default/hello-29042428" delay="0s"

说明:这里之所以用查看日志的方式查看时间,是因为kube-controller-manager-k8s-master01这个pod无法使用sh或bash的形式进入执行date命令查看

2、实验环境为1.32.3版本,添加timeZone字段重新定义yaml文件

[root@k8s-master01 ~]# vim cj-timezone.yaml
apiVersion: batch/v1
kind: CronJob
metadata:
  name: hello
spec:
  timeZone: "Asia/Shanghai"
  schedule: '50 16 * * *'
  jobTemplate:
    metadata:
      name: hello
    spec:
      template:
        metadata:
        spec:
          containers:
          - command:
            - sh
            - -c
            - echo "Hello,Job"
            image: registry.cn-hangzhou.aliyuncs.com/abroad_images/busybox:1.28
            name: hello
            resources: {}
          restartPolicy: OnFailure

3、创建CronJob

[root@k8s-master01 ~]# kaf cj-timezone.yaml

4、查看创建情况

# 查看现在的时间
[root@k8s-master01 ~]# date
2025年 03月 21日 星期五 16:48:22 CST

# 查看cj
[root@k8s-master01 ~]# kg cj
NAME    SCHEDULE      TIMEZONE        SUSPEND   ACTIVE   LAST SCHEDULE   AGE
hello   50 16 * * *   Asia/Shanghai   False     0        <none>          105

# 等到16:50后查看job
[root@k8s-master01 ~]# kg job
NAME             STATUS     COMPLETIONS   DURATION   AGE
hello-29042450   Complete   1/1           3s         3s

# 等到16:50后查看pod
[root@k8s-master01 ~]# kgp
NAME                   READY   STATUS      RESTARTS   AGE
hello-29042450-svc75   0/1     Completed   0          8s

5、环境复原

[root@k8s-master01 ~]# k delete -f cj-timezone.yaml