在Docker容器中的前景中运行Cron不会产生任何输出

发布于 2025-01-27 14:51:04 字数 1544 浏览 2 评论 0 原文

我想在Docker容器中运行一些CRON作业,然后将输出发送到STDOUT。我读了这篇文章:一个docker容器?

为了用一个简单的示例尝试一下,我创建了一个演示crontab:

my-crontab:

* * * * * date > /dev/stdout 2> /dev/stderr
# empty line

然后,我根据脚本需要的图像在docker容器中运行一个交互式外壳,

docker run -it --entrypoint bash python:3.10.3-bullseye

/# apt update
/# apt install cron
/# crontab < my-crontab
/# cron -f

如果我等待60几秒钟,我希望每分钟每分钟一次连接到容器上的控制台。但是没有输出。

最后,我在/var/spool/邮件/邮件中找到了输出。这是一条消息:

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中的外壳重定向。

I want to run some cron jobs in a Docker container and send the output to stdout. I read this post: How to run a cron job inside a docker container?

To try this out with a simple example, I created a demo crontab:

my-crontab:

* * * * * date > /dev/stdout 2> /dev/stderr
# empty line

Then I run an interactive shell inside a Docker container based on the image my scripts will need:

docker run -it --entrypoint bash python:3.10.3-bullseye

/# apt update
/# apt install cron
/# crontab < my-crontab
/# cron -f

If I wait 60 seconds, I expect to see some output to the console attached to the container once every minute. But there is no output.

Finally, I found the output in /var/spool/mail/mail. Here is one message:

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

Then it looks like /bin/sh is completely ignoring the shell redirection in the crontab.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

风透绣罗衣 2025-02-03 14:51:04

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

然而,这是违反直觉的。文件系统节点/dev/stdout和/dev/stderr已经存在于/proc/proc/1/fd/1和/proc/fd/fd/2的符号链接中,独立于cron。为什么不 cmd&gt; /dev/stdout cmd&gt; /proc/1/fd/1 在crontab中可以互换吗?

@DavidMaze answered this in his comment (above - can't find a link to it). Redirecting to /proc/1/fd/1 and /proc/1/fd/2 (for stderr) totally works. Thank you, David.

Nevertheless, that's counterintuitive. The filesystem nodes /dev/stdout and /dev/stderr already exist as symlinks that point to /proc/1/fd/1 and /proc/1/fd/2, respectively, independent of cron. Why wouldn't cmd > /dev/stdout and cmd > /proc/1/fd/1 be interchangeable in a crontab?

像极了他 2025-02-03 14:51:04

cron 是一段时间以前写的。预计,它不是 docker friendly。它希望任务不会产生输出。如果他们这样做,那被认为是错误, cron 试图给负责人发送电子邮件。有一些技巧可以使 cron 任务的输出在 docker logs 中可以看到,但是为什么不选择 docker docker -friendly 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

a 要点提供更多信息。

另一个好的是 noreflow noreferrer“> yacron yacron ,但它使用yaml。

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

但是,如果您坚持传统的内容,可以在我的其他答案

cron was written quite a while a ago. And expectedly, it's not, say, docker-friendly. It expects tasks to produce no output. And if they do, that is considered an error, and cron tries to email the responsible person about it. There are some tricks to make cron tasks' output to be seen in docker logs, but why not choose a docker-friendly cron implementation?

One of which is 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

A gist with a bit more info.

Another good one is yacron, but it uses YAML.

ofelia can be used, but they seem to focus on running tasks in separate containers. Which is probably not a downside, but I'm not sure why I'd want to do that.

But if you insist on traditional ones, you can find a couple in my other answer.

眸中客 2025-02-03 14:51:04

我重新考虑,并决定将克朗放在码头组的容器中是“反模式”。一方面,运行容器时“只能工作”的服务都很容易包装,但是如果我发生任何事情,那么接管的人可能很难弄清楚如何停止重复出现的任务(我网络工程师团队中唯一的开发人员和Docker用户)。相反,我只在团队使用的主机帐户中使用crontab,然后将容器的stderr重定向到主机上的日志文件。这样,对于那些知道在哪里看的人来说,一切都很容易找到。

I reconsidered and decided that putting cron in a Docker container was an “anti-pattern”. On the one hand, it’s tempting to package it all as a service that “just works” when you run the container, but if anything happened to me it might be hard for whoever takes over to figure out how to stop a recurring task (I’m the only developer and Docker user in a team of network engineers). Instead, I just use crontab in a host account used by my team, and redirect the container’s stderr to a log file on the host. That way everything can be found easily for those who know where to look.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文