使用 Filebeat 收集 Docker 容器日志
问题:开发人员查看测试环境或者生产环境的日志非常不方便,因为我们服务都是用 Docker 部署的,所以开发人员需要先登录到服务器,然后再登录到某个 Docker 容器才能看到日志。
解决办法:搭建一套日志可视化环境,让开发人员可以通过浏览器直接查看系统各个服务的日志。下面介绍一下如何使用 Filebeat 来收集 Docker 容器日志,并将日志存入 Elasticsearch,再通过 Kibana 来展示。
Filebeat vs. LogStash
Filebeat 是Elastic
公司的一个轻量型日志采集器,它可以用来代替该公司旗下的 Logstash,也可以和 Logstash 配合一起使用。
Filebeat 和 LogStash 相比十分轻量,体积只有 30 多 M,占用的资源较低,安装也比较简单,可以在每个需要收集日志的服务器上部署运行。
Filebeat 将更多能力放在了数据收集
上面,而 Logstash 更多的能力是体现在数据的过滤
和转换
上。
EFK 安装
ElasticSearch 和 Kibana 的安装比较简单,可以直接用 Docker 安装的方式,但要注意 Elasticsearch 和 Kibana 的版本需要保持一致,不然 Kibana 可能启动不起来。
Filebeat 的安装方式有多种,可以直接下载安装程序安装,也可以通过 Docker 方式安装,命令如下:
1 | docker run -d \ |
注意这里映射了 Filebeat 配置文件的路径,同时映射了 Docker 容器的文件路径。
也可以使用 Docker-compose 来启动 Filebeat:
1 | filebeat: |
基于 Docker 的 Filebeat 配置
使用官方推荐的这个配置模板就够了,我们对 Filebeat 的配置主要体现在具体的容器上,而不是 Filebeat 本身。
1 | # 使用这个命令下载 filebeat 配置文件 |
配置文件内容是这样:
1 | filebeat.config: |
过滤不需要收集日志的 Docker 容器
按照我们上面的方式启动 Filebeat 后,Filebeat 会自动收集机器上所有 Docker 容器的日志,包括 Elasticsearch,Kibana,Filebeat 这些工具容器的日志,但这些日志可能不是我们所关心的,我们不想让 Filebeat 收集这些容器的日志。
Filebeat 提供了一些 Docker 标签(Label),可以让 Docker 容器在 Filebeat 的autodiscover
阶段对日志进行过滤和加工,其中有个标签就是可以让某个容器的日志不进入 Filebeat:
- co.elastic.logs/enabled: 日志收集功能是否启动标志,默认值为
true
,设为false
即为不收集日志。
可以在docker run
的时候加上这个参数:
1 | docker run --label co.elastic.logs/enabled=false ... |
如果你是用 Docker-compose 启动的话,可以这样写:
1 | filebeat: |
当然更好的方法是在 Filebeat 的配置文件里面配置需要收集日志的容器,但试了几次没找到可以让配置生效的写法,如果有人知道如何配置,也请留言告知,谢谢。
统一收集容器中其他路径的日志
Filebeat 默认收集的是 Docker 容器启动后输出到docker logs
的日志,但有些服务除了这些日志外,还会把其他日志存放到容器的里面。比如egg.js
框架会把错误日志和一些 web 日志放到/root/logs/yourserver/
下面。那么要如何收集这些额外的日志呢?
解决方法是把额外日志的路径映射到 Docker 的输出控制台,我们可以在 Dockerfile 里面这样设置:
1 | # 将普通日志输出到 stdout |
这样容器启动后就会将容器里日志传输到控制台上,而 Filebeat 也就可以收集该日志了。
解决多行日志问题
Filebeat 收集日志后将其存入到 Elasticsearch,默认的存储规则是一行日志作为 Elasticsearch 的一条记录,但像错误信息这种日志会出现多行的情况,如果同一个日志分成多行的话查看起来就不太方便,因为中间可能被其他日志打断,而且搜索的时候也不能把同一个错误的日志一并查询出来,所以最好的方式是能将同一个错误的多行日志存入 Elasticsearch 的同一条记录。
Filebeat 考虑到了这种情况,让我们可以通过添加容器便签的方式来设置多行日志的整合规则,比如我们的每条日志都是以时间格式开始的:2019-01-01 11:11:11,1111 xxxx
,那么我们的多行设置规则就可以这样写:
1 | web-server-dev: |
其中 pattern 表示日志内容如果不匹配这个正则表达式则不能作为新的一行日志,这样日志就会按照时间进行分组了。
Kibana 建立对应服务的搜索
Filebeat 将日志存入到 Elasticsearch 后,我们就可以通过 Kibana 来查看日志了。在 Kibana 中创建以filebeat-*
开头的索引,表示查询以filebeat
开头的索引,这是 Filebeat 导入日志的索引,每天会产生这样的一个索引。
创建完索引后可以通过一些 Docker 的查询条件来查询日志,比如想查询容器名为foo
的容器的日志,就可以用container.name=foo
这样的过滤条件来查询,如果想以镜像名来查询也可以,用image.name=xxx
的查询条件就可以查询出该镜像的所有容器的日志。
展示字段一般只需要message
字段就可以了,也可以视情况添加container.name
或image.name
等字段。
总结
上面介绍的 Filebeat 官方推荐的一种收集 Docker 容器的方法,其实还有其他方案,比如说在每个容器里面安装一个 Filebeat 客户端来分别收集各自服务的日志,或者是把每个 Docker 容器的日志路径都映射到宿主机上的某个目录下面,然后在宿主机上安装一个 Filebeat 客户端来统一收集。如果您还有更好的方案,希望可以留言一起讨论分享,谢谢。