Docker cron 计划作业未 运行
Docker cron scheduled job not running
我正在尝试使用基于 Alpine 图像的 docker 容器来 运行 计划的 cron 作业,遵循此 tutorial,但是在我的启动脚本中打印语句之后,容器刚刚退出,没有 运行ning 我的其他脚本。
我的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
我在那里放了一个睡眠命令,这样我就可以在容器上启动一个交互式 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
文件,我看到以下内容(我已经多次重新 运行 容器,每次都创建一个新的 1 分钟文件夹,这是不必要的,但我认为不是这里的问题):
# 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 撰写文件中你有
command: /usr/local/startup.sh && crond -f -l 8
意图是 运行 作为 shell 命令,但从问题中完全不清楚会发生什么;这取决于您的 ENTRYPOINT
。由于它是用 []
括号定义的,因此不会提供额外的 shell。 command
值将作为参数传递给 ENTRYPOINT
.
假设将变为shell命令,&&
在shell 运行的左侧,如果成功,则 运行 位于右侧。所以startup.sh
需要在crond
执行之前完成。 startup.sh
以
结尾
sleep 300
crond
仅在 300 秒后 被调用。
在任何一种情况下,crond
要么根本没有被调用,要么 sleep
还没有完成。注释显示发现了从 crond
开始的错误。
使用这样的入口点是之前配置环境的标准做法,或者在调用主可执行文件时提供 运行时间参数。要正确执行此操作,您应该确保将 exec
用于 运行 主可执行文件,以便它接收信号,否则这些信号将转到 bash shell 运行设置入口点脚本。
所以在 startup.sh
结束时:
exec crond -f -l 8
将将shell运行宁startup.sh
替换为crond
,使crond
接收所有信号(此时 shell 消失了)。这很微妙但很重要!
一般而言,应使应用程序的调用尽可能简单。例如,您的执行过程分为入口点、命令和启动脚本,它们之间没有明确的接口。如果您将 crond
直接放入 Dockerfile 并将其留在那儿,您就不会挂断调用。有时必须在 运行 时提供参数,但环境变量 - 具有 名称 ,而不仅仅是位置 - 通常是首选。这使调用简单且调试简单。但是,当这不起作用时,shell 脚本入口点是一个很好的解决方案 - 只要确保 exec
你的最终过程!
我正在尝试使用基于 Alpine 图像的 docker 容器来 运行 计划的 cron 作业,遵循此 tutorial,但是在我的启动脚本中打印语句之后,容器刚刚退出,没有 运行ning 我的其他脚本。
我的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
我在那里放了一个睡眠命令,这样我就可以在容器上启动一个交互式 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
文件,我看到以下内容(我已经多次重新 运行 容器,每次都创建一个新的 1 分钟文件夹,这是不必要的,但我认为不是这里的问题):
# 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 撰写文件中你有
command: /usr/local/startup.sh && crond -f -l 8
意图是 运行 作为 shell 命令,但从问题中完全不清楚会发生什么;这取决于您的 ENTRYPOINT
。由于它是用 []
括号定义的,因此不会提供额外的 shell。 command
值将作为参数传递给 ENTRYPOINT
.
假设将变为shell命令,&&
在shell 运行的左侧,如果成功,则 运行 位于右侧。所以startup.sh
需要在crond
执行之前完成。 startup.sh
以
sleep 300
crond
仅在 300 秒后 被调用。
在任何一种情况下,crond
要么根本没有被调用,要么 sleep
还没有完成。注释显示发现了从 crond
开始的错误。
使用这样的入口点是之前配置环境的标准做法,或者在调用主可执行文件时提供 运行时间参数。要正确执行此操作,您应该确保将 exec
用于 运行 主可执行文件,以便它接收信号,否则这些信号将转到 bash shell 运行设置入口点脚本。
所以在 startup.sh
结束时:
exec crond -f -l 8
将将shell运行宁startup.sh
替换为crond
,使crond
接收所有信号(此时 shell 消失了)。这很微妙但很重要!
一般而言,应使应用程序的调用尽可能简单。例如,您的执行过程分为入口点、命令和启动脚本,它们之间没有明确的接口。如果您将 crond
直接放入 Dockerfile 并将其留在那儿,您就不会挂断调用。有时必须在 运行 时提供参数,但环境变量 - 具有 名称 ,而不仅仅是位置 - 通常是首选。这使调用简单且调试简单。但是,当这不起作用时,shell 脚本入口点是一个很好的解决方案 - 只要确保 exec
你的最终过程!