1. 引言

在实际生产环境中,我们经常需要定时执行一些任务,比如清理日志、备份数据、生成报表等。Kubernetes 提供了对定时任务(CronJob)的原生支持,让我们可以轻松地在集群中部署和管理这些周期性任务。

本文将介绍 Kubernetes 中 CronJob 的使用方式,包括定义、调度语法、管理命令以及时区设置等。


2. 什么是 CronJob?

CronJob 是指在指定时间周期性执行的任务。在类 Unix 系统中,这种机制通常通过 cron 工具实现。

Kubernetes 从 v1.21 开始,正式支持 CronJob 资源类型。我们可以使用标准的 cron 表达式来定义任务执行的频率,比如:

  • 每天晚上 10:00 执行
  • 每月第一天早上 6:00 执行
  • 每周二早上 7:00 执行
  • 每天 8:00 和 18:00 各执行一次

典型的使用场景包括:

  • 清理磁盘空间
  • 备份文件或目录
  • 生成监控指标或报表

3. 在 Kubernetes 中定义 CronJob

3.1. 定义格式

CronJob 的定义方式与 Deployment、DaemonSet 等资源类似,都是通过 YAML 文件来描述。以下是一个完整的 CronJob 示例:

apiVersion: batch/v1
kind: CronJob
metadata:
  name: cleanup-job
spec:
  schedule: "0 2 * * *"
  concurrencyPolicy: Allow
  suspend: false
  successfulJobsHistoryLimit: 10
  failedJobsHistoryLimit: 3
  startingDeadlineSeconds: 60
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: cleanup-job
            image: busybox:1.28
            imagePullPolicy: IfNotPresent
            command:
            - /bin/rm
            - -f
            - /tmp/*
          restartPolicy: OnFailure

这段配置定义了一个每天凌晨 2 点执行的任务,用于清理 /tmp/ 目录下的文件。

说明一下几个关键字段:

字段 说明
schedule ✅ 必填字段,定义任务执行时间,使用标准 cron 表达式
concurrencyPolicy 可选,控制并发策略,支持:Allow(允许多个同时运行)、Forbid(禁止并发)、Replace(新任务替换旧任务)
suspend 可选,默认 false,设为 true 时暂停任务
successfulJobsHistoryLimit 可选,默认 3,保留多少个成功任务的历史记录
failedJobsHistoryLimit 可选,默认 1,保留多少个失败任务的历史记录
startingDeadlineSeconds 可选,默认不限制,任务错过调度时间后多久仍允许执行

⚠️ 注意:jobTemplate 的结构与 Job、Deployment 非常相似,本质上就是 Job 的模板。


3.2. 管理 CronJob

假设我们将上面的配置保存为 cronjob.yaml,可以通过以下命令进行管理:

# 创建 CronJob
kubectl create -f cronjob.yaml

# 查看当前所有 CronJob
kubectl get cronjob
NAME          SCHEDULE    SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cleanup-job   0 2 * * *   False     0        15s             32s

# 查看 CronJob 详细信息
kubectl describe cronjob cleanup-job

# 删除 CronJob
kubectl delete cronjob cleanup-job

输出信息中会显示最后一次执行时间、任务历史、以及是否正在运行等信息。


3.3. Cron 表达式语法

Cron 表达式由 5 个字段组成,顺序如下:

分钟 小时 日 月 星期几

每个字段可以是数字、星号(*)或特殊符号(如 /, ,, -)。以下是一些常用示例:

表达式 含义
0 8 * * * 每天早上 8:00 执行
0 17 * * 2 每周二下午 5:00 执行
30 0,2,4,6,8,10,12,14,16,18,20,22 15 * * 每月 15 号每隔两小时 30 分执行
30 0-23/2 15 * * ✅ 更简洁的写法,效果同上

3.4. 特殊表达式

除了标准格式,Kubernetes 也支持一些简写形式:

表达式 含义
@yearly / @annually 每年 1 月 1 日午夜执行
@monthly 每月 1 日午夜执行
@weekly 每周日午夜执行
@daily / @midnight 每天午夜执行
@hourly 每小时开始时执行

3.5. 时区设置

默认情况下,Kubernetes CronJob 使用的是 kube-controller-manager 所在节点的系统时区。

从 Kubernetes v1.24 开始,可以显式指定时区:

spec:
  schedule: "0 2 * * *"
  timeZone: "GMT"

✅ 时区可以是任何有效的 IANA 时区数据库 名称,比如:

  • Asia/Shanghai
  • America/New_York
  • Europe/London

⚠️ 注意:该功能目前仍处于实验阶段,需要启用 CronJobTimeZone 特性开关才能使用。


4. 小结

CronJob 是 Kubernetes 中周期性执行任务的标准方式

本文我们介绍了:

  • 如何定义 CronJob(使用 YAML)
  • 如何管理 CronJob 生命周期(kubectl 命令)
  • 如何使用 cron 表达式定义任务调度频率
  • 如何设置时区(v1.24+)

如果你正在寻找一个在 Kubernetes 上运行定时任务的方案,CronJob 是一个非常合适的选择。合理使用并发策略和历史记录限制,可以避免资源浪费和任务堆积。


原始标题:Running Cron Jobs in Kubernetes