【问题标题】:How to run a cron job inside a docker container如何在 docker 容器中运行 cron 作业
【发布时间】:2016-08-29 04:14:50
【问题描述】:

我尝试在 docker 容器中运行 cron 作业,但对我没有任何作用。
我的容器只有 cron.dailycron.weekly 文件。
crontab,cron.d,cron.hourly 在我的容器中不存在。
crontab -e 也不起作用。
我的容器使用/bin/bash 运行。

【问题讨论】:

    标签: linux docker cron


    【解决方案1】:

    这是我运行我的一个 cron 容器的方法。

    Dockerfile:

    FROM alpine:3.3
    
    ADD crontab.txt /crontab.txt
    ADD script.sh /script.sh
    COPY entry.sh /entry.sh
    RUN chmod 755 /script.sh /entry.sh
    RUN /usr/bin/crontab /crontab.txt
    
    CMD ["/entry.sh"]
    

    crontab.txt

    */30 * * * * /script.sh >> /var/log/script.log
    

    entry.sh

    #!/bin/sh
    
    # start cron
    /usr/sbin/crond -f -l 8
    

    script.sh

    #!/bin/sh
    
    # code goes here.
    echo "This is a script, run by cron!"
    

    像这样构建

    docker build -t mycron .
    

    这样跑

    docker run -d mycron
    

    添加您自己的脚本并编辑 crontab.txt,然后构建映像并运行。由于是基于alpine,所以图片超级小。

    【讨论】:

    • 这很棒。我遇到的一个问题是,在 docker run ... 我无法使用 ctrl-c 停止容器运行?即使在我关闭终端之后,当我执行 docker ps 时,我也可以看到容器仍在运行。有人有同样的问题吗?
    • 请在答案中添加RUN apk add --update apk-cron && rm -rf /var/cache/apk/* 以获取完整示例。列出的将 cron 添加到 alpine 的方法有很多,而这一种方法适用于您的示例。
    • 嗨,为什么有 2 个 ADD 和 1 个 COPY?,根据我读到的内容,3 COPY 或 3 ADD 可以正常工作(在这种情况下)。我说的对吗?
    • crond -f -l 8, 8 是什么意思?据 man 说,日志级别是大写的L
    • 我没有看到 crond 默认在容器中运行。我必须执行并运行 crond,这实际上触发了 cron 作业。我在这里缺少什么吗?
    【解决方案2】:

    crond 与 Alpine 上的 tiny 配合得很好

    RUN apk add --no-cache tini
    
    ENTRYPOINT ["/sbin/tini", "--"]
    CMD ["/usr/sbin/crond", "-f"]
    

    但不应作为容器主进程 (PID 1) 运行,因为僵尸收割问题和信号处理问题。详情请参阅this Docker PRthis blog post

    【讨论】:

    • 为什么不应该作为PID1运行?
    【解决方案3】:

    Here is good explanation of cron problems inside docker container:

    Docker 文件示例:

    FROM alpine
    
    # Copy script which should be run
    COPY ./myawesomescript /usr/local/bin/myawesomescript
    # Run the cron every minute
    RUN echo '*  *  *  *  *    /usr/local/bin/myawesomescript' > /etc/crontabs/root
    
    CMD ['crond', '-l 2', '-f']
    

    【讨论】:

    • 就我而言,这种方法行不通。我也尝试了一些变体,似乎在最终容器中,对/etc/crontabs/root 所做的更改不存在。
    【解决方案4】:

    @ken-cochrane 的解决方案可能是最好的,但是,还有一种方法可以做到这一点,而无需创建额外的文件。

    无需额外文件即可:

    要走的路是在 entrypoint.sh 文件中设置 cron。

    Dockerfile

    
    ...
    
    # Your Dockerfile above
    
    
    COPY entrypoint.sh /
    RUN chmod +x /entrypoint.sh
    ENTRYPOINT ["/entrypoint.sh"]
    

    entrypoint.sh

    
    echo "* * * * * echo 'I love running my crons'" >> /etc/crontabs/root
    crond -l 2 -f > /dev/stdout 2> /dev/stderr &
    
    # You can put the rest of your entrypoint.sh below this line
    
    ...
    
    

    【讨论】:

      猜你喜欢
      • 2016-09-24
      • 2018-12-27
      相关资源
      最近更新 更多