Docker的Cron容器 - 它们实际上如何工作?

时间:2015-11-21 18:28:44

标签: cron docker

我已经使用docker几个月了,我正在开发各种不同的服务器映像。一个一致的问题是许多服务器需要运行cron作业。网上有很多讨论(包括Stackoverflow),但我并不完全理解它的机制。

目前,我正在使用主机的cron和docker exec进入每个容器来运行脚本。我创建了一个关于脚本名称和位置的约定;我的所有容器都有相同的脚本。这样可以避免使用主机的cron,具体取决于容器。

基本上,每分钟一次,主持人的cron会这样做:

for each container
   docker exec -it <containername> /cronscript/minute-script

这样可行,但会使容器依赖主机。

我想要做的是创建一个cron容器,在每个其他容器中启动一个脚本 - 但我不知道等同于#34; docker exec&#34;从一个容器到另一个容器。

我现在遇到的具体情况是在MySQL容器中运行备份,并且运行cron作业Moodle需要每分钟运行一次。最终,我还需要通过cron做更多的事情。 Moodle使用命令行PHP脚本。

什么是&#34;适当的&#34; dockerized方法从另一个容器中的一个容器启动脚本?

更新:也许提及我的具体用例会有所帮助,但随着时间的推移,会有更多用例。

目前,cron需要执行以下操作:

  • 从MySQL执行数据库转储。我可以通过来自cron容器的mysqldump TCP链接来做到这一点;这里的缺点是我无法将备份用户限制为主机127.0.0.1。我也许可以通过卷以某种方式将MySQL套接字导入到cron容器中。
  • 对Moodle安装执行定期维护。 Moodle包含一个运行所有维护任务的php命令行脚本。这对我来说很重要。我可以可能通过一个卷运行这个脚本,但是Moodle并没有考虑到这种情况,我不排除竞争条件。另外,我不希望我的moodle安装在卷中,因为它使得更容易更新容器(请记住,在Docker中,当您使用新映像更新容器时,卷不会重新初始化。)
  • 未来:对我的许多其他服务器执行例行维护,例如清理电子邮件队列等。

1 个答案:

答案 0 :(得分:8)

我的解决方案是:

  • 在容器内安装crond
  • 安装您的软件
  • 将cron作为守护进程运行
  • 运行你的软件

我的Dockerfile

的一部分
FROM debian:jessie

RUN mkdir -p /usr/src/app
WORKDIR /usr/src/app
COPY .crontab /usr/src/app

# Set timezone
RUN echo "Europe/Warsaw" > /etc/timezone \
    && dpkg-reconfigure --frontend noninteractive tzdata

# Cron, mail
RUN set -x \
    && apt-get update \
    && apt-get install -y cron rsyslog mailutils --no-install-recommends \
    && rm -rf /var/lib/apt/lists/*

CMD rsyslogd && env > /tmp/crontab && cat .crontab >> /tmp/crontab && crontab /tmp/crontab && cron -f

描述

  1. 设置时区,因为cron需要这个才能正常运行任务
  2. 安装cron软件包 - 包含cron守护程序的软件包
  3. 安装rsyslog包以记录cron任务输出
  4. 如果您要从cron任务发送电子邮件
  5. ,请安装mailutils
  6. 运行rsyslogd
  7. 将ENV变量复制到tmp文件,因为cron以最少的ENV运行任务而你的任务可能需要访问容器ENV变量
  8. 将您的.crontab文件(包含您的任务)附加到tmp文件
  9. 从tmp文件
  10. 设置root crontab
  11. 运行cron守护程序
  12. 我在容器中使用它并且工作得非常好。

    一过程每次容器

    如果你喜欢这个范例,那么每个cron任务一个Dockerfile。 e.g。

    • Dockerfile - 主程序
    • Dockerfile_cron_task_1 - cron task 1
    • Dockerfile_cron_task_1 - cron task 2

    并构建所有容器:

    docker build -f Dockerfile_cron_task_1 ...