K8S – 如何部署crontab

应用迁移K8S,不可忽略的就是crontab怎么迁移上去。

传统linux crontab可以满足下面的需求:

  • 避免任务并发执行(通过文件锁可以搞定)
  • 磁盘上可能写入有状态的文件

那么K8S呢?下面介绍2个方案。

cronjob方案

K8S支持cronjob资源类型,它可以满足:

  • 支持并发控制,前一个任务没跑完,这次会跳过

但是无法满足有状态的东西,因为POD执行完就退出了。

关于状态的问题,我们可以通过挂载volume解决,这个大家可以基于云平台或者自建的分布式存储来支持。

那么cronjob好不好用呢?首先我们明确,一个定时任务需要配置一个cronjob,如果定时任务数量特别多,那么就会遇到下面2个问题:

  • 发布应用的时候,需要循环推送大量的cronjob YAML到K8S,很容易出现异常。
  • 资源分配需要具体到每个cronjob(当然不限制POD资源也是可以的),这非常难于评估。
  • cronjob执行失败的具体原因很难得知,因为POD跑完就退了,留不下任何痕迹。

上述3个问题是我放弃cronjob的主要原因。

deployment方案

该方案就是基于deployment来执行定时任务。

我们传统linux crontab都是放在虚拟机或者物理机上跑,迁移到deployment的方式就相当于启动一个常驻的POD,里面还是基于crontab调度若干定时任务,区别并不大,但带来的好处就很明显了:

  • 多条crontab可以放到同一个POD内执行,发布的时候只需要推送一次deployment YAML。
  • 资源分配可以针对一批crontab进行整体评估,原先虚拟机/物理机用多少就可以分配多少。
  • 因为deployment拉起的POD是常驻的,所以crontab执行留下的输出可以登录到POD查看。

相比于cronjob方案,优势非常明显。

为了在发布平台里实现自动化的定时任务deployment发布,我们需要一点巧妙的设计。

将cron表达式放入POD内

为了执行定时任务,我们需要把cron表达式放到POD里面,才能交给linux crontab调度。

那么cron表达式如何放入POD呢?

  • 也许可以把cron表达式配置到POD的env中
  • 也许可以配置一个configmap保存cron表达式,再通过volume挂载到POD内。

我选择的是后一种。

在docker环境下的pid=1进程不是systemd,所以crond守护进程默认是没有拉起的。

我们需要在POD的启动命令中主动加载crontab文件,并拉起crond进程:

其中dot_cron文件中记录的是cron表达式,我在deployment YAML中配置了configmap volume挂载:

你必须付费加入我的知识星球,为有效知识付费是对作者最好的回报。

二维码见下方 或者 右侧边栏。