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

docker的Cron容器-它们实际上是如何工作的?,cron,docker,Cron,Docker,我已经使用docker几个月了,现在正在处理各种不同的服务器映像。一个一致的问题是许多服务器需要运行cron作业。关于这一点,网上有很多讨论(包括Stackoverflow),但我并不完全理解它的机制 目前,我在每个容器中使用主机的cron和docker exec来运行脚本。我创建了一个关于脚本名称和位置的约定;我所有的容器都有相同的脚本。这避免了主机的cron依赖于容器 基本上,主机的cron每分钟执行一次: for each container docker exec -it <

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

目前,我在每个容器中使用主机的cron和docker exec来运行脚本。我创建了一个关于脚本名称和位置的约定;我所有的容器都有相同的脚本。这避免了主机的cron依赖于容器

基本上,主机的cron每分钟执行一次:

for each container
   docker exec -it <containername> /cronscript/minute-script
每个容器的

docker exec-it/cronscript/minute脚本
这是可行的,但使容器依赖于主机

我想做的是创建一个cron容器,在其他每个容器中启动一个脚本——但我不知道有一个等效于“docker exec”的容器可以从一个容器工作到另一个容器

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

从一个容器启动另一个容器中的脚本的“正确”停靠方式是什么?

更新:提及我的特定用例可能会有所帮助,尽管随着时间的推移会有更多的用例

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

  • 从MySQL执行数据库转储。我可以通过cron容器中的mysqldump TCP链接来实现这一点;这里的缺点是我不能将备份用户限制为主机127.0.0.1。我还可以通过卷将MySQL套接字欺骗到cron容器中
  • 对Moodle装置进行定期维护。Moodle包括一个运行所有维护任务的php命令行脚本。这对我来说是件大事。我可能可以在一个卷中运行这个脚本,但Moodle的设计并没有考虑到这种情况,我也不会排除比赛条件。另外,我不希望在卷中安装moodle,因为这会使更新容器变得更加困难(请记住,在Docker中,使用新映像更新容器时不会重新初始化卷)
  • 未来:在我的许多其他服务器上执行日常维护,例如清理电子邮件队列等
我的解决方案是:

  • 在容器内安装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
描述
  • 设置时区,因为cron需要它来正确运行任务
  • 安装
    cron
    package-带有cron守护程序的包
  • 安装
    rsyslog
    包以记录cron任务输出
  • 如果要从cron任务发送电子邮件,请安装
    mailutils
    package
  • 运行
    rsyslogd
  • 将环境变量复制到tmp文件,因为cron使用最小的环境运行任务,而您的任务可能需要访问容器环境变量
  • .crontab
    文件(以及任务)附加到tmp文件
  • 从tmp文件设置根crontab
  • 运行cron守护进程
  • 我把它用在我的容器里,效果很好

    每个容器一个进程 如果您喜欢这个范例,那么为每个cron任务创建一个
    Dockerfile
    。e、 g

    • Dockerfile
      -主程序
    • Dockerfile\u cron\u task\u 1
      -cron task 1
    • Dockerfile\u cron\u task\u 1
      -cron task 2
    并构建所有容器:

    docker build -f Dockerfile_cron_task_1 ...
    

    你们读过这个有趣的想法吗?我没想过要这么做。不过,它似乎也面临同样的问题;或者一个容器是否有向另一个容器发送信号的方法?另请参见并检查
    docker run
    的doc
    --link=[]添加到另一个容器的链接在这里不起作用,因为它只允许基于网络的通信。最终目标是在目标容器中启动一个脚本,让目标容器只运行它为之设计的一个进程(MySQL、Apache、Nginx)。网络通信需要另一个进程监听来自cron的通信。还是我忽略了什么?谢谢!我可以看到这个解决方案是如何工作的,但我打破了每个容器一个进程的范式。不过,我喜欢将所有内容都保存在同一个容器中,我可能会实际使用此解决方案;对于这个问题,似乎没有真正好的解决方案。我注意到您在答案中添加了(每个容器都有一个进程),它确实解决了关注点的分离问题,但最终,它仍然面临相同的问题,即从cron容器到主容器的通信的唯一选项是通过共享卷,或者通过链接。您的体系结构允许cron对主容器有更多的了解,因此它实际上可以解决至少80%的实际用例。