我有一个简单的Dockerfile和docker compose设置来测试容器中的cron。
最后一步,启动了cron并收到消息cron已经启动,但是当我登录到容器并检查cron服务的状态时,它没有运行。这怎么可能?
我相信我误会了一些东西,但无法弄清楚它到底是什么。
Dockerfile:
FROM ubuntu:bionic
# Create the log file to be able to run tail
RUN touch /var/log/cron.log
# Install Cron
RUN apt-get update && apt-get install cron
# Install the crontab
COPY crontab /etc/cron.d/crontab
# Is this needed??
RUN touch /var/log/cron.log
RUN chmod 777 /var/log/cron.log
# Run the command on container startup
CMD service cron start && tail -f /var/log/cron.log
docker-compose.yml
version: '3'
services:
cron:
# build a custom image
build:
context: .
dockerfile: Dockerfile
# a name for easier reference
image: cron
文件crontab
有效,并且包含:
* * * * * echo "Hello world" >> /var/log/cron.log 2>&1
# Don't remove the empty line at the end of this file. It is required.
然后以docker-compose up --build
开头
输出为:
Creating network "docker-cron_default" with the default driver
Building cron
Step 1/8 : FROM ubuntu:bionic
---> 4c108a37151f
Step 2/8 : MAINTAINER wouter.samaey@storefront.be
---> Using cache
---> 0d9fa7049481
Step 3/8 : RUN touch /var/log/cron.log
---> Using cache
---> 39bb838fe945
Step 4/8 : RUN apt-get update && apt-get install cron
---> Using cache
---> d3ce6cc03821
Step 5/8 : COPY crontab /etc/cron.d/crontab
---> Using cache
---> fab99f2e2e77
Step 6/8 : RUN touch /var/log/cron.log
---> Using cache
---> c7fab49def98
Step 7/8 : RUN chmod 777 /var/log/cron.log
---> Using cache
---> 7dc00a5913bd
Step 8/8 : CMD service cron start && tail -f /var/log/cron.log
---> Running in a4bdec436613
Removing intermediate container a4bdec436613
---> 97c867e25091
Successfully built 97c867e25091
Successfully tagged cron:latest
Creating docker-cron_cron_1 ... done
Attaching to docker-cron_cron_1
cron_1 | * Starting periodic command scheduler cron
cron_1 | ...done.
但是当我在该容器上打开bash shell时,cron没有运行:
docker run -it cron /bin/bash
root@d6649b402133:/# /etc/init.d/cron status
* cron is not running
这怎么可能?
答案 0 :(得分:2)
Docker容器仅运行一个进程。当你
docker run --rm -it imagename bash
shell运行而不是 Dockerfile中的CMD
。
典型的最佳实践是将要运行的事物作为前台进程运行。在您的示例中,如果存在某种导致crond崩溃的错误,您将永远不会注意到,因为容器的主要过程是“永远休眠”。相应地,在显示的容器中获取交互式shell对于调试确实很有用(“如果我的文件不在/etc/cron.d
中,那么它实际在哪里?”),但这并不是操作Docker的真正标准方法。
简而言之:我将Dockerfile的最后一行更改为
CMD ["crond", "-n"]
使守护程序作为前台进程启动,而不必担心尝试同时获取shell。