前言
调研了ELK技术栈,发现新一代的logstash-forward即Filebeat,使用了golang,性能超logstash,部署简单,占用资源少,可以很方便的和logstash和ES对接,作为日志文件采集组件。所以决定使用ELK+Filebeat的架构进行平台搭建。Filebeat是Beats家族的一员,后续可以使用Packetbeat进行网络数据采集、Winlogbeat进行Windosw事件采集、Heartbeat进行心跳采集、Metricbeat进行系统指标采集。这种架构解决了 Logstash 在各服务器节点上占用系统资源高的问题。相比 Logstash,Beats 所占系统的 CPU 和内存几乎可以忽略不计。另外,Beats 和 Logstash 之间支持 SSL/TLS 加密传输,客户端和服务器双向认证,保证了通信安全。
各组件承担的角色和功能:
- Elasticsearch:分布式搜索和分析引擎,具有高可伸缩、高可靠和易管理等特点。基于 Apache Lucene 构建,能对大容量的数据进行接近实时的存储、搜索和分析操作。通常被用作某些应用的基础搜索引擎,使其具有复杂的搜索功能;
- Logstash:数据处理引擎,它支持动态的从各种数据源搜集数据,并对数据进行过滤、分析、丰富、统一格式等操作,然后存储到 ES;
- Kibana:数据分析和可视化平台。与 Elasticsearch 配合使用,对数据进行搜索、分析和以统计图表的方式展示;
- Filebeat:ELK 协议栈的新成员,一个轻量级开源日志文件数据搜集器,使用 golang 基于 Logstash-Forwarder 源代码开发,是对它的替代。在需要采集日志数据的 server 上安装 Filebeat,并指定日志目录或日志文件后,Filebeat 就能读取数据,迅速发送到 Logstash 进行解析。
ELK 常用架构及使用场景介绍
在这个章节中,我们将介绍几种常用架构及使用场景。
All-In-One
在这种架构中,只有一个 Logstash、Elasticsearch 和 Kibana 实例,集中部署于一台服务器。Logstash 通过输入插件从多种数据源(比如日志文件、标准输入 Stdin 等)获取数据,再经过滤插件加工数据,然后经 Elasticsearch 输出插件输出到 Elasticsearch,通过 Kibana 展示。详见图 1。
这种架构非常简单,使用场景也有限。初学者可以搭建这个架构,了解 ELK 如何工作。
Logstash 分布式采集
这种架构是对上面架构的扩展,把一个 Logstash 数据搜集节点扩展到多个,分布于多台机器,将解析好的数据发送到 Elasticsearch server 进行存储,最后在 Kibana 查询、生成日志报表等。详见图 2。
这种结构因为需要在各个服务器上部署 Logstash,而它比较消耗 CPU 和内存资源,所以比较适合计算资源丰富的服务器,否则容易造成服务器性能下降,甚至可能导致无法正常工作。
Beats 分布式采集
这种架构引入 Beats 作为日志搜集器。目前 Beats 包括四种:
- Packetbeat(搜集网络流量数据);
- Topbeat(搜集系统、进程和文件系统级别的 CPU 和内存使用情况等数据);
- Filebeat(搜集文件数据);
- Winlogbeat(搜集 Windows 事件日志数据)。
Beats 将搜集到的数据发送到 Logstash,经 Logstash 解析、过滤后,将其发送到 Elasticsearch 存储,并由 Kibana 呈现给用户。详见图 3。
这种架构解决了 Logstash 在各服务器节点上占用系统资源高的问题。相比 Logstash,Beats 所占系统的 CPU 和内存几乎可以忽略不计。另外,Beats 和 Logstash 之间支持 SSL/TLS 加密传输,客户端和服务器双向认证,保证了通信安全。
因此这种架构适合对数据安全性要求较高,同时各服务器性能比较敏感的场景。
引入消息队列机制的 Logstash 分布式架构
这种架构使用 Logstash 从各个数据源搜集数据,然后经消息队列输出插件输出到消息队列中。目前 Logstash 支持 Kafka、Redis、RabbitMQ 等常见消息队列。然后 Logstash 通过消息队列输入插件从队列中获取数据,分析过滤后经输出插件发送到 Elasticsearch,最后通过 Kibana 展示。详见图 4。
这种架构适合于日志规模比较庞大的情况。但由于 Logstash 日志解析节点和 Elasticsearch 的负荷比较重,可将他们配置为集群模式,以分担负荷。引入消息队列,均衡了网络传输,从而降低了网络闭塞,尤其是丢失数据的可能性,但依然存在 Logstash 占用系统资源过多的问题。
引入消息队列机制的 Filebeat + Logstash 分布式架构
截至到我们调研为止,Filebeat 已经支持 kafka 作为 ouput,5.2.1 版本的 Logstash 已经支持 Kafka 作为 Input,和上面的架构不同的地方仅在于,把 Logstash 日志搜集发送替换为了 Filebeat。这种架构是当前最为完美的,有极低的客户端采集开销,引入消息队列,均衡了网络传输,从而降低了网络闭塞,尤其是丢失数据的可能性。
对于绿湾的架构选型来说,高质量的数据传输、日志采集的低资源开销都需要考虑,同时,也需要logstash强大的插件支持灵活的日志数据过滤处理。确定采用引入消息队列机制的 Filebeat + Logstash 分布式架构
。
接下来我们进行初步的探视,利用测试环境体验下ELK Stack + Filebeat,测试环境我们就不进行 Kafka 的配置了,因为他的存在意义在于提高可靠性。
测试环境
- CentOS 7.2
- JDK 1.8.0_65
- Filebeat 5.2.1
- Log stash 5.2.1
- ES 5.2.1
- Kibana 5.2.1
机器分布
IP | Role |
---|---|
172.16.134.2 | Logstash, ES, Kibana |
172.16.134.3 | Filebeat |
172.16.134.8 | Filebeat |
浏览器支持
Kibana 4.x 不支持 IE9 及以下;Kibana 3.1 虽然支持 IE9,但是不支持 Safari(iOS)和 Chrome(Android)。具体对浏览器的支持,请看这里。
部署步骤
ELK 官网对于每种软件提供了多种格式的安装包(zip/tar/rpm/DEB),以 Linux 系列系统为例,如果直接下载 RPM,可以通过 rpm -ivh path_of_your_rpm_file
直接安装成系统 service。以后就可以使用 service 命令启停。比如service elasticsearch start/stop/status
。很简单,但缺点也很明显,就是不能自定义安装目录,相关文件放置比较分散。
实际使用中更常用是使用 tar 包安装,每种软件产品的安装过程非常相似。
Step1. SSH免密钥
假设所有步骤都在admin账户下执行,所有服务器的admin账户密码统一,需要打通172.16.134.2至所有agent的SSH免密登录,假设list_all
已经包含了所有agent机器的列表:
172.16.134.2
172.16.134.3
172.16.134.8
进行密钥打通:
ssh-keygen
for agent in `cat list_all`;do ssh-copy-id -i /home/admin/.ssh/id_rsa.pub admin@${agent};done;
Step2. JDK安装
JDK 是 IBM Java 8。ELK 需要 Oracle 1.7(或者是 OpenJDK 1.7) 及以上,如果是 IBM Java,则需要 8 及以上的版本。具体信息。
pssh -h list_all "sudo yum install -y java-1.8.0-openjdk.x86_64"
修改环境变量:
# .bash_profile
# Get the aliases and functions
if [ -f ~/.bashrc ]; then
. ~/.bashrc
fi
# User specific environment and startup programs
JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.65-3.b17.el7.x86_64
PATH=$JAVA_HOME/bin:$PATH
export PATH JAVA_HOME
分发环境变量配置:
pscp -h list_all ~/.bash_profile /tmp
pssh -h list_all "sudo cp /tmp/.bash_profile ~/"
Step3. 服务安装
安装ElasticSearch
下载安装包,如果待安装机器能访问外网,可以直接用以下命令下载安装包。
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.2.1.tar.gz
否则下载好后用 ftp 客户端等工具把包传过去。
解压到172.16.134.2指定目录/home/admin/soft
:
tar zxvf elasticsearch-5.2.1.tar.gz -C /home/admin/soft/
这时就能在 /home/admin/soft
下看到刚才解压出来的 elasticsearch-5.2.1 文件夹。
修改配置config/elasticsearch.yml
:
cluster.name: lw-test
node.name: v134002.yn1.lwsite.net
path.data: /home/admin/soft/elasticsearch-5.2.1/data
path.logs: /home/admin/soft/elasticsearch-5.2.1/logs
network.host: 172.16.134.2
http.port: 9200
Elasticsearch默认使用混合mmapfs / niofs
目录来存储其索引。 对mmap计数的默认操作系统限制可能过低,这可能导致内存不足异常。修改内核参数vm.max_map_count
:
sudo sysctl -w vm.max_map_count=262144
sudo vim /etc/sysctl.conf
vm.max_map_count = 262144
确认内核参数是否生效:
sysctl vm.max_map_count
修改 /etc/security/limits.conf
,添加:
admin soft nofile 65536
admin hard nofile 65536
修改 /etc/security/limits.d/90-nproc.conf
,添加:
admin soft nproc 2048
重新以admin登录后运行:
/home/admin/soft/elasticsearch-5.2.1/bin/elasticsearch &
验证是否启动:
curl 'http://172.16.134.2:9200'
看到如下输出表示启动成功:
{
"name" : "luOq_eh",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "mIcflXKsR3-ER66MCTSJzA",
"version" : {
"number" : "5.2.1",
"build_hash" : "db0d481",
"build_date" : "2017-02-09T22:05:32.386Z",
"build_snapshot" : false,
"lucene_version" : "6.4.1"
},
"tagline" : "You Know, for Search"
}
可以看到,它跟其他的节点的传输端口为9300,接受HTTP请求的端口为9200。
安装ElasticSearch Head (可选)
Head是一个用浏览器跟ES集群交互的插件,可以查看集群状态、集群的doc内容、执行搜索和普通的Rest请求等,本文不复述,这个不是重点。
安装Logstash
下载安装包,如果待安装机器能访问外网,可以直接用以下命令下载安装包。
wget https://artifacts.elastic.co/downloads/logstash/logstash-5.2.1.tar.gz
否则下载好后用 ftp 客户端等工具把包传过去。
解压到172.16.134.2指定目录/home/admin/soft
:
tar -zxvf logstash-5.2.1.tar.gz -C /home/admin/soft
一个Logstash的pipeline由3部分组成:input, filter, output。
为了进行安装完成后的测试,我们运行下最基本的pipeline:
cd logstash-5.2.1
bin/logstash -e 'input { stdin { } } output { stdout {} }'
-e
可以允许进行命令行的直接配置,而无需进行文件配置。这个pipeline例子从标准输入获取数据 stdin
,并把结构化数据输出到标准输出stdout
。在启动后,看到日志Pipeline main started
后,在终端中输入hello world
,可以在终端中看到对应输出:
hello world
2017-02-18T09:48:22.414Z v134002.yn1 hello world
在我们的架构中,Logstash的input是beat,output是ES,需要对应的插件。
安装beat input插件:
./bin/logstash-plugin prepare-offline-pack logstash-input-beats
./bin/logstash-plugin install file:///home/admin/soft/logstash-5.2.1/logstash-offline-plugins-5.2.1.zip
配置 5044 端口作为 Filebeat 的连接和创建 ES 索引。修改 logstash.conf
配置文件,保存在 config
目录:
input {
beats {
port => 5044
}
}
output {
elasticsearch {
hosts => "172.16.134.2:9200"
manage_template => false
index => "%{[@metadata][beat]}-%{+YYYY.MM.dd}"
document_type => "%{[@metadata][type]}"
}
}
Logstash 使用该配置使用 ES 的索引,和 Filebeat 做的事情是一样的,不过拥有了额外的缓存以及强大丰富的插件库。
启动 logstash :
./bin/logstash -f config/logstash.conf &
安装Kibana
Kibana 从 ES 获取数据做前端的可视化展示。 它提供了用户体验极佳的高定制化 UI,可以灵活配置出你需要的 Dashboard。 Dashboard 可以轻易的保存、链接和分享。
测试环境,笔者把 Kibana 和 ES 进行了混部,但是在实际生产环境中是没有必要的。我们可以通过配置文件 config/kibana.yml
中的URL(IP:PORT) 去指定需要访问的 ES 服务端。
curl -L -O https://artifacts.elastic.co/downloads/kibana/kibana-5.2.1-linux-x86_64.tar.gz
tar xzvf kibana-5.2.1-linux-x86_64.tar.gz
cd kibana-5.2.1-linux-x86_64/
./bin/kibana
修改配置 config/kibana.yml
:
elasticsearch.url: "http://172.16.134.2:9200"
server.host: "172.16.134.2"
启动服务:
./bin/kibana &
在浏览器中访问,确认是否正常启动:
http://172.16.134.2:5601/
安装Filebeat
在 172.16.134.3, 172.16.134.8 上进行Filebeat的安装,采集 Filebeat 自身的运行日志:/home/admin/soft/filebeat-5.2.1-linux-x86_64/logs/filebeat
。
在安装之前,需要确认以上服务已经正常运行:
- 存储和索引数据的 Elasticsearch 已经启动。
- UI 展示的 Kibana 已经启动。
- 写入和过滤数据的 Logstash 已经启动。
下载安装包,安装服务:
wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-5.2.1-linux-x86_64.tar.gz
tar zxvf filebeat-5.2.1-linux-x86_64.tar.gz -C /home/admin/soft/
修改配置:
cp filebeat.full.yml filebeat.yml
# 修改配置
filebeat.prospectors:
- input_type: log
paths:
- /home/admin/soft/filebeat-5.2.1-linux-x86_64/logs/filebeat
output.logstash:
hosts: ["172.16.134.2:5044"]
logging.level: debug 这个配置一般情况下不要开,因为会把所有 message 都会明文打印出来,一来不安全,二来磁盘压力大。
测试配置是否正确:
./filebeat -configtest -e
有如下输出表示正常:
Config OK
在 Elasticsearch 中, Index Pattern 用于定义字段应如何分析的设置和映射。Filebeat 的默认 Index Pattern 由软件包安装。 如果在 filebeat.yml 配置文件中接受模板加载的默认配置,则 Filebeat 在成功连接到Elasticsearch后会自动加载模板。 如果模板已存在,默认不会覆盖,但是可以通过配置进行覆盖。如果要禁用自动模板加载,或者要加载自己的模板,可以在Filebeat配置文件中更改模板加载的设置。 如果选择禁用自动模板加载,则需要手动加载模板。
配置模板加载 - 仅Elasticsearch输出支持。
手动加载模板 - Logstash输出所需。
由于我们需要的是输出到 Logstash,所以我们使用手动模板加载:
curl -XPUT 'http://172.16.134.2:9200/_template/filebeat' -d@/home/admin/soft/filebeat-5.2.1-linux-x86_64/filebeat.template.json
如果已经使用 Filebeat 将数据索引到 Elasticsearch 中,则索引可能包含旧文档。 加载 Index Pattern 后,您可以从filebeat- * 中删除旧文档,以强制 Kibana 查看最新的文档。 使用此命令:
curl -XDELETE 'http://172.16.134.2:9200/filebeat-*'
启动服务:
./filebeat start &
如果对于生产环境,我们应该用 systemd 来管理进程,修改 /usr/lib/systemd/system/filebeat.service
:
[Unit]
Description=Filebeat
Documentation=https://www.elastic.co/guide
After=network.target
[Service]
Type=Simple
ExecStart=/home/admin/soft/filebeat-5.2.1-linux-x86_64/filebeat -c /home/admin/soft/filebeat-5.2.1-linux-x86_64/filebeat.yml -httpprof 0.0.0.0:6060
ExecStop=/bin/kill -WINCH ${MAINPID}
Restart=always
RestartSec=0
WatchdogSec=1min
LimitNOFILE=100
LimitNPROC=100
[Install]
WantedBy=multi-user.target
其中filebest-current只是软连接,连接到真实目录,便于后续维护升级。
脚本 filebeat-stop.sh
:
#!/bin/bash
pid=`ps aux | grep filebeat | grep -v grep | awk '{print$2}'`
sudo kill -9 $pid
分发 filebeat.service
filebeat-stop.sh
pscp -h list_filebeat filebeat.service /tmp
pssh -h list_filebeat "sudo cp /tmp/filebeat.service /usr/lib/systemd/system/"
pscp -h list_filebeat filebeat-stop.sh /home/admin/soft/filebeat-current/
pssh -h list_filebeat "sudo systemctl daemon-reload"
pssh -h list_filebeat "sudo systemctl enable filebeat"
启动/停止脚本:
sudo systemd start filebeat
sudo systemd stop filebeat
注意,所采集的日志需要有 admin 用户的读权限,并且路径必须有执行权限。
Step4. Kibana 中加载 Index Pattern
在 Kibana 的 Discover
模块中,可以添加 filebeat-*
作为 Index Pattern。看到如下界面,说明添加成功:
我们可以根据 Fields 进行日志索引,还可以对其进行排序。
Q & A
Q: Discover: Fielddata is disabled on text fields by default. Set fielddata=true on [message] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory.
A: Fielddata 会使用大量的堆内存,尤其是加载了大量的 text
fileds。一旦 fileddata 被加载进入了堆,在生命周期内会一直常驻。同时,加载 fileddata 非常耗时,影响用户体验。这就是为什么默认禁止了 fielddata。如果尝试对 text
field 进行排序、聚合,就会报错如上。在尝试开启 fielddata 之前应该想想为什么要这么做,因为通常情况下不需要。
使用 Kibana Discover 搜索日志
Discover界面主要是通过各种过滤器搜索日志,如时间、type、loglevel等,并对所搜索到的日志做简单统计。界面如下所示,index 栏显示当前选择的 elasticsearch 中的 index。以下只做引导式介绍。
-
Search
表示的是搜索栏,输入想要搜索的关键字; -
filebeat
表示的是 index pattern 栏,我们之前导入的是filbeat-*
; -
Selected Fields
表示的是已选字段,右侧的内容框只会显示已选字段数据; -
Available Fileds
可以对预定义字段进行筛选,可以对Popular
中显示的可选字段进行筛选; -
Popular
显示的是最常用的字段; - 右上角的
Last 15 minutes
是用来选择时间区间的,也可以选择定时刷新Auto Refresh
;
搜索栏的使用
- 全字段匹配:搜索功能的后台支持是elasticsearch,属于全文搜索引擎,可以通过双引号进行任何字符串的匹配,如
"write_bytes=383"
,搜索结果为 message 字段包含了该字符串的 日志数据:
- 使用字段和逻辑表达:Elasticsearch的数据源是经过logstash格式化的日志,该格式通过elasticsearch的mapping API对应到kibana的字段。在文档栏的 source 中可以查看到格式化后的日志,以及原日志。搜索时可以使用字段和逻辑表达,如
type: log
等。这里注意,输入过程中kibana的搜索栏会动态解析搜索内容,搜索表达式输入过程中可能会显示红框,提示无法解析,待全部输入完全即可:
- 使用过滤器:过滤器可以叠加使用,左侧边栏只能够对
已有字段
进行设置。鼠标移动到对应字段,字段会变灰,并显示该字段统计量前五的数据,如下所示:
点击对应+(正向过滤)、-(反向过滤)进行过滤。对所有字段
的过滤,可以在文档栏的 source 中进行选择,如下所示:
选择后的过滤器会显示在搜索栏下方,便于进行设置:
图标和文字可以达到相同的功能,分别是过滤器 Enable、Disable、反选、锁定(更改搜索内容不变更)和删除。
工具栏的使用
过滤器设置好后,可以对该设置在工具栏中进行保存,作为visualize
的数据源。三个图标分别是开始一个新的搜索(New
)、保存搜索(Save
)、打开搜索(Open
)、分享搜索(Share
)。
柱状图统计
柱状图实时对搜索内容进行统计,以时间作为横坐标,显示搜索到的总日志条数。也可以通过箭头按钮展开或折叠显示相应的文本记录。默认一页最多显示500条。鼠标移动到相应柱状,可显示对应条数,数遍变为十字,可以进行放大(zoom in
)或缩小(zoom out
)。
文档栏字段选择
默认文档栏显示所有字段,需要调整显示字段,可以在页面左边字段选择框添加和删除。鼠标移动到相应字段,字段变灰,同时出现add或remove按钮。所选字段也可以进行移动布局,或排序。字段是否作为popular field,在settings中进行设置。
结合 Discover 和 Visualize 进行可视化图标展示
假设我们需要对来自2台 Filebeat 采集到的 message 数量按照 host 进行区别统计 sum。
首先我们在 Discover
中定义一个 Search
, Selected Fields
选择 host
message
:
点击 Save
进行保存,命名为 test1。
然后我们在 Visualize
里 Vertical Bar Chart
,在右侧的 Or, From a Saved Search
里搜索 test1,并且进入编辑。Y-Axis
和 X-Axis
分别配置如下:
点击Apply Changes
所得到的图表如下:
点击
Save
,我们可以很方便的在 Dashboard
中 Add
这个视图。
Q & A
Q: 启动 ES 的时候报错:system call filters failed to install; check the logs and fix your configuration or disable system call filters at your own risk
。
A: SecComp fails on CentOS 6,修改 elasticsearch.yml
,在 Memory
的配置下面添加:bootstrap.system_call_filter: false
。