docker CMD 末尾的“tail -f"输出未显示 [英] Output of `tail -f` at the end of a docker CMD is not showing

查看:70
本文介绍了docker CMD 末尾的“tail -f"输出未显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

将 Docker for Mac 1.13.1 与以下 Dockerfile 一起使用:

Using Docker for Mac 1.13.1 with the following Dockerfile:

FROM ubuntu:latest
MAINTAINER docker@ekito.fr

#Install packages and clean downloaded packages in the lowest layer
RUN apt-get update && apt-get -y install cron && rm -rf /var/lib/apt/lists/*

# Add crontab file in the cron directory
ADD crontab /etc/cron.d/hello-cron

# Give execution rights on the cron job and create the log file to tail in the next layer
RUN chmod 0644 /etc/cron.d/hello-cron && touch /var/log/cron.log

# Run the command on container startup
CMD echo "starting" && echo "continuing" && (cron) && echo "tailing..."  && tail -f /var/log/cron.log

带有一个contab文件:

With a contab file of:

* * * * * root echo "Hello world `date`" >> /var/log/cron.log 2>&1
# Don't remove the empty line at the end of this file. It is required to run the cron job

当我构建和运行它时:

docker build -t docker-cron-master .
docker run docker-cron-master

我看到了输出:

docker run docker-cron-master
starting
continuing
tailing...

如果我稍等片刻,tail -f 输出不会出现.然而,如果我登录到正在运行的容器并跟踪文件,我可以看到内容:

If I wait a minute the tail -f output doesn't appear. Yet if I login to the running container and tail the file I can see the contents:

$ docker exec -it 4eda6b1fc6ce bash
root@4eda6b1fc6ce:/# tail -f /var/log/cron.log
Hello world Fri May  5 09:53:01 UTC 2017
Hello world Fri May  5 09:54:01 UTC 2017

我尝试在 CMD 末尾添加另一个回显,以查看是否只有最后一个命令吞噬了 STDOUT,但这没有帮助.

I tried adding another echo at the end of the CMD to see if it was only the last command who's STDOUT was being swallowed but that didn't help.

我在 github 上发布了代码 https://github.com/simbo1905/docker-cron

I have posted the code is on github at https://github.com/simbo1905/docker-cron

谢谢!

推荐答案

docker文件系统使用copy-on-write和它的layered union fs.因此,当您写入作为镜像一部分的文件时,它会首先将该文件复制到容器文件系统,容器文件系统是所有镜像层之上的一层.

The docker filesystem uses copy-on-write with it's layered union fs. So when you write to a file that's part of the image, it will first make a copy of that file to the container filesystem which is a layer above all the image layers.

这意味着当您在/var/log/cron.log 中附加一行时,它将在文件系统中获得一个新的 inode,而 tail 命令所遵循的文件是不再是您在 docker exec 进入容器时看到的那个.您可以通过将无"附加到文件中来解决这个问题,这也修改了强制写入时复制的最后更新时间戳:

What that means is when you append a line to the /var/log/cron.log, it will get a new inode in the filesystem and the file that the tail command is following at is no longer the one you see when you docker exec into the container. You can solve that with a minor change to append "nothing" to the file which also modifies the last update timestamp which forces a copy-on-write:

CMD echo "starting" && echo "continuing" && (cron) 
 && echo "tailing..." && : >> /var/log/cron.log && tail -f /var/log/cron.log

我在这里整理了一个包含更多细节的要点:https://gist.github.com/sudo-bmitch/f91a943174d6aff5a57904485670a9eb

I put together a gist that goes through this issue with a lot more detail over here: https://gist.github.com/sudo-bmitch/f91a943174d6aff5a57904485670a9eb

这篇关于docker CMD 末尾的“tail -f"输出未显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆