我构建了一个 Docker 镜像来运行 crontab 文件:
from typing import (
TypeVar
)
SeriesString = TypeVar('pandas.core.series.Series(str)')
def f() -> SeriesString:
它有一个运行 RUN apt-get install -y cron
RUN touch /usr/local/learnintouch/cron.log
COPY learnintouch.cron /usr/local/learnintouch/
RUN chmod 0644 /usr/local/learnintouch/learnintouch.cron \
&& sudo crontab /usr/local/learnintouch/learnintouch.cron
文件的入口点,其中包含:
start.sh
# Run the crontab
sudo service cron start
文件包含:
learnintouch.cron
但是日志什么也没显示。
仅当我在容器中连接并手动运行 * * * * * echo "Hello cron" >> /usr/local/learnintouch/logs/cron.log 2>&1
文件时,即作为 start.sh
用户,日志才会显示 root
消息。
登录容器后,文件具有 Hello cron
用户:
apache
我认为是用户权限问题。
更新:我尝试使用 Dockerfile 复制问题,如下所示:
root@72f59adb5324:/usr/local/learnintouch# ll
total 2852
drwxr-xr-x 1 apache apache 4096 May 11 19:42 ./
drwxr-xr-x 1 root root 4096 May 3 20:10 ../
-rwxr-xr-x 1 apache apache 0 May 11 18:56 cron.log*
-rwxr-xr-x 1 apache apache 1057 May 11 19:34 start.sh*
root@72f59adb5324:/usr/local/learnintouch# whoami
root
构建镜像后:
FROM ubuntu:20.10
RUN apt-get update \
&& apt-get install -y sudo \
&& apt-get autoremove -y && apt-get clean
RUN mkdir -p /usr/local/learnintouch/
RUN apt-get install -y cron
COPY learnintouch.cron /usr/local/learnintouch/
RUN chmod 0644 /usr/local/learnintouch/learnintouch.cron \
&& crontab /usr/local/learnintouch/learnintouch.cron
ENTRYPOINT ["/usr/sbin/cron", "tail", "-f", "/dev/null"]
并运行容器:
docker build -t stephaneeybert/cronissue .
docker run --name cronissue -v ~/dev/docker/projects/common/volumes/logs:/usr/local/learnintouch/logs stephaneeybert/cronissue
开始工作正常,问题不会出现。
所以我认为问题可能出在我使用的 cron
文件中。
因此我尝试使用 docker-compose.yml
文件运行:
docker-compose.yml
使用 Docker Swarm 命令:
version: "3.7"
services:
cronissue:
image: stephaneeybert/cronissue
volumes:
- "~/dev/docker/projects/common/volumes/logs:/usr/local/learnintouch/logs"
cron 再次开始正常工作,问题不会出现。
所以我最终添加了我在我的项目中也有的 docker stack deploy --compose-file docker-compose.yml cronissue
属性:
user: "${CURRENT_UID}:${CURRENT_GID}"
这一次,version: "3.7"
services:
cronissue:
image: stephaneeybert/cronissue
volumes:
- "~/dev/docker/projects/common/volumes/logs:/usr/local/learnintouch/logs"
user: "${CURRENT_UID}:${CURRENT_GID}"
不起作用,问题出现了。
仅当我与主机用户一起运行容器时才会出现此问题。
作为旁注,我也尝试打开文件权限,但它没有改变任何东西:
cron
更新:我最终使用了 && chmod a+x /usr/bin/crontab \
&& chmod a+x /usr/sbin/cron \
而不是 supercronic
,因为它在容器中运行良好。
cron
答案 0 :(得分:0)
首先,ENTRYPOINT
中的命令没有意义。你有:
ENTRYPOINT ["/usr/sbin/cron", "tail", "-f", "/dev/null"]
您似乎试图在此处组合两个命令(cron
和 tail -f /dev/null
),但您不能将这样的命令混搭在一起。看起来您正在使用 tail -f /dev/null
来尝试在 cron
背景本身之后保持容器运行,但这是不必要的——查看 man page,我们可以使用 {{1 }} 标记为 -f
以使其保持在前台,这样就变成:
cron
幸运的是,按照您的配置方式,ENTRYPOINT ['/usr/sbin/cron', '-f']
只是忽略了未知参数(您可以运行 cron
并且它可以工作),因此您不小心做了正确的事情。>
<块引用>
仅当我与主机用户一起运行容器时才会出现此问题。
cron this is a test -f
守护进程旨在作为 cron
运行。如果我尝试以非 root
用户身份启动您的图像,例如使用您的 root
设置 docker-compose.yml
,我会得到:
user
即使您通过更改目录所有权来解决该问题,cronissue_1 | cron: can't open or create /var/run/crond.pid: Permission denied
仍然会失败:
cron
您需要以 $ cron -f
seteuid: Operation not permitted
的身份运行 cron
,或者如果您真的想以非 root
用户的身份运行调度程序,则需要找到其他一些工具。
作为旁注,我也尝试打开文件权限,但它没有改变任何东西:
root
注意上面的命令是no-ops;两个命令都已经 每个人都可以执行,所以你没有改变任何东西。