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 容器内运行的主要内容,如果未能解决你的问题,请参考以下文章
sh [打开#Ubuntu上的#minimize on dock选项]