docker CMD 末尾的“tail -f"输出未显示 [英] Output of `tail -f` at the end of a docker CMD is not showing
问题描述
将 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屋!