在Docker容器的前台运行cron没有输出



我想在Docker容器中运行一些cron作业,并将输出发送到stdout。我读了这篇文章:如何在docker容器内运行cron作业?

为了用一个简单的例子来验证这一点,我创建了一个演示crontab:

my-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重定向。

@DavidMaze在他的评论中回答了这个问题(上面-找不到链接)。重定向到/proc/1/fd/1和/proc/1/fd/2(对于stderr)完全有效。谢谢你,大卫。

然而,这是违反直觉的。文件系统节点/dev/stdout和/dev/stderr已经作为符号链接存在,分别指向/proc/1/fd/1和/proc/1/fd/2,独立于cron。为什么cmd > /dev/stdoutcmd > /proc/1/fd/1不能在crontab中互换?

cron是很久以前写的。意料之中的是,它不是,比如说,docker友好型的。它期望任务不产生任何输出。如果他们这样做了,那就被认为是一个错误,cron就会试图给负责人发电子邮件。有一些技巧可以使cron任务的输出在docker logs中看到,但是为什么不选择一个docker友好的cron实现呢?

其中一个是supercronic:

docker-compose.yml:

services:
supercronic:
build: .
command: supercronic crontab

Dockerfile:

FROM alpine:3.17
RUN set -x 
&& apk add --no-cache supercronic shadow 
&& useradd -m app
USER app
COPY crontab .

crontab:

* * * * * date

一个要点与更多的信息。

另一个很好的是yacron,但它使用YAML。

ofelia可以使用,但它们似乎专注于在单独的容器中运行任务。这可能不是一个缺点,但我不确定为什么我想这样做。

但如果你坚持传统的,你可以在我的另一个答案中找到一些。

相关内容

  • 没有找到相关文章

最新更新