Docker容器中Crontab任务未执行问题排查求助
问题背景
在Docker容器内配置crontab定时任务,容器创建成功后执行crontab -l能看到任务,但任务始终未运行。
用户提供的配置文件
Dockerfile
FROM openjdk:11-oraclelinux8 RUN mkdir -p /opt/my-user/ RUN mkdir -p /opt/my-user/joblogs RUN groupadd my-user && adduser my-user -g my-user RUN chown -R my-user:my-user /opt/my-user/ RUN microdnf install yum RUN yum -y update RUN yum -y install cronie RUN yum -y install vi RUN yum -y install telnet COPY talend /opt/my-user/ COPY entrypoint.sh /opt/my-user/ RUN chmod +x /opt/my-user/entrypoint.sh RUN chmod +x /opt/my-user/ETLJob/ETLJob_run.sh RUN chown -R my-user:my-user /opt/my-user/ RUN echo "*/2 * * * * /bin/sh /opt/my-user/ETLJob/ETLJob_run.sh >> /opt/my-user/joblogs/job.log 2>&1" >> /etc/cron.d/my-user-job RUN chmod 0644 /etc/cron.d/my-user-job RUN crontab -u my-user /etc/cron.d/my-user-job RUN chmod u+s /usr/sbin/crond USER my-user:my-user ENTRYPOINT [ "/opt/my-user/entrypoint.sh" ]
entrypoint.sh
#!/bin/bash echo "Start cron" crontab /etc/cron.d/diomedee-job echo "cron started" # Run forever tail -f /dev/null
排查思路与解决建议
修正crontab文件路径错误
entrypoint.sh中执行crontab /etc/cron.d/diomedee-job,但Dockerfile里创建的任务文件是/etc/cron.d/my-user-job,文件名不匹配导致加载的任务无效。将entrypoint.sh中的路径改为正确的/etc/cron.d/my-user-job。确保crond服务启动
当前entrypoint.sh仅加载了crontab任务,但未启动crond守护进程,这是任务不执行的核心原因。修改entrypoint.sh,在加载任务后启动crond:#!/bin/bash echo "Start cron" # 加载正确的任务文件 crontab /etc/cron.d/my-user-job # 启动crond服务,前台运行避免进程退出 crond -n & echo "cron started" # 保持容器运行 tail -f /dev/null或者直接将crond作为主进程运行,替换tail命令:
#!/bin/bash echo "Start cron" crontab /etc/cron.d/my-user-job echo "cron started" # 以前台模式启动crond,作为容器主进程 exec crond -n检查任务执行权限
确认/opt/my-user/ETLJob/ETLJob_run.sh有可执行权限(已在Dockerfile中设置chmod +x,可进入容器手动验证:ls -l /opt/my-user/ETLJob/ETLJob_run.sh);同时确保/opt/my-user/joblogs/目录对my-user有写入权限(可验证:touch /opt/my-user/joblogs/test.log看是否报错)。查看cron日志排查问题
cronie的日志默认输出到syslog,可修改entrypoint.sh将日志重定向到文件,方便排查:#!/bin/bash echo "Start cron" crontab /etc/cron.d/my-user-job # 启动crond并将日志输出到指定文件 crond -n >> /opt/my-user/joblogs/cron.log 2>&1 & echo "cron started" tail -f /dev/null等待任务执行周期后,查看
/opt/my-user/joblogs/cron.log和job.log,检查是否有错误信息(比如脚本路径错误、依赖缺失等)。验证cron任务格式
确保crontab任务格式正确:*/2 * * * *代表每2分钟执行一次,后面的命令路径使用绝对路径,重定向语法>> /opt/my-user/joblogs/job.log 2>&1已正确将标准输出和错误输出写入日志。
内容的提问来源于stack exchange,提问作者Angelo Immediata

