尝试 运行 一个带有 crontab 和简单 python 脚本的简单 docker 容器

Trying to run a simple docker container with a crontab and a simple python script

所以我对创建容器还很陌生,我有一个简单的 Dockerfile,我希望每分钟 运行 一个简单的 python 脚本:

FROM python:3.8-buster
RUN apt-get update && apt-get install -y cron
COPY my_python /bin/my_python
COPY root /var/spool/cron/crontabs/root
RUN chmod +x /bin/my_python
CMD cron -l 2 -f

其中 my_python:

print("hi world!!")

和根:

* * * * * python3 /bin/my_python

然后我只创建图像和容器:

 docker image build -t python-test
 docker container run -it --name python-test python-test

我本应每分钟都能看到 hi world 的打印,但是当 运行打开容器时(在图像构建之后)似乎没有日志出现。

我做错了什么?

首先,我相信您希望在 cron 命令行中使用 -L 2 而不是 -l 2;有关详细信息,请参阅 man page

cron 守护程序记录到 syslog,因此如果某些事情没有按预期工作,最好 ar运行ge 接收这些消息。 busybox 工具提供了一个简单的 syslog 守护进程,它可以记录到内存中的缓冲区和一个用于读取这些日志的工具,所以我将你的 Dockerfile 修改为如下所示:

FROM python:3.8-buster
RUN apt-get update && apt-get install -y cron busybox
COPY my_python /bin/my_python
COPY root /var/spool/cron/crontabs/root
RUN chmod +x /bin/my_python
CMD busybox syslogd -C; cron -L 2 -f

启动后,我 docker exec 进入容器并 运行 busybox logread 发现:

Jan 24 16:50:45 7f516db86417 cron.info cron[4]: (CRON) INFO (pidfile fd = 3)
Jan 24 16:50:45 7f516db86417 cron.info cron[4]: (root) INSECURE MODE (mode 0600 expected) (crontabs/root)
Jan 24 16:50:45 7f516db86417 cron.info cron[4]: (CRON) INFO (Running @reboot jobs)

你的问题来了:root crontab 的权限不正确。有两种方法可以解决此问题:

  1. 我们可以在将文件复制到位时显式 chmod 文件,或者
  2. 我们可以使用 crontab 命令来安装文件,它会帮我们搞定

我喜欢选项 2,因为它意味着我们不需要知道 cron 在权限方面期望的细节。这让我们:

FROM python:3.8-buster
RUN apt-get update && apt-get install -y cron busybox
COPY my_python /bin/my_python
COPY root /tmp/root.crontab
RUN crontab /tmp/root.crontab
RUN chmod +x /bin/my_python
CMD busybox syslogd -C; cron -L 2 -f

通过该更改,我们可以确认 cron 作业现在 运行 符合预期:

Jan 24 16:59:50 8aa688ad31cc syslog.info syslogd started: BusyBox v1.30.1
Jan 24 16:59:50 8aa688ad31cc cron.info cron[4]: (CRON) INFO (pidfile fd = 3)
Jan 24 16:59:50 8aa688ad31cc cron.info cron[4]: (CRON) INFO (Running @reboot jobs)
Jan 24 17:00:01 8aa688ad31cc authpriv.err CRON[7]: pam_env(cron:session): Unable to open env file: /etc/default/locale: No such file or directory
Jan 24 17:00:01 8aa688ad31cc authpriv.info CRON[7]: pam_unix(cron:session): session opened for user root by (uid=0)
Jan 24 17:00:02 8aa688ad31cc cron.info CRON[7]: (root) END (python3 /bin/my_python)
Jan 24 17:00:02 8aa688ad31cc authpriv.info CRON[7]: pam_unix(cron:session): session closed for user root

但是...容器仍然没有输出!如果您通读该手册页,您会发现:

cron then wakes up every minute, examining all stored crontabs, checking each command to see if it should be run in the current minute. When executing commands, any output is mailed to the owner of the crontab (or to the user named in the MAILTO environment variable in the crontab, if such exists)...

换句话说,cron 收集程序的输出并尝试 邮寄给拥有 cron 作业的用户。如果你想看到 控制台上 cron 作业的输出,您需要明确 重定向标准输出,像这样:

* * * * * python3 /bin/my_python > /dev/console

进行此更改后,运行 消息中的图像结果...

hi world!

...每分钟向控制台打印一次。