蒙国造博客

Docker cron定时任务

Docker在部署WEB环境时非常好用,一键即可完整部署,还不受限于具体的主机系统。

不过在使用cron定时,主机运行好好的,到了docker容器中却遇到各式各样的问题。

到底如何在容器中启用cron?

在主机和在容器中使用cron,那种更好?

这里我们列出集中用于定时的方案:

  1. 使用主机的cron实现定时任务
  2. 创建一个新容器专门执行定时任务
  3. 在原有容器上安装cron,里面运行2个进程

注意,我们这里所说的cron,包括传统的 cron 工具,或者其他的时间服务程序,它们功能是一样的。

方式1:最佳

我觉得最佳的方式应该是方式1,因为它最为简单。

比如,我在使用 Docker 搭建的一键 LNMP 环境(http://garymeng.com/2120.html)中,

会定时执行 Nginx 容器中的Certbo命令,以更新 HTTPS/SSL 证书的:

certbot renew

如果在主机中执行(dnmp_nginx_1是容器的名称):

docker exec -it dnmp_nginx_1 certbot renew

那在主机中的crontab -e中就可以:

0 2 * */2 * docker exec dnmp_nginx_1 certbot renew     # 每隔两个月的凌晨2点执行更新

注意:这里docker命令不需要加-it,因为加-it就要开启了一个终端,而计划任务是无法进入任何终端。(感谢小陈留言指正)

这就实现了主机通过docker命令定时执行容器内命令。

如果定时失败,可以开启cron日志看问题所在,方法请看本文末。

方式2

如果由于某种原因,不能使用方式1,那就退而求其次,使用方式2

方式2有一些现成的方案可以使用:https://hub.docker.com/r/willfarrell/crontab

因为这种方式略重,而且必须要同步cron脚本,

方式3

这里我们不讨论选项3,因为从docker的原则上来看,选项3本身就不是个好的方式

开启cron日志

如果定时失败,可以打开cron日志,方法:

sudo vim /etc/rsyslog.d/50-default.conf

将cron前面的注释符去掉:

cron.*              /var/log/cron.log

重启rsyslog

sudo service rsyslog restart

过段时间再查看日志:

tail -f /var/log/cron.log

 

参考资料:

  1. Docker Tip #40: Running Cron Jobs on the Host vs. in a Container
  2. How to run a cron job inside a docker container?
退出移动版