如何将应用程序日志从 Docker 容器转发到 ELK

如何将应用程序日志从 Docker 容器转发到 ELK

我正在尝试在使用多种应用程序技术(Java、Rails 和各种 DB)的环境中集中日志记录。

我们希望开发人员使用 Docker Compose 启动堆栈,但我们希望他们参考中央日志源(ELK)来调试问题,而不是尝试打开 shell 来运行 Docker 容器。

所有应用程序都写入文件系统而不是 STDOUT/STDERR,这会删除与 Docker 日志驱动程序和 logspout 相关的所有选项。

我们所做的是配置容器,让 rsyslog 包含应用程序日志文件,并将其转发到具有 syslog 输入的 logstash。这在将日志从 A 移动到 B 方面是可行的,但基于 syslog 输入在 ELK 中管理多技术日志非常糟糕(例如尝试捕获多条 Java 堆栈跟踪或 MySQL 慢速查询)。

有没有更好的方法可以做到这一点?我是否应该在每个容器中运行 logstash,以便我可以将过滤器和编解码器直接应用于日志文件,这样我就不必依赖 syslog 输入?

是否有某种方法可以将 Docker 日志驱动程序与写入文件系统的应用程序日志文件一起使用?

答案1

Docker 的最新版本支持将“GELF”格式的日志传输到网络端口。Logstash 有一个 GELF 输入。您可以在每个节点上运行 Logstash,并让节点上的所有 Docker 实例转发给它。

作为 Logstash 输入:https://www.elastic.co/guide/en/logstash/current/plugins-inputs-gelf.html

gelf {
}

对于 Docker 输出: https://docs.docker.com/engine/admin/logging/overview/#gelf

$ docker run -dit \
             --log-driver=gelf \
             --log-opt gelf-address=udp://127.0.0.1:12201 \
             alpine sh

(gelf-address 是从容器外部的角度,而不是内部的角度)

答案2

您还可以配置 logstash 来解析各种json 日志文件docker 默认生产。

另一种方法是使用 Kubernetes 中的 Sidecar。

他们提供了一些不同的例子集群日志概念页面。

如何选择应用该概念完全取决于您的需求。

但是,一个简单的概念验证可能会起作用:

  • 创建一个接受传入 syslog 流的 logstash sidecar(例如使用 syslog 输入)
  • 配置所有容器以使用docker的系统日志驱动程序将日志发送到 sidecar。

当然,您也可以设置一个中央 syslog 监听器(例如使用 logstash 或 rsyslog),并且不需要 sidecar 即可完成此操作。

这种方法也与@杰森·马丁建议使用 GELF。

本地 sidecar 的另一个用途可能是创建一个运行 logstash 的容器文件输入,并公开日志卷(例如 /var/log/ 或 /logs)。然后您可以与其他容器共享该卷,以允许它们写入日志(例如 /logs/$INSTANCE_ID/file.log),并让 logstash 解析它们。

最后的设置允许监控文件而不是 STDOUT/STDERR,但您可能必须有自己的日志目录chmod 1777(或有多个这样的附属目录)。

当然,“反向”设置也可以工作(但似乎更难管理/维护):让你的应用程序容器公开一个日志卷,并让 logstash sidecar 读取日志卷的内容。

相关内容