Docker不仅改变了应用程序的部署方式,还改变了日志管理的工作流程。容器将日志写入控制台(stdout / stderr),而Docker Logging Drivers将日志转发到目的地,而不是将日志写入文件。快速检查Docker GitHub问题表明用户在处理Docker日志时遇到各种问题。使用Docker管理日志似乎很棘手,需要更深入了解Docker日志驱动程序实现和替代方案,以克服人们报告的问题。
首先,让我们首先概述Docker日志记录驱动程序和选项,以便将日志发送到集中式日志管理解决方案,如Elastic Stack(前ELK Stack)或Sematext Cloud。
在Docker的早期,容器日志只能通过Docker远程API获得,即通过“docker logs”命令和一些高级日志转发器。后来,Docker将日志驱动程序作为插件引入,打开Docker以与各种日志管理工具集成。这些日志记录驱动程序在docker守护程序中实现为二进制插件。最近,插件体系结构扩展为将外部进程作为外部进程运行,可以注册为插件并通过Unix套接字检索日志。目前,docker二进制文件附带的日志记录驱动程序是二进制插件,但这可能会在不久的将来发生变化。
Docker日志记录驱动程序接收容器日志并将其转发到远程目标或文件。默认日志记录驱动程序是“json-file”。它以本地磁盘上的JSON格式存储容器日志。Docker有一个用于记录驱动程序的插件架构,因此可以使用开源工具和商业工具的插件:
要获得完整的日志管理解决方案,还需要使用其他工具:
要将日志发送到其中一个后端,您可能需要选择支持所选日志管理解决方案的日志记录驱动程序或日志记录工具。如果您的工具需要Syslog输入,则可以选择Syslog驱动程序。
默认的日志记录驱动程序“json-file”将日志写入本地磁盘,json文件驱动程序是唯一与“docker logs”命令并行工作的驱动程序。一旦使用其他日志记录驱动程序,例如Syslog,Gelf或Splunk,Docker日志API调用开始失败,“docker logs”命令显示报告限制的错误,而不是在控制台上显示日志。docker log命令不仅失败,而且使用Docker API进行日志的许多其他工具(如Portainer等Docker用户界面或Logspout等日志收集容器)无法在这种情况下显示容器日志。
请参阅https://github.com/moby/moby/issues/30887
使用带有TCP或TLS的Docker Syslog驱动程序是提供日志的可靠方法。但是,当容器启动时,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
与上面的问题2类似,导致日志丢失的原因是Docker日志记录驱动程序在无法将日志传送到远程目标时缓冲日志的能力。
一个值得关注的有趣问题:https://github.com/moby/moby/issues/30979
当我们考虑日志时,大多数人会想到简单的单行日志,比如Nginx或Apache日志。但是,日志也可以跨越多行。例如,异常跟踪通常跨越多行,因此为了帮助Logstash用户,我们已经共享了如何使用Logstash处理堆栈跟踪。在容器世界中情况并不好,事情变得更加复杂,因为来自容器中运行的所有应用程序的日志都会被发送到同一输出 - 标准输出。难怪看到问题#22920以“已关闭”结束。不在乎。“这么多人都很失望。幸运的是,有一些工具,如Sematext Docker Agent,可以开箱即用解析多行日志,以及应用自定义多行模式。
虽然json文件驱动程序看起来很坚固,但遗憾的是其他日志驱动程序仍然会导致Docker Swarm模式出现问题。
请参阅Github问题:https://github.com/docker/docker/issues/28793
另一种情况是,当远程目标不可访问时,日志记录驱动程序会导致问题 - 在此特定情况下,日志记录驱动程序会抛出导致Docker守护程序崩溃的异常。
如果Splunk服务器在容器启动时返回504,则实际启动容器,但Docker报告容器未能启动。一旦处于此状态,容器不再出现在docker ps下,并且无法使用docker kill停止容器进程。停止该过程的唯一方法是手动终止它。
Github:https://github.com/moby/moby/issues/24376
事实证明,此问题是由记录速率限制引起的,当Docker为所有正在运行的应用程序创建日志时,需要增加该速度限制,并且由于速率限制设置,journald可能会跳过某些日志。因此,当您将Docker连接到它时,请注意您的日记设置。
Gelf日志记录驱动程序缺少TCP或TLS选项,仅支持UDP,这可能会在UDP数据包丢失时丢失日志消息。一些问题报告了使用GELF驱动程序解析DNS /缓存的问题,因此当您的Graylog服务器IP更改时,您的日志可能会被发送到“Nirvana” - 这可能会使用容器部署快速发生。
将日志存储在服务器上的本地以及将它们发送到远程服务器的可能性会很好。目前,Docker不支持多个日志驱动程序,因此用户被迫选择一个日志驱动程序。了解本文中列出的各种问题并非易事。
原文标题《Top 10 Docker Logging Gotchas》
作者:Stefan Thies
译者:February
不代表云加社区观点,更多详情请查看原文链接
本文系外文翻译,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系外文翻译,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。