繁体   English   中英

Docker cron 计划作业未运行

[英]Docker cron scheduled job not running

我正在尝试使用基于 Alpine 映像的 docker 容器来运行计划的 cron 作业,遵循本教程,但是在我的启动脚本中打印语句后,容器只是退出,而没有运行我的其他脚本。

我的 docker-compose 服务配置如下:

  cron:
    image: alpine:3.11
    command: /usr/local/startup.sh && crond -f -l 8
    volumes:
      - ./cron_tasks_folder/1min:/etc/periodic/1min/:ro
      - ./cron_tasks_folder/15min:/etc/periodic/15min/:ro
      - ./cron_tasks_folder/hourly:/etc/periodic/hourly/:ro
      - ./scripts/startup.sh:/usr/local/startup.sh:ro

所以它运行一个名为startup.sh的初始脚本,然后启动 cron 守护进程。 startup.sh脚本包含以下内容:

#!/bin/sh

echo "Starting startup.sh.."
echo "*       *       *       *       *       run-parts /etc/periodic/1min" >> /etc/crontabs/root
crontab -l
sleep 300

我在里面放了一个 sleep 命令,这样我就可以在容器上启动一个交互式 shell 并确保里面的所有东西看起来都很好。 该脚本为 1 分钟脚本创建了另一个文件夹。 我在那里添加了一个测试脚本,我可以验证它在那里:

/etc/periodic/1min # ls -a
.           ..          testScript

该脚本是可执行的:

/etc/periodic/1min # ls -l testScript 
-rwxr-xr-x    1 root     root            31 Jul 30 01:51 testScript

testScript只是一个 echo 语句,以确保它首先工作:

echo "The donkey is in charge"

查看 etc/crontabs 中的root文件,我看到以下内容(我已经多次重新运行容器,并且每次都创建一个新的 1min 文件夹,这是不必要的,但我认为不是这里的问题):

# do daily/weekly/monthly maintenance
# min   hour    day     month   weekday command
*/15    *       *       *       *       run-parts /etc/periodic/15min
0       *       *       *       *       run-parts /etc/periodic/hourly
0       2       *       *       *       run-parts /etc/periodic/daily
0       3       *       *       6       run-parts /etc/periodic/weekly
0       5       1       *       *       run-parts /etc/periodic/monthly

*       *       *       *       *       run-parts /etc/periodic/1min
*       *       *       *       *       run-parts /etc/periodic/1min
*       *       *       *       *       run-parts /etc/periodic/1min
*       *       *       *       *       run-parts /etc/periodic/1min
*       *       *       *       *       run-parts /etc/periodic/1min

testScript的 echo 语句永远不会打印到我的终端,并且容器在启动后不久以退出代码 0 退出。 我想每分钟打印一次这个声明......我错过了什么?

在 docker compose 文件中,你有

    command: /usr/local/startup.sh && crond -f -l 8

目的是作为一个 shell 命令运行,但从问题中完全不清楚会发生什么; 这取决于您的ENTRYPOINT 因为它是用[]括号定义的,所以不会提供额外的 shell。 command值将作为参数传递给ENTRYPOINT

假设这成为一个 shell 命令,shell 中的&&运行左侧,如果成功,则运行右侧。 所以startup.sh需要crond执行之前完成。 startup.sh

sleep 300

crond300 秒调用。

在任何一种情况下, crond要么根本没有被调用,要么sleep没有完成。 评论显示发现了启动crond的错误。

使用这样的入口点是在调用主可执行文件之前配置环境或提供运行时参数的标准做法。 要做到这一点,您应该确保使用exec来运行主可执行文件,以便它接收信号,否则这些信号将进入运行入口点脚本的 bash shell。

所以在startup.sh的末尾:

exec crond -f -l 8

将使用crond替换运行startup.sh的外壳,以便crond接收所有信号(此时外壳消失了)。 这很微妙但很重要!

通常,使应用程序的调用尽可能简单。 举个例子,你的执行过程被分割成入口点、命令和启动脚本,它们之间没有明确的接口。 如果您将crond直接放入 Dockerfile 并将其留在那里,您就不会挂断调用。 有时必须在运行时提供参数,但环境变量 - 具有名称,而不仅仅是位置 - 通常是首选。 这使调用保持简单且调试简单。 但是,当这不起作用时,shell 脚本入口点是一个很好的解决方案 - 只需确保exec您的最终进程即可!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM