我想在Docker容器中运行一些cron作业,并将输出发送到stdout。How to run a cron job inside a docker container?
为了用一个简单的例子来尝试这个方法,我创建了一个演示crontab:
我的电子表格:
* * * * * date > /dev/stdout 2> /dev/stderr
# empty line
然后,我在Docker容器中运行一个交互式shell,它基于脚本所需的图像:
docker run -it --entrypoint bash python:3.10.3-bullseye
/# apt update
/# apt install cron
/# crontab < my-crontab
/# cron -f
如果我等待60秒,我希望每分钟看到一次连接到容器的控制台的输出,但是没有输出。
最后,我在/var/spool/mail/mail中找到了输出。
From root@5e3c82cb3651 Tue May 10 20:04:02 2022
Return-path: <root@5e3c82cb3651>
Envelope-to: root@5e3c82cb3651
Delivery-date: Tue, 10 May 2022 20:04:02 +0000
Received: from root by 5e3c82cb3651 with local (Exim 4.94.2)
(envelope-from <root@5e3c82cb3651>)
id 1noW5S-0000SA-0T
for root@5e3c82cb3651; Tue, 10 May 2022 20:04:02 +0000
From: root@5e3c82cb3651 (Cron Daemon)
To: root@5e3c82cb3651
Subject: Cron <root@5e3c82cb3651> date > /dev/stdout 2> /dev/stderr
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
X-Cron-Env: <SHELL=/bin/sh>
X-Cron-Env: <HOME=/root>
X-Cron-Env: <PATH=/usr/bin:/bin>
X-Cron-Env: <LOGNAME=root>
Message-Id: <E1noW5S-0000SA-0T@5e3c82cb3651>
Date: Tue, 10 May 2022 20:04:02 +0000
Tue May 10 20:04:01 UTC 2022
然后看起来/bin/sh完全忽略了crontab中的shell重定向。
2条答案
按热度按时间vd8tlhqk1#
@DavidMaze在他的评论中回答了这个问题(上面-找不到链接)。重定向到/proc/1/fd/1和/proc/1/fd/2(对于stderr)完全有效。谢谢你,David。
然而,这是违反直觉的。文件系统节点/dev/stdout和/dev/stderr已经作为符号链接存在,它们分别指向/proc/1/fd/1和/proc/1/fd/2,独立于cron。为什么
cmd > /dev/stdout
和cmd > /proc/1/fd/1
不能在crontab中互换呢?j9per5c42#
cron
是很久以前写的。可以预料到,它对docker
并不友好。它希望任务不产生输出。如果它们产生输出,则认为是错误,cron
尝试通过电子邮件向负责人报告。有一些技巧可以使cron
任务的输出在docker logs
中可见。但是为什么不选择docker
友好的cron
实现呢?其中之一是
supercronic
:docker-compose.yml
:Dockerfile
:crontab
:一个gist,包含更多信息。
另一个不错的例子是
yacron
,但是它使用了YAML。ofelia
也可以使用,但是它们似乎专注于在单独的容器中运行任务,这可能不是缺点,但是我不确定我为什么要这样做。但是如果你坚持传统的,你可以在我的other answer中找到一对。