如何在 docker 容器中运行 cron 作业?

新手上路,请多包涵

我正在尝试在调用 shell 脚本的 docker 容器中运行 cronjob。

昨天我一直在网上搜索和堆栈溢出,但我真的找不到有效的解决方案。

我怎样才能做到这一点?

原文由 C Heyer 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 916
2 个回答

您可以将 crontab 复制到映像中,以便从所述映像启动的容器运行作业。

请参阅 Julien Boulay 在他的 Ekito/docker-cron 中的“ 使用 Docker 运行 cron 作业”:

让我们创建一个名为“ hello-cron ”的新文件来描述我们的工作。

 # must be ended with a new line "LF" (Unix) and not "CRLF" (Windows)
* * * * * echo "Hello world" >> /var/log/cron.log 2>&1
# An empty line is required at the end of this file for a valid cron file.

如果您想知道什么是 2>&1, Ayman Hourieh 解释说

以下 Dockerfile 描述了构建映像的所有步骤

FROM ubuntu:latest
MAINTAINER docker@ekito.fr

RUN apt-get update && apt-get -y install cron

# Copy hello-cron file to the cron.d directory
COPY hello-cron /etc/cron.d/hello-cron

# Give execution rights on the cron job
RUN chmod 0644 /etc/cron.d/hello-cron

# Apply cron job
RUN crontab /etc/cron.d/hello-cron

# Create the log file to be able to run tail
RUN touch /var/log/cron.log

# Run the command on container startup
CMD cron && tail -f /var/log/cron.log

(请参阅 Gaafar评论我如何使 apt-get 安装噪音更小?

apt-get -y install -qq --force-yes cron 也可以工作)

正如 Nathan Lloyd评论 中指出的那样:

关于陷阱的快速说明:

如果您要添加脚本文件并告诉 cron 运行它,请记住

RUN chmod 0744 /the_script

如果你忘记了,Cron 会默默地失败


或者,确保您的工作本身直接重定向到 stdout/stderr 而不是日志文件,如 hugoShaka回答 中所述:

  * * * * * root echo hello > /proc/1/fd/1 2>/proc/1/fd/2

将最后 Dockerfile 行替换为

CMD ["cron", "-f"]

另请参阅(关于 cron -f ,即 cron “前景”)“ docker ubuntu cron -f 不工作


构建并运行它:

 sudo docker build --rm -t ekito/cron-example .
sudo docker run -t -i ekito/cron-example

请耐心等待 2 分钟,您的命令行应该会显示:

 Hello world
Hello world


埃里克 在评论中 补充道:

请注意,如果在映像构建期间创建了 tail 可能不会显示正确的文件。

如果是这种情况,您需要在容器运行时创建或触摸文件,以便 tail 获取正确的文件。

请参阅“ tail -f 末尾的 CMD 的输出未显示”。


Jason Kulatunga 的“ 在 Docker 中运行 Cron ”(2021 年 4 月)中查看更多信息,他 在下面评论

参见 Jason 的图片 AnalogJ/docker-cron 基于:

  • Dockerfile 安装 cronie / crond ,取决于分布。

  • 一个入口点初始化 /etc/environment 然后调用

  cron -f -l 2

原文由 VonC 发布,翻译遵循 CC BY-SA 4.0 许可协议

接受的答案 _在生产环境中可能是危险的_。

在 docker 中,每个容器应该只执行一个进程,因为如果不这样做,分叉并进入后台的进程不会受到监控,并且可能会在您不知情的情况下停止。

当你在后台使用 CMD cron && tail -f /var/log/cron.log cron进程基本上是fork以便在后台执行 cron ,主进程退出并让你在前台执行 tailf 。后台 cron 进程可能会停止或失败,您不会注意到,您的容器仍将静默运行,并且您的编排工具不会重新启动它。

You can avoid such a thing by redirecting directly the cron’s commands output into your stdout and stderr which are located respectively in /proc/1/fd/1 and /proc/1/fd/2

使用基本的 shell 重定向,您可能想要执行以下操作:

 * * * * * root echo hello > /proc/1/fd/1 2>/proc/1/fd/2

你的 CMD 将是: CMD ["cron", "-f"]

原文由 hugoShaka 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题