1. 背景
如今越来越多的产品采用微服务架构,整个系统会被拆分成若干个服务,然后可被独立部署到不同的服务器上,服务分散在不同的环境中给团队开发和运维会带来如下常见问题:
- 开发人员通常无生产环境服务器权限,当生产环境出现故障,开发人员很难及时查看到相应服务的日志;
- 服务日志分散在多个服务器上,查询起来非常不方便;
- 日志通常以文件的形式保存于各服务器上,缺乏快速检索日志的机制;
- 当系统越来越庞大,我们希望能够对日志文件进行分析处理,实现智能化运维,但是缺乏方便的日志获取机制。
ELK Stack是一套开源的集中式日志解决方案,能够以非常低成本的方式满足我们上面的需求。ELK并不是一款软件,而是一整套工具集,包含ElasticSearch,LogStash,Kibana,还有新加入的Beats。
- ElasticSearch:分布式搜索引擎,基于Apache Lucene构建,能对大规模的数据进行存储、检索以及分析。
- Kibana:数据可视化平台,通常与ElasticSearch集成,能够对ElasticSearch中的数据进行检索及可视化展示。
- LogStash:作为数据处理管道,支持对不同来源数据进行采集、过滤、分析处理等操作,然后输出到多种不同的存储介质中去实现持久化。
- Beats:轻量级的专用数据收集器,其对宿主环境的资源消耗几乎可忽略不计,支持对多种不同来源的数据进行采集,包含Filebeat,Metricbeat,Packetbeat,Heartbeat等。
2. ELK架构
最简单的ELK架构使用LogStash,ElasticSearch,Kibana即可搭建,如下图所示。
该架构直接使用LogStash通过其输入插件如Stdin或日志文件等获取数据,然后经过数据处理后写入到ElasticSearch中进行存储,最后通过Kibana进行数据展示。
此种架构需要将LogStash部署到环境中的各业务节点上,但是LogStash组件的运行本身需要占用较多的CPU和内存资源,很容易对正常业务造成影响,因此出现了非常轻量级的数据采集器Beats,其相对于LogStash占用的系统资源几乎不计。Beats当前支持对多种数据进行采集,如Filebeat用于搜集文件中的数据,Packetbeat用于搜集网络流中数据等。
引入Beats之后的架构如下,使用Beats组件对数据进行采集,对接LogStash流水线中的输入插件,然后数据在经过分析过滤之后通过输出插件写入ElasticSearch,最后通过Kibana对数据进行展示。
当系统业务负载突然变大时会产生大规模的日志数据流,在LogStash流水线中的各分析过滤插件往往会形成瓶颈造成阻塞,此时我们可以在Beats和LogStash之间引入消息队列,以达到削峰填谷的作用。
此时的ELK架构如下图所示,分布在各服务节点上的Beats采集数据之后写入到消息队列中,当前Beats支持的消息队列包含常见的如Kafka,RabbitMQ,Redis等,然后LogStash通过输入插件获取到数据流,经过分析过滤插件处理之后写入到ElasticSearch中进行存储,最后再通过Kibana实现数据的可视化。
3. 快速搭建
这里我们使用Docker快速搭建一套ELK系统,用于搜集位于各Linux系统上面的业务日志。这里为了方便,消息队列占时不引入,具体引入方法可参考官方文档在配置文件中引入相应的数据输入输出插件即可实现。ELK各组件官方均提供了Docker镜像,可在这里查看并使用docker pull下载,国内下载速度可能会比较慢。
3.1 ElasticSearch
在安装ElasticSearch之前需要进行一下系统设置,在/etc/sysctl.conf文件末尾加上vm.max_map_count=655360
,然后使用命令sysctl -p
刷新一下,否则启动ElasticSearch可能会出现max virtual memory areas vm.max_map_count [65530] likely too low, increase to at least [262144]
错误。
在系统目录中创建/root/elasticsearch/data和/root/elasticsearch/logs文件夹,分别用于对ElasticSearch的数据和日志进行持久化,另外使用命令chmod 775 /root/elasticsearch/*
设置一下两个文件夹的读写权限,最后运行如下命令启动ElasticSearch服务。
# docker run -d --name elasticsearch --user root -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -e ELASTICSEARCH_USERNAME=admin -e ELASTICSEARCH_PASSWORD=admin@123 -v /root/elasticsearch/data/:/usr/share/elasticsearch/data/ -v /root/elasticsearch/logs/:/usr/share/elasticsearch/logs/ docker.elastic.co/elasticsearch/elasticsearch:6.5.2
ElasticSearch服务启动之后我们可以访问如下API验证是否启动成功。
# curl -XGET http://192.168.1.6:9200/_search
{"took":0,"timed_out":false,"_shards":{"total":0,"successful":0,"skipped":0,"failed":0},"hits":{"total":0,"max_score":0.0,"hits":[]}}
3.2 Kibana
服务启动命令如下:
# docker run -d --name kibana -p 5601:5601 -e ELASTICSEARCH_URL=http://192.168.1.6:9200 docker.elastic.co/kibana/kibana:6.5.2
Kibana服务启动之前需要先启动ElasticSearch,启动Kibana时需要配置ElasticSearch数据库地址。启动完成之后通过 http://192.168.1.6:5601 即可访问Kibana界面。
3.3 LogStash
在启动LogStash之前在目录/root/logstash下创建logstash.conf文件作为LogStash服务的配置文件,内容如下:
input {
beats {
port => "5044"
}
}
#filter {
# grok {
# match => { "message" => "%{TIMESTAMP_ISO8601:timestamp} %{LOGLEVEL:level} %{JAVALOGMESSAGE:msg}"
# }
#}
output {
elasticsearch {
hosts => ["192.168.1.6:9200"]
}
}
然后运行如下命令启动LogStash。
# docker run -d --name logstash -p 5044:5044 --link elasticsearch -v /root/logstash/logstash.conf:/usr/share/logstash/pipeline/logstash.conf docker.elastic.co/logstash/logstash:6.5.2
3.4 Filebeat
在/root/filebeat目录下面创建/data文件夹和filebeat.yml文件,分别用于存储filebeat数据采集状态以及filebeat配置文件。在filebeat.yml文件中添加如下内容:
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/test.log
output.logstash:
hosts: ["192.168.1.6:5044"]
然后使用如下命令启动Filebeat进行日志数据采集。
# docker run -d --name filebeat --user root -v /root/filebeat/data/:/usr/share/filebeat/data/ -v /root/filebeat/filebeat.yaml:/usr/share/filebeat/filebeat.yml -v /var/log/:/var/log/ docker.elastic.co/beats/filebeat:6.5.2
4. 简单使用
当所有服务搭建起来之后,我们就可以访问 http://kibana_host:5601 Kibana界面了。具体的使用说明参考官方文档。