如何在 docker 容器中运行 cron 作业
Posted
技术标签:
【中文标题】如何在 docker 容器中运行 cron 作业【英文标题】:How to run a cron job inside a docker container 【发布时间】:2016-08-29 04:14:50 【问题描述】:我尝试在 docker 容器中运行 cron 作业,但对我没有任何作用。
我的容器只有 cron.daily
和 cron.weekly
文件。crontab,cron.d,cron.hourly
在我的容器中不存在。crontab -e
也不起作用。
我的容器使用/bin/bash
运行。
【问题讨论】:
【参考方案1】:这是我运行我的一个 cron 容器的方法。
Dockerfile:
FROM alpine:3.3
ADD crontab.txt /crontab.txt
ADD script.sh /script.sh
COPY entry.sh /entry.sh
RUN chmod 755 /script.sh /entry.sh
RUN /usr/bin/crontab /crontab.txt
CMD ["/entry.sh"]
crontab.txt
*/30 * * * * /script.sh >> /var/log/script.log
entry.sh
#!/bin/sh
# start cron
/usr/sbin/crond -f -l 8
script.sh
#!/bin/sh
# code goes here.
echo "This is a script, run by cron!"
像这样构建
docker build -t mycron .
这样跑
docker run -d mycron
添加您自己的脚本并编辑 crontab.txt,然后构建映像并运行。由于是基于alpine,所以图片超级小。
【讨论】:
这很棒。我遇到的一个问题是,在 docker run ... 我无法使用 ctrl-c 停止容器运行?即使在我关闭终端之后,当我执行 docker ps 时,我也可以看到容器仍在运行。有人有同样的问题吗? 请在答案中添加RUN apk add --update apk-cron && rm -rf /var/cache/apk/*
以获取完整示例。列出的将 cron 添加到 alpine 的方法有很多,而这一种方法适用于您的示例。
嗨,为什么有 2 个 ADD 和 1 个 COPY?,根据我读到的内容,3 COPY 或 3 ADD 可以正常工作(在这种情况下)。我说的对吗?
crond -f -l 8
, 8 是什么意思?据 man 说,日志级别是大写的L
。
我没有看到 crond 默认在容器中运行。我必须执行并运行 crond,这实际上触发了 cron 作业。我在这里缺少什么吗?【参考方案2】:
crond 与 Alpine 上的 tiny 配合得很好
RUN apk add --no-cache tini
ENTRYPOINT ["/sbin/tini", "--"]
CMD ["/usr/sbin/crond", "-f"]
但不应作为容器主进程 (PID 1) 运行,因为僵尸收割问题和信号处理问题。详情请参阅this Docker PR 和this blog post。
【讨论】:
为什么不应该作为PID1运行?【参考方案3】:Here is good explanation of cron problems inside docker container:
Docker 文件示例:
FROM alpine
# Copy script which should be run
COPY ./myawesomescript /usr/local/bin/myawesomescript
# Run the cron every minute
RUN echo '* * * * * /usr/local/bin/myawesomescript' > /etc/crontabs/root
CMD ['crond', '-l 2', '-f']
【讨论】:
就我而言,这种方法行不通。我也尝试了一些变体,似乎在最终容器中,对/etc/crontabs/root
所做的更改不存在。【参考方案4】:
@ken-cochrane 的解决方案可能是最好的,但是,还有一种方法可以做到这一点,而无需创建额外的文件。
无需额外文件即可:
要走的路是在 entrypoint.sh
文件中设置 cron。
Dockerfile
...
# Your Dockerfile above
COPY entrypoint.sh /
RUN chmod +x /entrypoint.sh
ENTRYPOINT ["/entrypoint.sh"]
entrypoint.sh
echo "* * * * * echo 'I love running my crons'" >> /etc/crontabs/root
crond -l 2 -f > /dev/stdout 2> /dev/stderr &
# You can put the rest of your entrypoint.sh below this line
...
【讨论】:
以上是关于如何在 docker 容器中运行 cron 作业的主要内容,如果未能解决你的问题,请参考以下文章
在我在docker容器中重新保存cron文件之前,Cron作业不起作用
如何使用Docker将NodeJS应用程序与cron作业进行容器化?