应用迁移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进程:
1 |
crontab /root/cronfiles/dot_cron && crond && while true; do sleep 1000; done |
其中dot_cron文件中记录的是cron表达式,我在deployment YAML中配置了configmap volume挂载:
1 2 3 4 5 6 7 8 9 |
volumeMounts: - name: dot-cron mountPath: "/root/cronfiles/" volumes: - configMap: name: xxxe-service-cron-1 name: dot-cron |
阅读后续内容?
你必须付费加入我的知识星球,为有效知识付费是对作者最好的回报。
二维码见下方 或者 右侧边栏。

1