【问题标题】:Output of `tail -f` at the end of a docker CMD is not showingdocker CMD 末尾的“tail -f”输出未显示
【发布时间】:2017-05-05 10:04:37
【问题描述】:

将 Docker for Mac 1.13.1 与以下 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文件:

* * * * * 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 输出不会出现。然而,如果我登录到正在运行的容器并尾随文件,我可以看到内容:

$ 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 末尾添加另一个 echo 以查看它是否只是 STDOUT 被吞下的最后一个命令,但这没有帮助。

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

谢谢!

【问题讨论】:

  • 使用exec 运行您的主程序(尾部),否则它不会收到 Ctrl-C(退出)信号。这也可能解决您的问题。 && exec tail -f ..

标签: docker dockerfile


【解决方案1】:

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

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

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

【讨论】:

  • 迫不及待想试试这个。它可以解释我看到的很多奇怪的错误。
  • 我在发布之前提取了 repo 并进行了测试。我的第一个怀疑是输出缓冲,但stdbuf 没有修复它。经ls -il /var/log/cron.log 验证,它在第一次写入后获得了新的 inode。
  • 这个技巧对我有用。您也可以使用touch /var/log/cron.log 代替: >> /var/log/cron.log
  • BMitch,先生,你真棒!
【解决方案2】:

尝试使用音量:

VOLUME /var/log/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-29
    • 2011-02-25
    相关资源
    最近更新 更多