Kubernetes的Cron任务

cronjob以如下的形式进行定义, 截取自官方文档

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
apiVersion: batch/v1beta1
kind: CronJob
metadata:
name: hello
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: busybox
args:
- /bin/sh
- -c
- date; echo Hello from the Kubernetes cluster
restartPolicy: OnFailure

我的需求

目前我是在一个PaaS平台中使用K8S, 对于定时任务的需求, 集中在以下几个方面:

功能需求:

  1. 创建定时任务
  2. 编辑定时任务(编辑时, 暂停任务, 编辑主要修改任务调度时间以及命令, 编辑后重新打开任务)
  3. 每次程序发新版本, 同步更新定时任务(旧任务仍然运行至结束)
  4. 删除定时任务

非功能需求:

  1. 同一时刻, 一个定时任务只能运行一份
  2. 严格禁止K8S停止正在运行的定时任务

本文随后将会就上面的需求提供方案, 如果读者与我的需求不一致, 建议仅仅参考此博客, 不要照搬.

需求处理

定时任务的创建, 删除

比较简单, 不进行介绍

定时任务的暂停与启动

各位读者可以试验, 如果使用kubectl delete, 正在运行的定时任务将会被强制终止, 不符合我们的需求, 所以delete不合要求.

官方文档中提供了suspend参数:

1
2
3
The .spec.suspend field is also optional. If it is set to true, all subsequent executions are suspended. This setting does not apply to already started executions. Defaults to false.

如果设置为true, 那么接下来的任务将会被暂停. 这项设置不影响已经开始的任务.

suspend是可以比较好的解决任务暂停这样的需求的, 修改时设suspend为true. 修改完成后设置为false.

suspend也有副作用, 如果你从true变更为false时, 也就是重新打开定时任务, 错过的任务会立刻执行(如果没有设置 starting deadline), K8S会马上调度先前错过的任务.

starting deadline的问题我会在之后对于源码阅读的博客中给出, 这里只介绍suspend参数.

限制只能运行一份

官方文档中, 有介绍Concurrency Policy, 如果你设置为Forbid, 那么每次将只会有一个Job在执行.

总结

这篇文章主要就K8S的定时任务做了简单的梳理. 但是在使用过程中, suspend参数又带来了另外的问题, 为此, 我阅读了CronJob的实现代码, 下一篇博客, 将会结合源码梳理CronJob的实现.