【发布时间】:2016-08-29 04:14:50
【问题描述】:
我尝试在 docker 容器中运行 cron 作业,但对我没有任何作用。
我的容器只有 cron.daily 和 cron.weekly 文件。crontab,cron.d,cron.hourly 在我的容器中不存在。crontab -e 也不起作用。
我的容器使用/bin/bash 运行。
【问题讨论】:
我尝试在 docker 容器中运行 cron 作业,但对我没有任何作用。
我的容器只有 cron.daily 和 cron.weekly 文件。crontab,cron.d,cron.hourly 在我的容器中不存在。crontab -e 也不起作用。
我的容器使用/bin/bash 运行。
【问题讨论】:
这是我运行我的一个 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,所以图片超级小。
【讨论】:
RUN apk add --update apk-cron && rm -rf /var/cache/apk/* 以获取完整示例。列出的将 cron 添加到 alpine 的方法有很多,而这一种方法适用于您的示例。
crond -f -l 8, 8 是什么意思?据 man 说,日志级别是大写的L。
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。
【讨论】:
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 所做的更改不存在。
@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
...
【讨论】: