验证crontab在使用slim-buster docker镜像的容器上工作?

0yg35tkg  于 2023-08-03  发布在  Docker
关注(0)|答案(2)|浏览(120)

问题描述

在运行docker-compose up后运行docker-compose logs -f cron时,我无法看到cron作业的任何输出。
当我使用VSCode附加到容器时,我导航到var/logs/cron.log并运行cat命令,没有看到任何输出。奇怪的是,当我运行crontab -l时,我看到* * * * * /bin/sh get_date.sh作为输出。

尝试解决方案说明

下面是我如何组织这个项目的(由于稍后的可扩展性原因,目前它被过度工程化了)

├── config
│   └── crontab
├── docker-compose.yml
├── Dockerfile
├── README.md
└── scripts
    └── get_date.sh

字符串
这里是关于上面的细节,内容很简单。此外,我尝试使用一个精简的python:3.8-slim-buster docker镜像,这样我就可以运行bash或python脚本(没有尝试):

crontab

* * * * * /bin/sh get_date.sh

get_date.sh

#!/bin/sh
echo "Current date and time is " "$(date +%D-%H:%M)"

docker-compose.yml

version: '3.8'
services:
  cron:
    build:
      context: .
      dockerfile: ./Dockerfile

Dockerfile

FROM python:3.8-slim-buster

#Install cron  
RUN apt-get update \
&& apt-get install -y cron 

# Copying script file into the container.
COPY scripts/get_date.sh .

# Giving executable permission to the script file.
RUN chmod +x get_date.sh

# Adding crontab to the appropriate location
ADD config/crontab /etc/cron.d/my-cron-file

# Giving executable permission to crontab file
RUN chmod 0644 /etc/cron.d/my-cron-file

# Running crontab
RUN crontab /etc/cron.d/my-cron-file

# Create the log file to be able to run tail
RUN touch /var/log/cron.log

# Creating entry point for cron 
CMD ["cron", "tail", "-f", "/var/log/cron.log"]

尝试的内容

我刚开始尝试让cron在容器环境中工作。我没有得到任何错误消息,所以不知道我如何可以调试这个问题,除了描述的行为。
我已经将crontab的内容从* * * * * root bash get_date.sh更改为上面的内容。我还检查了stackoverflow,发现了一个类似的问题here,但据我所知,没有明确的解决方案。
先谢谢你了。

参考文献

z9ju0rcb

z9ju0rcb1#

有几个问题阻碍了此功能的正常工作:
1.您尝试运行tail是无效操作:在CMD中,您只需运行cron tail -f /var/log/cron.log命令即可。换句话说,您正在运行cron并提供tail -f /var/log/cron.log作为参数。如果你想运行cron,然后运行tail命令,你需要这样写:

CMD ["sh", "-c", "cron && tail -f /var/log/cron.log"]

字符串
1.虽然上面的命令将启动cron并运行tail命令,但您仍然不会看到任何日志输出......因为Debian cron不记录到文件;它记录到syslog。在/var/log/cron.log中看不到任何输出,除非安装、配置并运行syslog守护进程。
我建议这是一个替代方案:
1.修复config/crontab中的语法;对于安装在/etc/cron.d中的文件,您需要提供用户名:

* * * * * root /bin/sh /usr/local/bin/get_date.sh


我在这里也明确了路径,而不是假设我们的cron作业和COPY命令具有相同的工作目录。
这里还有一个问题:这个脚本输出到 stdout,但这不会有任何用处(cron通常从cron作业中获取输出,然后将其通过电子邮件发送给root)。我们可以显式地将输出发送到syslog

* * * * * root /bin/sh /usr/local/bin/get_date.sh | logger


1.我们不需要使get_date.sh可执行,因为我们使用sh命令显式地运行它。
1.我们将使用busybox作为一个系统日志守护进程,它会记录到 stdout
这一切让我们:

FROM python:3.8-slim-buster

# Install cron and busybox
RUN apt-get update \
  && apt-get install -y \
    cron \
    busybox

# Copying script file into the container.
COPY scripts/get_date.sh /usr/local/bin/get_date.sh

# Adding crontab to the appropriate location
COPY config/crontab /etc/cron.d/get_date

# Creating entry point for cron 
CMD sh -c 'cron && busybox syslogd -n -O-'


如果我们以此构建一个镜像,启动一个容器,并让它运行一段时间,我们会看到输出:

Sep 22 00:17:52 701eb0bd249f syslog.info syslogd started: BusyBox v1.30.1
Sep 22 00:18:01 701eb0bd249f authpriv.err CRON[7]: pam_env(cron:session): Unable to open env file: /etc/default/locale: No such file or directory
Sep 22 00:18:01 701eb0bd249f authpriv.info CRON[7]: pam_unix(cron:session): session opened for user root by (uid=0)
Sep 22 00:18:01 701eb0bd249f cron.info CRON[8]: (root) CMD (/bin/sh /usr/local/bin/get_date.sh | logger)
Sep 22 00:18:01 701eb0bd249f user.notice root: Current date and time is  09/22/22-00:18
Sep 22 00:18:01 701eb0bd249f authpriv.info CRON[7]: pam_unix(cron:session): session closed for user root
Sep 22 00:19:01 701eb0bd249f authpriv.err CRON[12]: pam_env(cron:session): Unable to open env file: /etc/default/locale: No such file or directory
Sep 22 00:19:01 701eb0bd249f authpriv.info CRON[12]: pam_unix(cron:session): session opened for user root by (uid=0)
Sep 22 00:19:01 701eb0bd249f cron.info CRON[13]: (root) CMD (/bin/sh /usr/local/bin/get_date.sh | logger)
Sep 22 00:19:01 701eb0bd249f user.notice root: Current date and time is  09/22/22-00:19
Sep 22 00:19:01 701eb0bd249f authpriv.info CRON[12]: pam_unix(cron:session): session closed for user root

xa9qqrwz

xa9qqrwz2#

我最近不得不将cron添加到debian 11 docker中。我不确定我的方法是否正确,但我的docker文件将所有crontab复制到/etc/cron.d中(您需要指定用户)。然后我在启动脚本中包含了/etc/init.d/cron start。虽然我不确定这是“正确”的方式来做到这一点,但它似乎工作。
Docker文件:

RUN apt update && \
apt install ... cron

COPY cronjobs /etc/cron.d

字符串
启动文件(run.sh):

...
postfix start \
 && /etc/init.d/cron start \
 && bash

相关问题