winxcoder 2019-06-29
虽然用了ELK很久了,但一直苦于没有自己尝试搭建过,所以想抽时间尝试尝试。原本打算按照教程 《ELK集中式日志平台之二 — 部署》(作者:樊浩柏科学院) 进行测试的,没想到一路出了很多坑,所以又按照自己成功搭建的流程写了本文。
《ELK集中式日志平台之二 — 部署》一文参考价值非常大,图文并茂,大家可以在学习过程中参考参考。作者一上来就安装ELK插件,实际可以按需选择安装,但作为初学者,无疑增加了复杂度。ELK插件后续我会单独拿出来讲解,本文略过。
ELK 指的是一套解决方案,是 Elasticsearch、Logstash 和 Kibana 三种软件产品的首字母缩写,Beats 是 ELK 协议栈的新成员。
本来ELK是没有Beats的。
最开始的架构中,由 Logstash 承担数据采集器和过滤功能,并部署在应用服务器。由于 Logstash 对大量日志进行过滤操作,会消耗应用系统的部分性能,带来不合理的资源分配问题;另一方面,过滤日志的配置,分布在每台应用服务器,不便于集中式配置管理。
所以就有了Beats。
由于 Beats 的系统性能开销更小,所以应用服务器性能开销可以忽略不计;另一方面,Beats 可以作为数据采集插件形式工作,可以按需启用 Beats 下不同功能的插件,更灵活,扩展性更强。例如,应用服务器只启用 Filebeat,则只收集日志文件数据,如果某天需要收集系统性能数据时,再启用 Metricbeat 即可,并不需要太多的修改和配置。
其中,目前 Beats 家族根据功能划分,主要有:
Real-time insight into log data.
负责收集文件数据。
Analyze network packet data.
负责收集网络流量数据。
Analyze Windows event logs.
负责收集 Windows 事件日志数据。
Ship and analyze metrics.
负责收集系统级的 CPU 使用率、内存、文件系统、磁盘 IO 和网络 IO 统计数据。
Ping your Infrastructure.
Send audit data to Elasticsearch.
如果日志量巨大,可能还会引入Kafka用以均衡网络传输,从而降低了网络闭塞,尤其是丢失数据的可能性;另一方面,这样可以系统解耦,具有更好的灵活性和扩展性。
环境:CentOS6.8
ELK各自版本最好都是一致的,否则可能会有兼容性问题。
本次都是使用5.6.2版本。截止到2018-09-23,官网的最新版本是6.4.1。
官网下载地址:
https://www.elastic.co/downloads
https://artifacts.elastic.co/...
https://artifacts.elastic.co/...
https://artifacts.elastic.co/...
https://artifacts.elastic.co/...
历史版本汇集页:
https://www.elastic.co/downlo...
安装有两种方法:
建议第二种方法,可以自由安装版本及定义安装目录。
另外需要注意的是:ELK系列软件启动服务的时候不允许以root用户启动。这里我们统一建立用户 elk
:
useradd elk
Mac因为默认用户就不是root,可以忽略这一步。
启动软件的时候,有2种方式启动:
service
启动测试的时候建议以第一种,这样可以及时查看错误日志。生产环境可以配置service
启动。
1、ElasticSearch、Kibana都支持安装插件:例如x-pack。
2、ElasticSearch、Kibana的配置文件一般在安装目录的config里(yml格式),二进制文件在bin里。ElasticSearch和Logstatsh config目录都有jvm.options
,测试环境建议修改:
-Xms256m -Xmx1g
默认可能是2g,测试环境改小一点。后面这点还会说明。
安装JDK1.8:
yum install -y java-1.8.0-openjdk
配置环境变量:
vi /etc/profile
增加:
JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.181-3.b13.el6_10.x86_64 PATH=$JAVA_HOME/bin:$PATH CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar JAVACMD=/usr/bin/java export JAVA_HOME JAVACMD CLASSPATH PATH
然后使之生效:
source /etc/profile
验证版本信息:
# java -version openjdk version "1.8.0_181" OpenJDK Runtime Environment (build 1.8.0_181-b13) OpenJDK 64-Bit Server VM (build 25.181-b13, mixed mode)
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.6.2.tar.gz
大小32.2M。安装很简单,解压即可:
mkdir -p /usr/local/elk tar zxvf elasticsearch-5.6.2.tar.gz -C /usr/local/elk mv /usr/local/elk/elasticsearch-5.6.2 /usr/local/elk/elasticsearch
配置权限:
chown -R elk:elk /usr/local/elk/elasticsearch
对目录/usr/local/elk/elasticsearch
的增删改操作建议使用上面创建的elk用户,否则还要使用chown命令修改权限。
su -e elk
修改config/jvm.options
:
vi /usr/local/elk/elasticsearch/config/jvm.options
根据实际情况修改:默认是2g:
# 最小值 -Xms256m #最大值 -Xmx1g
我测试的时候忘记修改了,测试机器卡死了。
如果没有配置service
启动方式,需要切换用户。
su - elk # -d表示后台运行 /usr/local/elk/elasticsearch/bin/elasticsearch -d
查看是否已运行:
$ netstat -tulnp | grep 9200 tcp 0 0 127.0.0.1:9200 0.0.0.0:* LISTEN 121/java
默认是 9200 端口。如果需要修改,可以编辑config/elasticsearch.yml
。
$ curl http://127.0.0.1:9200 { "name" : "6e1PMnr", "cluster_name" : "elasticsearch", "cluster_uuid" : "Uahv9iLnSLyMjIxX57lbMQ", "version" : { "number" : "5.6.2", "build_hash" : "bd92e7f", "build_date" : "2017-12-17T20:23:25.338Z", "build_snapshot" : false, "lucene_version" : "7.1.0", "minimum_wire_compatibility_version" : "5.6.0", "minimum_index_compatibility_version" : "5.0.0" }, "tagline" : "You Know, for Search" }
防盗版声明:本文系原创文章,发布于公众号飞鸿影的博客
(fhyblog)及博客园,转载需作者同意。
Kibana负责日志数据的可视化。Kibana从ElasticSearch里读取数据。
wget https://artifacts.elastic.co/downloads/kibana/kibana-5.6.2-linux-x86_64.tar.gz
大小48.5M。同样是解压:
tar zxvf kibana-5.6.2-linux-x86_64.tar.gz -C /usr/local/elk/ mv /usr/local/elk/kibana-5.6.2-linux-x86_64 /usr/local/elk/kibana chown -R elk:elk /usr/local/elk/kibana
对目录/usr/local/elk/kibana
的增删改操作建议使用上面创建的elk用户,否则还要使用chown命令修改权限。
su -e elk
修改配置:
vim /usr/local/elk/kibana/config/kibana.yml
默认配置都是注释了的,默认端口是5601,默认访问 elasticsearch 的9200端口。我们可以按需修改。例如:
server.port: 5601 # 监听端口 server.host: "0.0.0.0" # 绑定地址 #server.name: "elk.fanhaobai.com" # 域名 #elasticsearch.url: "http://127.0.0.1:9200" # es #kibana.index: ".kibana" # 索引名 #elasticsearch.username: "elastic" # 用户名 #elasticsearch.password: "changeme" # 密码
这里修改了server.host
,默认是localhost
。
/usr/local/elk/kibana/bin/kibana
注意:默认是前台运行的,如果需要后台运行:
nohup /usr/local/elk/kibana/bin/kibana &
可以使用前台运行的方式,没有报错误,然后使用后台运行的方式。
查看是否已运行:
$ netstat -tulnp | grep 5601 tcp 0 0 0.0.0.0:5601 0.0.0.0:* LISTEN 248/./kibana/bin/..
默认打开浏览器 http://127.0.0.1:5601 就可以看到 kibana 的界面了:
也可以配置Nginx代理到别的域名:
server { listen 80; server_name elk.cc; #当前主机名 # auth_basic "Restricted Access"; # auth_basic_user_file /usr/local/nginx/conf/htpasswd.users; #登录验证 location / { proxy_pass http://127.0.0.1:5601; #转发到kibana proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection 'upgrade'; proxy_set_header Host $host; proxy_cache_bypass $http_upgrade; } }
到现在还没有数据可以展示,因为ES里我们还没有导入或者传入数据。接下来我们使用 Logstash+Filebeat 导入日志数据。
wget https://artifacts.elastic.co/downloads/logstash/logstash-5.6.2.tar.gz tar zxvf logstash-5.6.2-linux.gz -C /usr/local/elk/ mv /usr/local/elk/logstash-5.6.2/ /usr/local/elk/logstash chown -R elk:elk /usr/local/elk/logstash
logstash-5.6.2.tar.gz 大小96.8M。
对目录/usr/local/elk/logstash
的增删改操作建议使用上面创建的elk用户,否则还要使用chown命令修改权限。
# 切换用户 su - elk
1、修改 config/jvm.options
:
vim /usr/local/elk/logstash/config/jvm.options
这里我修改为:
-Xms128m -Xmx512m
2、修改 config/logstash.yml
:
vim /usr/local/elk/logstash/config/logstash.yml
默认全是注释的,这里仅修改一处:
path.config: /usr/local/elk/logstash/config/conf.d
这样就支持子配置了,我们可以把新建的配置都放在conf.d
目录里。
注意:path.config:
后面有一个空格。
然后创建子文件夹:
mkdir /usr/local/elk/logstash/config/conf.d
由于现在我们还没有安装filebeat,也不打算直接使用logstash收集日志,所以先简单测试下标准输入输出,只要正常就行了:
$ ./logstash/bin/logstash -e 'input { stdin { } } output { stdout {}}'
稍等几秒钟:
Sending Logstash's logs to /usr/local/elk/logstash/logs which is now configured via log4j2.properties [2018-09-24T23:07:35,424][INFO ][logstash.modules.scaffold] Initializing module {:module_name=>"netflow", :directory=>"/usr/local/elk/logstash/modules/netflow/configuration"} [2018-09-24T23:07:35,434][INFO ][logstash.modules.scaffold] Initializing module {:module_name=>"fb_apache", :directory=>"/usr/local/elk/logstash/modules/fb_apache/configuration"} [2018-09-24T23:07:35,657][INFO ][logstash.pipeline ] Starting pipeline {"id"=>"main", "pipeline.workers"=>4, "pipeline.batch.size"=>125, "pipeline.batch.delay"=>5, "pipeline.max_inflight"=>500} [2018-09-24T23:07:35,683][INFO ][logstash.pipeline ] Pipeline main started The stdin plugin is now waiting for input: [2018-09-24T23:07:35,776][INFO ][logstash.agent ] Successfully started Logstash API endpoint {:port=>9600} hello 2018-09-24T15:07:42.760Z 2106567e5bce hello welcome 2018-09-24T15:07:49.501Z 2106567e5bce welcome
我们输入了hello、welcome,终端实时的输出了内容。后面的内容里,我们将会修改 stdin 为为beats,修改 stdout 为ElasticSearch。
如果新增配置,需要后台常驻运行,可以使用下列命令:
/usr/local/elk/logstash/bin/logstash &
查看是否已运行(需要过10s左右,可以多刷几次):
$ netstat -tulnp | grep 5044 tcp 0 0 0.0.0.0:5044 0.0.0.0:* LISTEN 1040/java
Filebeat不依赖JDK。
wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-5.6.2-linux-x86_64.tar.gz
filebeat 8.4M。解压、设置 :
mkdir /usr/local/elk/beats tar zxvf filebeat-5.6.2-linux-x86_64.tar.gz -C /usr/local/elk/beats/ mv /usr/local/elk/beats/filebeat-5.6.2-linux-x86_64/ /usr/local/elk/beats/filebeat chown -R elk:elk /usr/local/elk/beats
注意:后续对目录/usr/local/elk/beats
的增删改操作建议使用上面创建的elk用户,否则还要使用chown命令修改权限。
# 切换用户 su - elk
为了让测试简单,我们手动模拟日志的生成:
echo "test - test2" >> /tmp/test1.log echo "test - test2" >> /tmp/test2.log
生成了2个日志文件test1.log
、test2.log
,各有一行日志。
新建一个filebeat配置文件:
cd /usr/local/elk vim beats/filebeat/filebeat.test.yml
配置内容:
filebeat.prospectors: - type: log paths: - /tmp/test1.log tags: ["test1"] document_type: test1 - type: log paths: - /tmp/test2.log tags: ["test2"] document_type: test2 output.elasticsearch: hosts: ["127.0.0.1:9200"] index: "test-filebeat"
配置说明:
filebeat.prospectors:
type
表示一个-
表示一个filebeat.prospector
,这里设置了2个。日志发送到elasticsearch,索引index 是test-filebeat
。
我们运行 filebeat:
# 修改权限 chmod 600 beats/filebeat/filebeat.test.yml # 指定配置文件前台运行 ./beats/filebeat/filebeat -c beats/filebeat/filebeat.test.yml
我们新开终端查看ES里是否新增了内容:
curl http://127.0.0.1:9200/test-filebeat/_search?q=* { "took": 0, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 2, "max_score": 1, "hits": [ { "_index": "test-filebeat", "_type": "test2", "_id": "AWYL9s4WJzfnbYlB_DSO", "_score": 1, "_source": { "@timestamp": "2018-09-24T14:23:30.652Z", "beat": { "hostname": "2106567e5bce", "name": "2106567e5bce", "version": "5.6.2" }, "input_type": "log", "message": "test - test2", "offset": 13, "source": "/tmp/test2.log", "tags": [ "test2" ], "type": "test2" } }, { "_index": "test-filebeat", "_type": "test1", "_id": "AWYL9s4WJzfnbYlB_DSP", "_score": 1, "_source": { "@timestamp": "2018-09-24T14:23:30.652Z", "beat": { "hostname": "2106567e5bce", "name": "2106567e5bce", "version": "5.6.2" }, "input_type": "log", "message": "test - test2", "offset": 13, "source": "/tmp/test1.log", "tags": [ "test1" ], "type": "test1" } } ] } }
新开命令行追加一行日志:
echo "new msg" >> /tmp/test1.log
curl http://127.0.0.1:9200/test-filebeat/_search?q=*&size=1&sort=@timestamp:desc { "took": 0, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 3, "max_score": null, "hits": [ { "_index": "test-filebeat", "_type": "test1", "_id": "AWYL-BjvJzfnbYlB_DSQ", "_score": null, "_source": { "@timestamp": "2018-09-24T14:24:55.654Z", "beat": { "hostname": "2106567e5bce", "name": "2106567e5bce", "version": "5.6.2" }, "input_type": "log", "message": "new msg", "offset": 21, "source": "/tmp/test1.log", "tags": [ "test1" ], "type": "test1" }, "sort": [ 1537799095654 ] } ] } }
这说明直接使用filebeat,也是可以发送数据到ES的,为什么还用logstash呢?原因是filebeat采集的是原始日志内容,发送到ES的也是原始内容,如果不需要处理的话,使用filebeat也行。
我们可以看到返回的文档json里有一个字段 message
,这个是日志原始内容。filebeat还默认加了一些字段:
打开kibana web地址:http://127.0.0.1:5601,依次打开:Management
-> Kibana
-> Index Patterns
,选择Create Index Pattern
:
a. Index pattern 输入:test-filebeat
;
b. Time Filter field name 选择 @timestamp
。
c. 点击Create。
然后打开Discover,选择 test-filebeat 就能看到日志数据了。
这时候我们去访问下自己配置了nginx日志的应用,这里能实时更新,再也不用去命令行使用tail查看了。
接下来,我们将日志使用filebeat发送到logstash,然后通过logstash处理后发送到ElasticSearch。
首先我们要修改上一节里filebeat的配置:
vim beats/filebeat/filebeat.test.yml
改为:
filebeat.prospectors: - type: log paths: - /tmp/test1.log tags: ["test1"] document_type: test1 - type: log paths: - /tmp/test2.log tags: ["test2"] document_type: test2 output.logstash: hosts: ["127.0.0.1:5046"] #output.elasticsearch: # hosts: ["127.0.0.1:9200"] # index: "test-filebeat"
我们把output.elasticsearch
注释了,新增了output.logstash
。
然后新增logstash配置:
vim logstash/config/conf.d/filebeat.test.conf
input { beats { port => 5046 } } output { elasticsearch { hosts => ["127.0.0.1:9200"] index => "test-filebeat-%{type}" } stdout { codec => rubydebug } }
这里的type
变量就是filebeat里面的document_type
。端口指定为5046(自定义即可),和filebeat里面配置的一致。logstash可以有多个子配置,所以也就能配置多个端口。此时,logstash是作为服务端运行的,filebeat是客户端。
接下来我们启动logstash和filebeat:
./logstash/bin/logstash &
&
表示后台运行:
./beats/filebeat/filebeat -c beats/filebeat/filebeat.test.yml
我们新开终端往日志里加点新内容:
echo "new msg" >> /tmp/test2.log echo "new msg3" >> /tmp/test2.log
稍等几秒钟,我们可以查看ES里的数据:
curl http://127.0.0.1:9200/test-filebeat-test2/_search?q=*&sort=@timestamp:desc { "took": 3, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 2, "max_score": null, "hits": [ { "_index": "test-filebeat-test2", "_type": "test2", "_id": "AWYMF-PeJzfnbYlB_DSo", "_score": null, "_source": { "@timestamp": "2018-09-24T14:59:38.188Z", "offset": 49, "@version": "1", "input_type": "log", "beat": { "name": "2106567e5bce", "hostname": "2106567e5bce", "version": "5.6.2" }, "host": "2106567e5bce", "source": "/tmp/test2.log", "message": "new msg3", "type": "test2", "tags": [ "test2", "beats_input_codec_plain_applied", "_grokparsefailure" ] }, "sort": [ 1537801178188 ] }, { "_index": "test-filebeat-test2", "_type": "test2", "_id": "AWYMF-PeJzfnbYlB_DSn", "_score": null, "_source": { "@timestamp": "2018-09-24T14:59:38.186Z", "offset": 40, "@version": "1", "input_type": "log", "beat": { "name": "2106567e5bce", "hostname": "2106567e5bce", "version": "5.6.2" }, "host": "2106567e5bce", "source": "/tmp/test2.log", "message": "new msg", "type": "test2", "tags": [ "test2", "beats_input_codec_plain_applied", "_grokparsefailure" ] }, "sort": [ 1537801178186 ] } ] } }
本节里我们虽然用到了logstash,但没有发挥它的强大处理功能。仅仅是演示了将日志使用filebeat发送到logstash,然后通过logstash处理后发送到ElasticSearch。处理功能后续再做讲解。
提示:其实我们可以在logstash里根据filebeat里的document_type做条件判断:
# 根据tags判断 if "test1" in [tags] { # something } # type 就是filebeat里的document_type if [type] == 'test1'{ }else if [type] == 'test2'{ }
ELK我们一共安装了4个软件:
其中es、kibana、logstash三者作为服务端安装在一起,filebeat安装在应用服务器,用于收集日志。
我们看一下共起了哪些端口:
$ netstat -tulnp Active Internet connections (only servers) Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name tcp 0 0 0.0.0.0:9000 0.0.0.0:* LISTEN 13/php-fpm tcp 0 0 127.0.0.1:9200 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 10/nginx tcp 0 0 0.0.0.0:5046 0.0.0.0:* LISTEN - tcp 0 0 127.0.0.1:9300 0.0.0.0:* LISTEN - tcp 0 0 127.0.0.1:9600 0.0.0.0:* LISTEN - tcp 0 0 0.0.0.0:5601 0.0.0.0:* LISTEN -
1、ELK集中式日志平台之二 — 部署 - 樊浩柏's Blog
https://www.fanhaobai.com/201...
2、ElasticSearch 5学习(1)——安装Elasticsearch、Kibana和X-Pack - wuxiwei - 博客园
https://www.cnblogs.com/wxw16...
3、Logstash Filebeat 安装配置之使用 Kibana 分析日志数据 - 任我乐
https://renwole.com/archives/661
4、ELK集中式日志平台之一 — 平台架构 - 樊浩柏's Blog
https://www.fanhaobai.com/201...
5、ELK集中式日志平台之三 — 进阶 - 樊浩柏's Blog
https://www.fanhaobai.com/201...
6、ELK+Filebeat 集中式日志解决方案详解
https://www.ibm.com/developer...