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

查看:546
本文介绍了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

b
$ b

When I build and run it with:

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文件系统使用分层写入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中添加一行时,它将在文件系统和 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天全站免登陆