我试图在调用shell脚本的docker容器内运行cronjob。
昨天我一直在网上搜索,堆栈溢出,但我真的找不到一个有效的解决方案。 我该怎么做呢?
我试图在调用shell脚本的docker容器内运行cronjob。
昨天我一直在网上搜索,堆栈溢出,但我真的找不到一个有效的解决方案。 我该怎么做呢?
当前回答
VonC的回答相当彻底。此外,我想补充一件对我有帮助的事情。如果您只想运行一个cron作业而不跟踪文件,那么您可能会想从cron命令中删除&& tail -f /var/log/cron.log。
然而,这将导致Docker容器在运行后不久退出,因为当cron命令完成时,Docker认为上一个命令已经退出,因此杀死了容器。这可以通过在前台通过cron -f运行cron来避免。
其他回答
虽然这旨在通过Docker的exec接口在容器中运行进程的旁边运行作业,但您可能会感兴趣。
我已经编写了一个守护进程,用于观察容器并调度在其元数据中定义的作业。例子:
version: '2'
services:
wordpress:
image: wordpress
mysql:
image: mariadb
volumes:
- ./database_dumps:/dumps
labels:
deck-chores.dump.command: sh -c "mysqldump --all-databases > /dumps/dump-$$(date -Idate)"
deck-chores.dump.interval: daily
“经典”,cron一样的配置也是可能的。
这是文档,这是图像存储库。
我决定使用busybox,因为它是最小的图像之一。
crond在前台(-f)执行,日志发送到stderr (-d),我没有选择更改日志级别。 Crontab文件拷贝到默认路径:/var/spool/ Crontab
FROM busybox:1.33.1
# Usage: crond [-fbS] [-l N] [-d N] [-L LOGFILE] [-c DIR]
#
# -f Foreground
# -b Background (default)
# -S Log to syslog (default)
# -l N Set log level. Most verbose 0, default 8
# -d N Set log level, log to stderr
# -L FILE Log to FILE
# -c DIR Cron dir. Default:/var/spool/cron/crontabs
COPY crontab /var/spool/cron/crontabs/root
CMD [ "crond", "-f", "-d" ]
但是任务的输出显然不能在docker日志中看到。
不幸的是,上面的答案都不适合我,尽管所有的答案都指向解决方案,并最终指向我的解决方案,如果它对某人有帮助,这里是一个片段。谢谢
这个问题可以用bash文件解决,由于Docker的分层架构,cron服务不会通过RUN/CMD/ENTRYPOINT命令启动。
只需添加一个bash文件,该文件将启动cron和其他服务(如果需要)
DockerFile
FROM gradle:6.5.1-jdk11 AS build
# apt
RUN apt-get update
RUN apt-get -y install cron
# Setup cron to run every minute to print (you can add/update your cron here)
RUN touch /var/log/cron-1.log
RUN (crontab -l ; echo "* * * * * echo testing cron.... >> /var/log/cron-1.log 2>&1") | crontab
# entrypoint.sh
RUN chmod +x entrypoint.sh
CMD ["bash","entrypoint.sh"]
entrypoint.sh
#!/bin/sh
service cron start & tail -f /var/log/cron-2.log
如果任何其他服务也需要与cron一起运行,那么在同一个命令中添加&,例如:/opt/wildfly/bin/standalone.sh & service cron start & tail -f /var/log/cron-2.log
一旦你进入docker容器,你可以看到测试cron....将每分钟打印在文件:/var/log/cron-1.log
但是,如果cron死亡,容器将继续运行。
在生产环境中,公认的答案可能是危险的。
在docker中,你应该每个容器只执行一个进程,因为如果你不这样做,fork和后台进程就不会被监控,可能会在你不知道的情况下停止。
当你使用CMD cron && tail -f /var/log/cron.log时,cron进程基本上会分叉,以便在后台执行cron,主进程退出,让你在前台执行tailf。后台cron进程可能会停止或失败,但你不会注意到,你的容器仍然会默默地运行,你的编排工具也不会重新启动它。
你可以通过直接将cron的命令输出重定向到分别位于/proc/1/fd/1和/proc/1/fd/2的docker stdout和stderr中来避免这样的事情
使用基本的shell重定向,你可能想做这样的事情:
* * * * * root echo hello > /proc/1/fd/1 2>/proc/1/fd/2
你的CMD将是:CMD ["cron", "-f"]
但是:如果你想以非根用户的身份运行任务,这就行不通了。
显然,可以在容器中(在根用户下)与其他进程一起运行cron,使用Dockerfile中的ENTRYPOINT语句和start.sh脚本,其中包括行进程cron start。更多信息请点击这里
#!/bin/bash
# copy environment variables for local use
env >> etc/environment
# start cron service
service cron start
# start other service
service other start
#...