英文原文:Top 10 Docker Logging Gotchas
Docker 不仅改变了应用程序的部署方式,还改变了日志管理的工作流程。容器不但无需将日志写入文件,反而是将日志写入控制台(stdout / stderr),然后 Docker Logging Drivers 将日志转发到目标。针对 Docker GitHub 问题的检查很快会显示用户在处理 Docker 日志时遇到各种问题。使用 Docker 管理日志貌似有点棘手,且需要深入理解 Docker Logging Driver 的实现和替代方法,以解决报告的问题。
那么,Docker 日志的十大陷阱是什么?
首先,让我们从 Docker Logging Drivers 和选项的概述开始,将日志发送到集中式日志管理解决方案,如 Elastic Stack(前身 ELK Stack)或 Sematext Cloud。
在 Docker 的早期,容器日志只能通过 Docker 远程 API,即通过“docker logs”命令和一些高级的日志传送工具才能使用。之后,Docker 引入日志驱动程序作为插件,以打开 Docker 与各种日志管理工具进行集成。这些日志驱动程序是作为 docker 守护进程中的二进制插件实现的。最近,插件体系结构得到了扩展,以便于运行日志驱动程序作为外部进程,不但可以注册为插件,还可以通过 Unix 套接字检索日志。目前,Docker 二进制文件附带的日志记录驱动程序是二进制插件,但在不久的将来可能会发生变化。
Docker Logging Drivers 接收容器日志并将其转发到远程目标或文件。默认的日志驱动程序是“json-file”。它在本地磁盘上以 JSON 格式存储容器日志。Docker 有一个用于日志记录驱动程序的插件体系结构,所以有插件可用于开源工具和商业工具:
对于完整的日志管理解决方案,需要包含附加工具:
日志解析器来构造日志,通常是日志传送工具(fluentd,rsyslog,logstash,logagent 等)的一部分
日志索引,可视化和警报:
为了将日志发送到其中一个后端,你可能需要选择一个支持所选日志管理解决方案的日志驱动程序或日志记录工具。如果你的工具需要 Syslog 输入,则可以选择 Syslog 驱动程序。
Docker 日志的十大陷阱
1. Docker 日志命令只在使用 json-file 日志驱动程序时可工作
默认的日志驱动程序“json-file”将日志写入本地磁盘,而 json-file 驱动程序是唯一与“docker logs”命令并行工作的驱动程序。只要有人使用替代日志驱动程序,例如 Syslog,Gelf 或 Splunk,则 Docker 日志 API 调用就会失败,而“docker logs”命令将显示报告限制的错误,而不是在控制台上显示日志。docker log 命令不仅会失败,而且很多其他使用 Docker API 的日志工具,比如像 Portainer 这样的 Docker 用户界面,或者像 Logspout 这样的日志集合容器,都不能在这种情况下显示容器日志。
请参阅 https://github.com/moby/moby/issues/30887
2. Docker Syslog 驱动程序可以阻止容器部署
使用 Docker Syslog 驱动程序与 TCP 或 TLS 是提供日志的可靠方式。但是,Syslog 日志驱动程序需要在启动容器时建立与 Syslog 服务器的 TCP 连接。如果无法在容器启动时建立此连接,则容器启动失败,并显示错误消息如
docker: Error response from daemon: Failed to initialize logging driver: dial tcp
这意味着暂时的网络问题或高网络延迟可以阻止容器的部署。此外,Syslog 服务器的重新启动可能会将所有通过 TCP / TS 的容器日志记录到中央 Syslog 服务器,这绝对是要避免的情况。
请参阅:https://github.com/docker/docker/issues/21966
3. 当目标关闭时,Docker Syslog 驱动程序会丢失日志
与上面的问题#2 类似,导致日志丢失的原因是 Docker 日志驱动程序在日志无法传递到远程目标时缺少了缓冲磁盘日志的能力。
一个有趣的问题要看:https://github.com/moby/moby/issues/30979
4. Docker 日志驱动程序不支持像 Error Stack Traces 这样的多行日志
当我们考虑日志时,大多数人都会想到简单的单行日志,比如 Nginx 或 Apache 日志。但是,日志也可以跨越多个行。例如,异常跟踪通常跨越多行,因此为了帮助 Logstash 用户,我们分享了如何使用 Logstash 处理堆栈跟踪。在容器世界中情况也不见得好一点,甚至反而更加复杂,因为在容器中运行的所有 app 的日志都被输出到相同的输出——标准输出。难怪看到问题#22920 以“Closed. Don’t care.”结束使得这么多人失望了。幸运的是,像 Sematext Docker Agent 这样的工具可以立即可用地解析多行日志,以及应用自定义的多行模式。
5. Docker 服务日志命令与非 JSON 日志记录驱动程序挂起
虽然 json-files 驱动程序看起来很健壮,但其他日志驱动程序可能仍然会造成 Docker Swarm 模式的麻烦。
请参阅 Github 问题:https://github.com/docker/docker/issues/28793
6. 如果 fluentd 守护进程已经失效并且缓冲区已满,则 Docker 守护进程会崩溃
另一种日志驱动程序在远程目标不可访问时会导致问题的情境——在这种情况下,日志驱动程序会抛出导致 Docker 后台程序崩溃的异常。
7. 在 Splunk 驱动程序失败时,Docker Container 陷入创建状态
如果 Splunk 服务器在容器启动时返回 504,则容器实际上是启动的,但是 Docker 报告容器未能启动。一旦处于这种状态,容器将不再出现在 docker ps 下,并且容器进程不能通过 docker kill 停止。停止该过程的唯一方法是手动 kill。
Github:https://github.com/moby/moby/issues/24376
8. Docker 日志跳过/缺少应用程序日志(journald 驱动程序)
事实证明,这个问题是由 journald 速率限制引起的,当 Docker 为所有正在运行的应用程序创建日志时,需要增加日志速率限制,而由于其速率限制设置,journald 可能会跳过某些日志。所以当你连接 Docker 的时候要注意你的 journald 设置。
9. Gelf 驱动程序问题
Gelf 日志驱动程序缺少 TCP 或 TLS 选项,并且仅支持 UDP,当 UDP 数据包丢失时可能会有丢失日志消息的风险。有些问题报告了使用 GELF 驱动程序进行 DNS 解析/缓存的问题,所以当你的 Graylog 服务器 IP 更改时,你的日志可能会发送到“Nirvana” ——这使用容器部署可能会快速发生。
10. Docker 不支持多个日志驱动程序
将日志存储在本地服务器上并将其发送到远程服务器是很好的。目前,Docker 不支持多个日志驱动程序,所以用户不得不选择单个日志驱动程序。
尽管已经知道了这篇文章中列出的各种问题,但抉择起来依然不是一件易事。
-
译文链接:http://www.codeceo.com/article/10-docker-logging-gotchas.html
翻译作者:码农网 – 小峰