1. 简介

在 Kubernetes 中,CronJob 是一种用于创建定时任务的资源对象。它允许我们在集群中预定和运行定期的作业,类似于 Linux 系统中的 cron 任务。

使用 CronJob 资源可以很容易地在 Kubernetes 上创建定时任务,无需依赖外部工具或服务。以下是 CronJob 的一些主要特点和应用:

  • 定时调度:CronJob 允许您基于 Cron 表达式来定义任务的调度规则,比如每天凌晨执行、每个星期五执行等。

  • 作业管理:CronJob 创建的任务会生成对应的 Job 资源,并在指定的时间执行任务。如果任务成功完成,则 Job 会被标记为完成;如果任务失败,则 Job 会保留失败的状态,并且根据配置的重试策略进行重试。

  • 并行处理:CronJob 允许您配置并发性,即同时执行的任务数量。这可以帮助您控制资源的使用情况,避免过多的任务同时运行导致资源耗尽。

  • 灵活的配置:CronJob 支持很多配置选项,例如定义任务的容器镜像、环境变量、命令参数等,使得定时任务的执行更加灵活。

2. Linux 上的 CronJob 定时任务

在 Linux 上,CronJob 是一种用于定时执行任务的工具,它可以让您在指定的时间间隔内运行命令或脚本。

Cron 表达式:

# ┌───────────── 分钟 (0 - 59)
# │ ┌───────────── 小时 (0 - 23)
# │ │ ┌───────────── 月的某天 (1 - 31)
# │ │ │ ┌───────────── 月份 (1 - 12)
# │ │ │ │ ┌───────────── 周的某天 (0 - 6)(周日到周一;在某些系统上,7 也是星期日)
# │ │ │ │ │                          或者是 sun,mon,tue,web,thu,fri,sat
# │ │ │ │ │
# │ │ │ │ │
# * * * * *

下面是在 Linux 上使用 CronJob 的一般步骤:

  • 编辑 Cron 表:打开终端,并使用以下命令编辑 Cron 表。
crontab -e

如果是第一次编辑 Cron 表,系统会提示您选择默认的编辑器。

  • 添加定时任务:在 Cron 表中,每行表示一个定时任务。每行包含六个字段,分别表示分钟、小时、日期、月份、星期和要执行的命令。您可以根据需要调整这些参数。
    例如,要在每天的凌晨 2 点运行 /path/to/command 命令,可以在 Cron 表中添加以下内容:
0 2 * * * /path/to/command

这表示每天的第 0 分钟、第 2 小时(凌晨 2 点)执行 /path/to/command 命令。

  • 保存 Cron 表:完成编辑后,请保存并关闭 Cron 表。编辑器会自动将新的 Cron 表写入系统。

  • 验证 Cron 任务:可以使用以下命令查看当前用户的 Cron 表内容。

crontab -l

这将显示当前用户的所有定时任务。

  • 管理 Cron 任务:通过编辑 Cron 表,您可以添加、修改或删除定时任务。当您需要对定时任务进行更改时,请使用 crontab -e 命令再次编辑 Cron 表。

另外,还有一些其他的 CronJob 使用技巧:

可以使用 * 通配符表示任意值,例如 * * * * * 表示每分钟都运行。
您可以使用逗号分隔的值来指定多个值,例如 0,15,30,45 * * * * 表示每小时的第 0、15、30 和 45 分钟运行。
可以使用连字符指定一个范围,例如 0 9-17 * * 1-5 表示在周一至周五的上午 9 点到下午 5 点之间的每个整点运行。

请注意,CronJob 的精度是分钟级别的,并且会受到系统时间的影响。因此,确保系统时间准确无误。

看了下我这里的定时任务:

[root@docker-54 config]# crontab -l
0-59/10 * * * * /usr/sbin/ntpdate us.pool.ntp.org | logger -t NTP
[root@docker-54 config]# 

这个定时任务的含义是每隔10分钟执行一次 /usr/sbin/ntpdate us.pool.ntp.org 命令,并将命令的输出通过管道传递给 logger -t NTP

让我来解释一下每个部分的含义:

  • 0-59/10:这表示分钟字段,表示每隔10分钟执行一次任务。范围是从0到59,斜杠后面的数字表示步长,也就是间隔。因此,0-59/10 表示每隔10分钟执行一次任务。

  • *:这是通配符,表示“每”。

  • *:这是通配符,表示不限制。

  • *:这是通配符,表示不限制。

  • /usr/sbin/ntpdate us.pool.ntp.org:这是要执行的命令,它会使用 NTP 协议从 us.pool.ntp.org 获取时间并进行同步。

  • |:这是管道符号,用于将命令的输出传递给下一个命令。

  • logger -t NTP:这是将命令的输出通过 logger 工具记录到系统日志中,标记为 NTP。

因此,这个定时任务的含义是每隔10分钟使用 NTP 协议从 us.pool.ntp.org 获取时间并进行同步,同时将命令的输出记录到系统日志中,以便日后查看或跟踪时间同步的情况。

3. 创建 K8s 的 CronJob

新建配置文件:cron-job-pd.yaml

apiVersion: batch/v1
kind: CronJob # 定时任务
metadata:
  name: cron-job-test # 定时任务名字
spec:
  concurrencyPolicy: Allow # 并发调度策略:Allow 允许并发调度,Forbid:不允许并发执行,Replace:如果之前的任务还没执行完,就直接执行新的,放弃上一个任务
  failedJobsHistoryLimit: 1 # 保留多少个失败的任务
  successfulJobsHistoryLimit: 3 # 保留多少个成功的任务
  suspend: false # 是否挂起任务,若为 true 则该任务不会执行
#  startingDeadlineSeconds: 30 # 间隔多长时间检测失败的任务并重新执行,时间不能小于 10
  schedule: "* * * * *" # 调度策略
  jobTemplate:
    spec:
      template:
        spec:
          containers:
          - name: busybox
            image: busybox:1.28
            imagePullPolicy: IfNotPresent
            command:
            - /bin/sh
            - -c
            - date; echo Hello from the Kubernetes cluster
          restartPolicy: OnFailure

这里使用 busybox镜像创建一个容器,每分钟执行一次 date; echo Hello from the Kubernetes cluster的命令。

[root@docker-54 jobs]# kubectl apply -f cron-job-pd.yaml 
cronjob.batch/cron-job-test created
[root@docker-54 jobs]# 
[root@docker-54 jobs]# kubectl get cronjob
NAME            SCHEDULE    SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cron-job-test   * * * * *   False     0        <none>          5s
[root@docker-54 jobs]#
[root@docker-54 jobs]# kubectl get cj
NAME            SCHEDULE    SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cron-job-test   * * * * *   False     0        <none>          36s
[root@docker-54 jobs]# 

这里显示LAST SCHEDULE为 none 表示最后一次调度记录不存在,证明还没有执行过。

[root@docker-54 jobs]# kubectl describe cj cron-job-test
Name:                          cron-job-test
Namespace:                     default
Labels:                        <none>
Annotations:                   <none>
Schedule:                      * * * * *
Concurrency Policy:            Allow
Suspend:                       False
Successful Job History Limit:  3
Failed Job History Limit:      1
Starting Deadline Seconds:     <unset>
Selector:                      <unset>
Parallelism:                   <unset>
Completions:                   <unset>
Pod Template:
  Labels:  <none>
  Containers:
   busybox:
    Image:      busybox:1.28
    Port:       <none>
    Host Port:  <none>
    Command:
      /bin/sh
      -c
      date; echo Hello from the Kubernetes cluster
    Environment:     <none>
    Mounts:          <none>
  Volumes:           <none>
Last Schedule Time:  Sun, 26 Nov 2023 22:35:00 +0800
Active Jobs:         cron-job-test-28350155
Events:
  Type    Reason            Age   From                Message
  ----    ------            ----  ----                -------
  Normal  SuccessfulCreate  57s   cronjob-controller  Created job cron-job-test-28350155
[root@docker-54 jobs]# 

可以下这个任务的具体信息。

接着再看下状态:

[root@docker-54 jobs]# kubectl get cj
NAME            SCHEDULE    SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cron-job-test   * * * * *   False     0        32s             3m30s
[root@docker-54 jobs]# 

可以看到已经距离上次调度已经过了 32s 了。

另外看下执行记录:

[root@docker-54 jobs]# kubectl get po | grep cron
cron-job-test-28350156--1-xn5xf   0/1     Completed   0               2m46s
cron-job-test-28350157--1-9mfwx   0/1     Completed   0               106s
cron-job-test-28350158--1-75v5k   0/1     Completed   0               46s
[root@docker-54 jobs]# 
[root@docker-54 jobs]# kubectl logs -f cron-job-test-28350158--1-75v5k
Sun Nov 26 14:38:01 UTC 2023
Hello from the Kubernetes cluster
[root@docker-54 jobs]# 

可以看到这些执行任务,并且是执行成功的状态。

在我们实际是用的过程中,也是这样,只是把我们的脚本改成自定义的实现就好了。

4. 删除 k8s 的 CronJob

接着我们来删除这个 CronJob:

[root@docker-54 jobs]# kubectl get cj
NAME            SCHEDULE    SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cron-job-test   * * * * *   False     0        11s             7m9s
[root@docker-54 jobs]# 
[root@docker-54 jobs]# kubectl delete cj cron-job-test
cronjob.batch "cron-job-test" deleted
[root@docker-54 jobs]# 
[root@docker-54 jobs]# kubectl get cj
No resources found in default namespace.
[root@docker-54 jobs]# 
[root@docker-54 jobs]# kubectl get po | grep cron
[root@docker-54 jobs]# 

可以看到,在我删除了CronJob 之后,对应的 Pod 记录也随之删除了。

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐