cron 作业未在 ubuntu 上的 docker 容器内运行

Posted

技术标签:

【中文标题】cron 作业未在 ubuntu 上的 docker 容器内运行【英文标题】:cron job not running inside docker container on ubuntu 【发布时间】:2015-12-28 15:11:44 【问题描述】:

我有一个简单的 Dockerfile 如下

FROM ubuntu:latest

ADD crontab /etc/cron.d/test-cron

RUN chmod a+x /etc/cron.d/test-cron
RUN touch /var/log/cron.log

CMD cron && tail -f /var/log/cron.log

crontab文件的内容很简单

* * * * * root echo "Hello world" >> /var/log/cron.log 2>&1
# empty line

当我在本地 OS X 机器上运行它时(运行 docker-machine),它运行良好(“Hello world”每分钟打​​印到日志文件中)。但是,当我尝试在 Ubuntu 机器上运行它时,cron 作业没有运行(空日志文件)。

这是我用来运行容器的命令

docker build -t crontest .
docker run --name cron crontest

我不确定为什么会这样。我想知道我的 Ubuntu 盒子是否有问题(时间设置错误?)。我试图重新启动那台机器没有效果。我目前确实在 Ubuntu 机器上运行了其他 docker 容器,它们运行良好。

任何关于我可以做些什么来调试/修复此问题的建议将不胜感激。

编辑:

进入容器 (docker exec -it cron /bin/bash) 后,我可以验证 cron 正在那里运行:

root@a2ad451af8d9:/# ps -ef | grep cron
root         1     0  0 20:15 ?        00:00:00 /bin/sh -c cron && tail -f /var/log/cron.log
root         6     1  0 20:15 ?        00:00:00 cron
root         7     1  0 20:15 ?        00:00:00 tail -f /var/log/cron.log
root        25    11  0 20:21 ?        00:00:00 grep --color=auto cron

【问题讨论】:

我投票结束这个问题,因为它属于 AskUbuntu。 @TinyGiant 我能理解你来自哪里,但我认为这仍然是一个有效的问题,因为它也涉及到 docker。 @TriNguyen 你有没有想过这个问题?我遇到了完全相同的问题,如果您找到解决方案,我希望避免冗长的日志调查! @DaveNovelli 不,不幸的是,我还没有弄清楚这一点:( 我在仔细查看日志后让它工作了。我必须解决两件事:1)我使用的是 Windows,并且我的 crontab 文件有 CRLF 而不是 LF 作为换行符。错误消息中的附加“^M”提示了我。 2)在我修复它之后,我有一个新的错误,表明一个错误的命令。我意识到,由于我使用的是用户 crontab 文件,因此我不需要命令开头的“root”。在那之后,它就像一个魅力。非常感谢@Dzamo 提供的 rsyslog 提示! 【参考方案1】:

使用apt-get install rsyslog 在容器内安装rsyslog 并使用命令rsyslogd 启动它,然后使用cron -L15 启动cron(最大日志记录)。然后观察容器内的文件/var/log/syslog 可以看到cron 守护进程自己的日志输出。它会告诉您解析 crontab 是否有问题,如果它已注册并正在尝试运行您的作业,它会在您的情况下每分钟记录一个类似于以下内容的条目。

CRON[16]: (root) CMD (echo "Hello world" >> /var/log/cron.log 2>&1)

【讨论】:

我在 docker 容器下遇到了同样的问题。您的解决方案对我有用,但我必须在 /var/log (touch /var/log/syslog) 下创建 syslog 文件并将其所有者更改为 syslog:adm (chown syslog:adm /var/log/syslog)。通过 cron 与 syslog 对话,我发现了这一点:/usr/sbin/cron[2990]: (root) INSECURE MODE (mode 0600 expected) (crontabs/root)。所以我必须设置正确的权限模式 0600(chmod 0600 /var/spool/cron/crontabs/root)。之后,一切正常。 我在 Docker 容器中也遇到了这个问题。安装rsyslog,启动它并运行cron -L15 神奇地使我的工作运行(我什至没有检查日志)。所以我的 cron 作业命令没有错误。【参考方案2】:

我遇到了类似的问题,特别是 Ubuntu 14.04。为了调试,我尝试在前台运行 cron,发现它在尝试运行计划作业时发出 System error 消息。

显然,这是--net=host 参数的一个已知问题(参考:https://github.com/moby/moby/issues/5899)。我尝试按照建议传递--pid=host,这样,cron 作业开始运行良好。

【讨论】:

【参考方案3】:

我有一个名为backup.sh 的备份脚本,我将它复制到/etc/cron.daily。 脚本调用不正确。

为了做到这一点,我不得不重命名为 backup 而没有 .sh

所以对我来说ls -l /etc/cron.daily 有以下输出:

root@0989a35b8f94:/# ls -l /etc/cron.daily
total 24
-rwxr-xr-x 1 root root 1474 Sep 13 16:47 apt-compat
-rwxrwxr-x 1 root root   45 Nov  9 11:18 dobackup
-rwxr-xr-x 1 root root 1597 Feb 22  2017 dpkg
-rwxr-xr-x 1 root root 4125 Mar  2  2016 exim4-base
-rwxr-xr-x 1 root root  249 May 17 11:59 passwd

为了测试/分析这一点,我使用了以下方法:

我查看了 crontab 文件 cat /etc/crontab,其中显示了每日 cronjobs 的以下行:

25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )

然后我将我的备份脚本隔离到一个专用文件夹中:

mkdir /etc/cron.test
mv /etc/cron.daily/dobackup /etc/cron.test

然后通过运行

test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.test)

并在另一个终端上使用ps auxf 向我显示作业现在正在运行。您还可以验证重命名为.sh 版本时它是否中断:

mv /etc/cron.test/dobackup /etc/cron.test/dobackup.sh
test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.test)

然后它立即存在,所以没有作业运行。

【讨论】:

【参考方案4】:

就我而言,当我 COPY 一个文件时,它创建了一个辅助硬链接(它可能是 Windows 的东西)。

我要做的是确保文件是在一个正在运行的容器中创建的。

FROM mysql:5.7
RUN apt-get update && apt-get install -y anacron
COPY crontab /tmp/crontab

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

# Run the command on container startup
CMD (cat /tmp/crontab > /etc/cron.d/hello-cron ) && cron && tail -f /var/log/cron.log

【讨论】:

【参考方案5】:

最近已在 debian 中修复:https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=726661 和 Ubuntu Wily (15.10)。

作为一种解决方法,您可以尝试评论模块 pam_loginuid.so 在 /etc/pam.d/cron 中并重新启动 cron(或 docker 容器)。

【讨论】:

以上是关于cron 作业未在 ubuntu 上的 docker 容器内运行的主要内容,如果未能解决你的问题,请参考以下文章

Cron 作业未在所有站点上激活

Ubuntu 上的 dotnet 运行时安装在哪里?

节点 cron 未在 EC2 上运行

sh [打开#Ubuntu上的#minimize on dock选项]

linux ubuntu /bin/sh 上的脚本错误:curl:找不到? [关闭]

如何为服务器上的 codeigniter 脚本设置 cron 作业