如何在Ubuntu16.04上使用Fluentd和ElasticSearch集中您的Docker日志

来自菜鸟教程
跳转至:导航、​搜索

Fluentd 的一篇文章

介绍

当您将 Docker 容器投入生产时,您会发现越来越需要将日志保存在比容器更短暂的地方。 Docker 带有用于 Fluentd 的本机日志记录驱动程序,可以轻松收集这些日志并将它们路由到其他地方,例如 Elasticsearch,因此您可以分析数据。

Fluentd 是一个开源数据收集器,旨在统一您的日志基础设施。 它通过使收集和存储日志变得简单且可扩展,将操作工程师、应用程序工程师和数据工程师聚集在一起。

Fluentd 有四个关键特性,使其适合构建干净、可靠的日志管道:

  • 使用 JSON 进行统一日志记录: Fluentd 尝试尽可能地将数据结构化为 JSON。 这允许 Fluentd 统一处理日志数据的所有方面:收集、过滤、缓冲和输出跨多个源和目标的日志。 使用 JSON 进行下游数据处理要容易得多,因为它有足够的结构可以访问,而无需强制使用严格的模式。
  • Pluggable Architecture: Fluentd 有一个灵活的插件系统,允许社区扩展其功能。 超过 300 个社区贡献的插件将数十个数据源连接到数十个数据输出,根据需要操纵数据。 通过使用插件,您可以立即更好地利用日志。
  • 最少资源需求: 数据收集器应该是轻量级的,这样它才能在繁忙的机器上舒适地运行。 Fluentd 是结合 C 和 Ruby 编写的,并且需要最少的系统资源。 vanilla 实例在 30-40MB 内存上运行,可以处理 13,000 个事件/秒/核心。
  • 内置可靠性: 永远不会发生数据丢失。 Fluentd 支持基于内存和文件的缓冲,以防止节点间数据丢失。 Fluentd 还支持强大的故障转移,并且可以设置为高可用性。

在本教程中,您将学习如何安装 Fluentd 并将其配置为从 Docker 容器收集日志。 然后,您会将数据流式传输到在同一 Ubuntu 16.04 服务器上运行 Elasticsearch 的另一个容器并查询日志。

先决条件

要完成本教程,您将需要以下内容:

  • 按照 Ubuntu 16.04 初始服务器设置指南 设置一台 4GB Ubuntu 16.04 服务器,包括 sudo 非 root 用户和防火墙。 这满足了 Elasticsearch 的内存需求。
  • 按照 如何在 Ubuntu 16.04 上安装和使用 Docker 将 Docker 安装在您的服务器上。 请务必将 Docker 配置为以非 root 用户身份运行。

第 1 步 — 安装 Fluentd

安装 Fluentd 最常见的方法是通过 td-agent 包。 Treasure Data,Fluentd 的原作者,将 Fluentd 与自包含的 Ruby 运行时打包,因此您无需设置 Ruby 环境即可运行 Fluentd。 他们还提供了一个脚本来获取最新的 td-agent 包,该包配置存储库并为您安装包。

以非 root 用户身份登录您的服务器:

ssh sammy@your_server_ip

然后使用Treasure Data提供的脚本安装td-agent。 首先,下载脚本:

\curl -L http://toolbelt.treasuredata.com/sh/install-ubuntu-xenial-td-agent2.sh -o install-td-agent.sh

如果要审核脚本,请使用文本编辑器打开它:

nano install-td-agent.sh

熟悉脚本内容后,运行脚本安装 td-agent

sh install-td-agent.sh 

安装完成后,启动 td-agent

sudo systemctl start td-agent

检查日志以确保它已成功安装:

tail /var/log/td-agent/td-agent.log

您将看到类似于以下内容的输出:

Output    port 8888
  </source>
  <source>
    @type debug_agent
    bind 127.0.0.1
    port 24230
  </source>
</ROOT>
2016-12-02 19:45:31 +0000 [info]: listening fluent socket on 0.0.0.0:24224
2016-12-02 19:45:31 +0000 [info]: listening dRuby uri="druby://127.0.0.1:24230" object="Engine"

接下来,使用 td-agent-gem 命令为 Fluentd 安装 Elasticsearch 插件:

sudo td-agent-gem install fluent-plugin-elasticsearch

注意: 或者,Fluentd 可以作为 Ruby gem 使用,并且可以与 gem install fluentd 一起安装。 如果您已经配置了 Ruby 环境,则可以使用 gem 命令安装 Fluentd 和 Elasticsearch 插件:

gem install fluentd --no-rdoc --no-ri
gem install fluentd-plugin-elasticsearch --no-rdoc --no-ri

Fluentd 现在以默认配置启动并运行。 接下来,我们将配置 Fluentd,以便我们可以侦听 Docker 事件并将它们传送到 Elasticsearch 实例。

第 2 步 — 配置 Fluentd

Fluentd 需要知道从哪里收集信息,以及从哪里传递信息。 您可以在位于 /etc/td-agent/td-agent.conf 的 Fluentd 配置文件中定义这些规则。

在文本编辑器中打开此文件:

sudo nano /etc/td-agent/td-agent.conf 

删除文件的内容。 在本教程中,您将从头开始编写自己的规则。

您在 source 部分中定义信息源。 将此配置添加到文件中:

/etc/td-agent/td-agent.conf

<source>
  @type forward
  port  24224
</source>

这将源定义为 forward,它是运行在 TCP 之上的 Fluentd 协议,在将日志发送到 Fluentd 时将由 Docker 使用。

当日志记录进来时,它们会有一些额外的关联字段,包括timetagmessagecontainer_id等等。 您使用 _tag_ 字段中的信息来决定 Fluentd 应该将数据发送到哪里。 这称为 数据路由

要对此进行配置,请定义一个与 tag 字段的内容匹配的 match 部分,并对其进行适当的路由。 将此配置添加到文件中:

/etc/td-agent/td-agent.conf

<match docker.**>
  @type elasticsearch
  logstash_format true
  host 127.0.0.1
  port 9200
  flush_interval 5s
</match>

该规则表示,带有前缀为 docker. 的标签的每条记录都将被发送到 Elasticsearch,它在端口 9200 上的 127.0.0.1 上运行。 flush_interval 告诉 Fluentd 它应该多久记录一次 Elasticsearch。

有关缓冲和刷新的更多详细信息,请参阅 缓冲插件 概述文档部分。


保存新配置文件后,重新启动 td-agent 服务以应用更改:

sudo systemctl restart td-agent

现在 Fluentd 已为我们的目的正确配置,让我们安装 Elasticsearch 以从 Fluentd 捕获我们的日志。

第 3 步 — 启动 Elasticsearch 容器

我们将使用 Docker 来运行我们的 Elasticsearch 实例,因为它比我们自己配置一个更快。 我们将使用 Elasticsearch Docker 映像 来创建我们的容器。 要使用此映像,请在 Docker 主机上增加 max_map_count 的值,如下所示:

sudo sysctl -w vm.max_map_count=262144

然后执行以下命令下载 Elasticsearch 镜像并启动容器:

docker run -d -p 9200:9200 -p 9300:9300 elasticsearch

图像将下载,Elasticsearch 容器将启动。 通过检查 Docker 进程并查找容器来确保容器正常运行:

docker ps

你应该看到这样的输出:

OutputCONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                                            NAMES
76e96943491f        elasticsearch       "/docker-entrypoint.s"   About a minute ago   Up 51 seconds       0.0.0.0:9200->9200/tcp, 0.0.0.0:9300->9300/tcp   gigantic_hawking

如果未列出容器,请在不使用 -d 开关的情况下再次启动它,以便容器在前台运行。 运行命令 docker run -p 9200:9200 -p 9300:9300 elasticsearch 并查找任何特定的错误消息。 您最可能遇到的错误是系统内存不足,或者 Docker 主机上的 max_map_count 值太低。 检查本教程中的所有步骤以确保您没有遗漏任何内容,然后重试。

现在 Elasticsearch 在容器中运行,让我们生成一些日志并将它们摄取到 Fluentd 中。

第 4 步 — 从 Docker 容器生成日志

使用 Docker,您可以通过标准输出 (STDOUT) 和错误 (STDERR) 接口将日志视为数据流。 当您启动 Docker 应用程序时,只需指示 Docker 使用本机 Fluentd 日志记录驱动程序刷新日志。 Fluentd 服务将接收日志并将它们发送到 Elasticsearch。

通过在 Docker 容器中启动 Bash 命令来测试这一点,如下所示:

docker run --log-driver=fluentd ubuntu /bin/echo 'Hello world'

这会将消息 Hello world 打印到标准输出,但它也会被 Docker Fluentd 驱动程序捕获并传递到您之前配置的 Fluentd 服务。 大约五秒钟后,记录将被刷新到 Elasticsearch。 您在 Fluentd 配置文件的 match 部分中配置了此间隔。

这足以将日志传输到 Elasticsearch,但您可能需要查看 官方文档 以了解有关可用于 Docker 来管理 Fluentd 驱动程序的选项的更多详细信息。

最后,让我们确认 Elasticsearch 正在接收事件。 使用 curl 向 Elasticsearch 发送查询:

curl -XGET 'http://localhost:9200/_all/_search?q=*'

输出将包含如下所示的事件:

{"took":2,"timed_out":false,"_shards":{"total":1,"successful":1,"failed":0},"hits":{"total":1,"max_score":1.0,"hits":[{"_index":"logstash-2016.12.02","_type":"fluentd","_id":"AVQwUi-UHBhoWtOFQKVx","_score":1.0,"_source":{"container_id":"d16af3ad3f0d361a1764e9a63c6de92d8d083dcc502cd904155e217f0297e525","container_name":"/nostalgic_torvalds","source":"stdout","log":"Hello world","@timestamp":"2016-12-02T14:59:26-06:00"}}]}}

根据您的设置,您可能会记录很多事件。 单个事件应以 {"took": 开头并以时间戳结束。 它还将包含一些与源容器相关的额外信息。 如该输出所示,Elasticsearch 正在从我们的 Docker 容器接收数据。

结论

从 Docker 容器收集日志只是使用 Fluentd 的一种方式。 许多用户来到 Fluentd 是为了构建一个日志管道,该管道既可以进行实时日志搜索,也可以进行长期存储。 这种架构利用了 Fluentd 复制数据流并将其输出到多个存储系统的能力。 例如,您可以使用 Elasticsearch 进行实时搜索,但使用 MongoDB 或 Hadoop 进行批量分析和长期存储。

Web 应用程序会产生大量的日志,并且它们通常被任意格式化并存储在本地文件系统中。 由于两个原因,这可能会出现问题。 首先,日志难以以编程方式解析,需要大量 正则表达式 ,因此对于希望通过统计分析、查看 A/B 测试结果或执行操作来了解用户行为的人来说,不太容易获得欺诈识别。

其次,由于文本日志被批量加载到存储系统中,因此无法实时访问日志。 更糟糕的是,如果服务器的磁盘在批量加载之间损坏,日志就会丢失或损坏。

Fluentd 通过为各种编程语言提供具有一致 API 的记录器库来解决这两个问题。 每个记录器都会向 Fluentd 发送包含时间戳、标签和 JSON 格式事件的记录,就像您在本教程中看到的那样。 有用于 Ruby、Node.js、Go、Python、Perl、PHP、Java 和 C++ 的 logger 库。 这让应用程序“一劳永逸”; 记录器将数据异步发送到 Fluentd,Fluentd 依次缓冲日志,然后将它们发送到后端系统。

您可以使用 Fluentd 和 Elasticsearch 做很多其他有用的事情。 您可能会发现以下链接很有趣: