【问题标题】:how container logging works?容器日志记录如何工作?
【发布时间】:2020-04-29 15:28:28
【问题描述】:

我在很多 docker 容器中看到,创建日志文件并像这样记录日志是一种常见的做法

/var/log/container.log
...

tail  -f /var/log/container.log

不知何故,输出似乎是由容器运行时日志驱动程序获取的。所以如果我跑

docker container logs container

这将显示文件container.log的输出

我知道任何容器的最佳做法是登录stdoutstderr,但我不明白为什么第一个选项有效(创建一个文件并在其上运行tail)。是因为tail 的输出被驱动程序日志获取并将其与标准输出的内容合并?

非常感谢您的帮助。 谢谢。

【问题讨论】:

    标签: docker logging kubernetes


    【解决方案1】:

    tail -f 方法并不是真正的最佳实践。

    正如您所注意到的,运行进程并生成日志的正确方法是将其输出直接写入 stdout 和 stderr,docker logs 将捕获它们。您可以配置 Docker 的日志记录层以将它们发送到其他地方;如果您迁移到 Kubernetes 等集群基础架构,您可以配置其日志记录层来捕获日志,而无需修改您的应用程序代码。

    #!/bin/sh
    # I am the script that runs the main container process.
    # Run a single process, as a foreground process; when that
    # process ends, the container exits.
    exec some_server --no-daemon --log-file /dev/stdout
    

    当您看到tail -f 时,它通常看起来像这样:

    #!/bin/sh
    # Start something as a background process.
    something --log-file /var/log/something.log &
    # Hackily keep the container from exiting.
    tail -f /var/log/something.log
    

    主容器进程是tail 进程。当tail退出时,容器会停止,如果你docker stop容器,信号会转到tail。哦,顺便说一句,作为副作用,有一个something 进程正在运行,但如果它失败了,Docker 无法注意到它。尽管如此,由于tail 进程是主进程并且tail -f 将永远不会退出,这会保持容器运行,并且它会使其基于文件的日志对容器的标准输出可见。

    这里另一个有趣的方法是 Docker Hub httpd 映像所做的:它将日志记录设置为指向一个文件,但该文件的默认内容是指向 /dev/stdout 的符号链接。

    RUN mkdir /var/log/something \
     && ln -s /dev/stdout /var/log/something/something.log
    CMD ["something", "--log-file", "/var/log/something/something.log"]
    

    这很有趣,因为默认行为是将内容写入该日志文件,但它实际上是 /dev/stdout 特殊设备,因此它将转到进程的标准输出(主容器进程的)。如果您想在文件中捕获它,您可以将自己的目录绑定到 /var/log/something 上,这将隐藏符号链接。

    【讨论】:

    • 很好的答案,非常感谢大卫。此外,符号链接是一个很好的建议。
    猜你喜欢
    • 1970-01-01
    • 2011-02-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-07-30
    • 2014-10-31
    相关资源
    最近更新 更多