Docker Swarm下Airflow定时任务容器保活与日志留存问题求助
解决思路
临时无重启方案
针对当前已运行的容器,通过修改Airflow执行命令的输出重定向,让任务日志进入Docker日志流:
- 将Airflow中的
main_command修改为:
容器内的main_command = f"docker exec {container_name} .venv/bin/python main.py >> /proc/1/fd/1 2>> /proc/1/fd/2"/proc/1/fd/1和/proc/1/fd/2对应PID1进程的标准输出和错误输出,也就是Docker日志捕获的流。任务的所有输出会被重定向到这里,直接出现在docker logs中。
长期部署优化方案
如果可以调整Docker Swarm服务的启动命令,从根源解决日志捕获问题:
方案1:使用管道作为日志中转
修改容器启动命令为:
mkfifo /var/log/task_pipe && tail -f /var/log/task_pipe
同时将Airflow的执行命令改为:
main_command = f"docker exec {container_name} .venv/bin/python main.py > /var/log/task_pipe 2>&1"
PID1进程是监听管道的tail,所有写入管道的任务输出都会被它捕获并输出到Docker日志中。
方案2:使用轻量init进程管理输出
在Dockerfile中添加tini(轻量init进程):
RUN apt-get update && apt-get install -y tini ENTRYPOINT ["tini", "-g", "--"] CMD ["tail", "-f", "/dev/null"]
tini作为PID1会统一管理容器内的进程组,配合临时方案的输出重定向命令,既能确保任务日志进入Docker日志流,还能解决僵尸进程问题。
方案3:替换保活命令为bash循环
将容器启动命令改为:
bash -c "while true; do sleep 86400; done"
这个命令作为PID1时,搭配临时方案的输出重定向,同样可以让任务日志进入Docker日志,同时比tail -f /dev/null更稳定。
内容的提问来源于stack exchange,提问作者Quoc Bao
相关产品推荐
相关产品推荐

