【问题标题】:Enable crond in an Alpine container在 Alpine 容器中启用 crond
【发布时间】:2021-04-01 21:05:05
【问题描述】:

上下文

我正在尝试在 Alpine 容器中安排一些摄取作业。我花了一段时间才明白为什么我的cron 作业 没有启动:crond 似乎没有运行

rc-service -l | grep crond 

根据Alpine's documentation,crond 必须首先以openrc 开始(即某种systemctl)。这是 Dockerfile

FROM python:3.7-alpine

# set work directory
WORKDIR /usr/src/collector

RUN apk update \
    && apk add curl openrc

# ======>>>> HERE !!!!! 
RUN rc-service crond start && rc-update add crond

# install dependencies
RUN pip install --upgrade pip
RUN pip install pipenv
COPY ./Pipfile /usr/src/collector/Pipfile
RUN pipenv install --skip-lock --system --dev

# copy entrypoint.sh
COPY ./entrypoint.sh /usr/src/collector/entrypoint.sh

# copy project
COPY . /usr/src/collector/

# run entrypoint.sh
ENTRYPOINT ["/usr/src/collector/entrypoint.sh"]

entrypoint.sh 只是在/etc/crontabs/root 末尾追加作业

问题

我收到以下错误:

 * rc-service: service `crond' does not exist
ERROR: Service 'collector' failed to build: The command '/bin/sh -c rc-service crond start && rc-update add crond' returned a non-zero code: 1

事情开始有点循环了。 rc-service 如何同时无法识别服务:

  • sh好像知道crond这个名字,

  • 有一个/etc/crontabs/root

我错过了什么?

【问题讨论】:

  • 查看stackoverflow.com/questions/56803812/…,我在其中概述了如何构建一个简单的 CRON 容器并让它在 docker-compose 环境中的其他容器中运行命令。
  • 尝试用RUN crond 替换RUN rc-service crond start && rc-update add crond
  • @fjc 有趣的帖子,但它不能解决我的问题。我试图在 docker 文件的末尾添加RUN crondCMD crond -f,但它似乎并没有改变任何事情:没有 cron 作业,并且 rc-services 列表中仍然缺少 crond。我认为这是个问题
  • 这两种方法有一个基本的区别。我相信,您尝试让cron 与您的应用程序在同一个容器中运行。这只会导致戏剧性,每次;-)。我的方法,以及我看到许多其他人使用的方法,是在单独的容器中运行它。
  • 我还是很疑惑。为什么呢?此容器不包含数据库或应用程序,而只是用于填充数据库的简单注入作业。这个容器已经很简单了,不用拆分它。我会弄清楚并及时通知您

标签: docker cron alpine


【解决方案1】:

一些 Alpine Docker 容器缺少 busybox-initscripts package。只需将其附加到 apk add 命令的末尾,crond 就应该作为服务运行。

您可能还需要从 Dockerfile 中删除以下行,因为 busybox-initscripts 似乎在安装后立即将 crond 作为服务运行:

RUN rc-service crond start && rc-update add crond

【讨论】:

    【解决方案2】:

    我可以通过在实际脚本命令之前将 crond 命令添加到 docker-entrypoint.sh 来解决此问题。

    例如:

    #!/bin/sh
    set -e
    
    crond &
    
    ...(rest of the original script)
    

    这样 crond 会作为分离的进程重新加载。

    所以所有需要的步骤就是

    • 找到 entrypoint.sh 并将其复制到构建文件夹。我是从一个正在运行的容器中完成的:
    docker cp <running container name>:<path to script>/entrypoint.sh <path to Dockerfile folder>/entrypoint.sh
    
    • 如上所述修改entrypoint.sh
    • 在用于构建自定义映像的 Dockerfile 中再次包含 entrypoint.sh。 Dockerfile 示例:
    ...
    COPY docker-entrypoint.sh <path to script>/entrypoint.sh
    RUN chmod +x <path to script>/entrypoint.sh
    ...
    
    • 然后构建并使用新的自定义映像:
    docker build -t <registry if used>/<image name>:<tag> .
    

    【讨论】:

      【解决方案3】:

      也遇到过这个问题。我对容器的解决方案是在 screen 中执行 crond

      # apk add screen --no-cache
      # screen -dmS crond crond -f -l 0
      

      【讨论】:

        【解决方案4】:

        运行这个:apk add openrc --no-cache

        【讨论】:

        • 请解释一下它有什么帮助
        • openrc 在容器中不起作用。它不喜欢不是 pid 1
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-14
        • 2023-01-22
        • 2021-04-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多