一、ELK日志分析系统概述
1.1 日志服务器
-
提高安全性
-
集中存放日志
-
缺陷
对日志的分析困难
1.2 ELK日志分析系统
- Elasticsearch(索引数据库)
- Logstash(收集,输出,存储日志)
- Kibana(展示显示数据)
1.3 日志处理步骤
-
将日志进行集中化管理
因为es拥有前端和后端所有集群的数据信息,对于es来说就是集中化管理,不需要每一台去收集,Logstash回去收集信息,只需管理和 Logstash对接的日志数据源就可以
-
将日志格式化(Logstash) 并输出到Elasticsearch
格式化目的:输出为一个标准可以作为展示页面的输出
-
对格式化后的数据进行索引和存储( Elasticsearch)
非常强大的索引,百度和谷歌都用这个搜索引擎
-
前端数据的展示( Kibana)
二、ELK组件介绍
2.1 Elasticsearch介绍(索引数据库)
2.11 Elasticsearch的概述
- 提供了一个分布式多用户能力的全文搜索引擎
- 搜索引擎效率高是因为有分片和副本机制
2.12 Elasticsearch核心概念
-
接近实时
lasticsearch是一个接近实时的搜索平台,这意味着,从索引一个文档直到这个文档能够被搜索到有一个轻微的延迟(通常是1秒)
-
集群
一个集群就是由一个或多个节点组织在一起,它们共同持有你整个的数据,并一起提供索引和搜索功能。其中一个节点为主节点,这个主节点是可以通过选举产性的,并提供跨节点的联合索引和搜索的功能。集群有一 个唯一性标示的名字,默认是elasticsearch,集群名字很重要,每个节点是基于集群名字加入到其集群中的。因此,确保在不同环境中使用不同的集群名字。
一个集群可以只有一个节点。强烈建议在配置elasticsearch时, 配置成集群模式。
es具有集群机制,节点通过集群名称加入到集群中,同时在集群中的节点会有一个自己的唯一身份标识
-
节点
节点就是一台单一的服务器,是集群的一部分,存储数据并参与集群的索引和搜索功能。像集群一样,节点也是通过名字来标识,默认是在节点启动时随机分配的字符名。当然,你可以自己定义。该名字也很重要,在集群中用于识别服务器对应的节点。
节点可以通过指定集群名字来加入到集群中。默认情况,每个节点被设置成加入到elasticsearch集群。如果启动了多个节点,假设能自动发现对方,他们将会自动组建一个名为elasticsearch的集群。
-
索引
索引就是一个拥有几分相似特征的文档的集合。比如说,你可以有一个客户数据的索引, 另一个产品目录的索引,还有一个订单数据的索引。一个索引由一个名字来标识(必须全部是小写字母的),并且当我们要对对应于这个索引中的文档进行索引、搜索、更新和删除的时候,都要使用到这个名字。在一个集群中,如果你想,可以定义任意多的索引。
–索引相对于关系型数据库的库。
–索引(库)→类型(表)→文档(记录)
–索引对应的类型(type)
会为具有一组共同字段的文档定义一个类型。比如说,我们假设你运营一个博客平台并且将你所有的数据存储到一个索引中。在这个索引中,你可以为用户数据定义一个类型,为博客数据定义另一 个类型,当然,也可以为评论数据定义另一个类型。
–类型相对于关系型数据库的表 -
类型(type)
在一个索引中,你可以定义一种或多种类型。一个类型是你的索引的一个逻辑上的分类/分区,其语义完全由你来定。通常,会为具有一组共同字段的文档定义一个类型。比如说,我们假设你运营一个博客平台并且将你所有的数据存储到一个索引中。在这个索引中,你可以为用户数据定义一个类型,为博客数据定义另一个类型,当然,也可以为评论数据定义另一个类型。
类型相对于关系型数据库的表
-
文档(document)
一个文档是一个可被索引的基础信息单元。比如,你可以拥有某一个客户的文档, 某一个产品的一个文档,当然,也可以拥有某个订单的一个文档。文档以SON (Javascript Object Notation)格式来表示,而JSON是一个到处存在的互联网数据交互格式。
在一个index/type里面,只要你想,你可以存储任意多的文档。注意,虽然一个文档在物理上位于一个索引中, 实际上一个文档必须在一个索引内被索引和分配一个类型。
文档相对于关系型数据库的列。
-
分片和副本(shards & replicas)
在实际情况下,索引存储的数据可能超过单个节点的硬件限制。如一个10亿文档需1TB空间可能不适合存储在单个节点的磁盘上,或者从单个节点搜索请求太慢了。为了解决这个问题,elasticsearch提供将索引分成多个分片的功能。当在创建索引时,可以定义想要分片的数量。每一个分片就是一个全功能的独立的索引,可以位于集群中任何节点上。
分片的两个最主要原因:
a.水平分割扩展,增大存储量
b.分布式并行跨分片操作,提高性能和吞吐量
分布式分片的机制和搜索请求的文档如何汇总完全是有elasticsearch控制的, 这些对用户而言是透明的。优点:
1.分担es数据库存储(读取,处理)压力,压力分层,分离
2.索引性能提高(搜索速度提高)小结:
网络问题等等其它问题可以在任何时候不期而至,为了健壮性,强烈建议要有一个故障切换机制, 无论何种故障以防止分片或者节点不可用。为此,elasticsearch让我们将索引分片复制一份或多份,称之为分片副本或副本。副本也有两个最主要原因:
a.高可用性,以应对分片或者节点故障。出于这个原因,分片副本要在不同的节点上。
b. 增大吞吐量,搜索可以并行在所有副本上执行。优点:
读取,写入,修改,索引数据,分片和自身对应的副本,可以同时进行系统操作,总结:
总之,每个索引可以被分成多个分片。一个索引也可以被复制0次(意思是没有复制)或多次。一旦复制了,每个索引就有了主分片(作为复制源的原来的分片)和复制分片(主分片的拷贝)之别。分片和副本的数量可以在索引创建的时候指定。在索引创建之后,你可以在任何时候动态地改变副本的数量,但是你事后不能改变分片的数量
2.2 Logstash介绍
2.21 Logstash简介
- 一款强大的数据处理工具
- 可实现数据传输、格式处理、格式化输出
- 数据输入、数据加工(如过滤,改写等)以及数据输出
小结:Logstash由JRuby语言编写, 基于消息(message based) 的简单架构,并运行在Java虚拟机(JVM)上。不同于分离的代理端(agent)或主机端(server) ,LogStash可配置单一的代理端(agent) 与其它开源软件结合,以实现不同的功能
2.22 LogStash主要组件
- Shipper: 日志收集者。负责监控本地日志文件的变化,及时把日志文件的最新内容收集起来。通常,远程代理端(agent)
只需要运行这个组件即可 - lndexer: 日志存储者。负责接收日志并写入到本地文件。
- Broker: 日志Hub。负责连接多个Shipper和多个Indexer
- Search and Storage: 允许对事件进行搜索和存储;
- Web Interface: 基于Web的展示界面
小结:正是由于以上组件在LogStash架构中可独立部署,才提供了更好的集群扩展性
2.23 Logstash的理念
- Collect:数据输入
- Enrich:数据加工,如过滤,改写等
- Transport:数据输出(被其他模块进行调用)
2.3 Kibana介绍
2.31 Kibana介绍(从ES拿取数据)
- 一个针对Elasticsearch的开源分析及可视化平台
- 搜索、查看存储在Elasticsearch索引中的数据
- 通过各种图表进行高级数据分析及展示
2.32 Kibana主要功能
- Elasticsearch无缝之集成
- 整合数据,复杂数据分析
- 让更多团队成员受益
- 接口灵活,分享更容易
- 配置简单,可视化多数据源
- 简单数据导出
三、部署ELK日志分析系统
3.1 项目图示
3.2 项目环境
主机名 | ip地址 |
---|---|
node1 | 20.0.0.11 |
node2 | 20.0.0.12 |
apache | 20.0.0.13 |
3.3 项目准备
Node1、Node2节点内存分配4G,Apache节点分配1G内存
改名并关闭防火墙
hostnamectl set-hostname node1
hostnamectl set-hostname node2
hostnamectl set-hostname apache
systemctl stop firewalld
setenforce 0
3.4 项目步骤
所有服务器添加映射
vi /etc/hosts #添加映射
20.0.0.11 node1
20.0.0.12 node2
20.0.0.13 apache
node1,mode2检测java环境
root@node1 ~]# java -version
openjdk version "1.8.0_131"
OpenJDK Runtime Environment (build 1.8.0_131-b12)
OpenJDK 64-Bit Server VM (build 25.131-b12, mixed mode)
在node1,2上添加elk安装包
node1,mode2安装elasticsearch的rpm包
[root@node1 ~]# rpm -ivh elasticsearch-5.5.0.rpm
重启守护进程,并设置开机自启动
[root@node1 ~]# systemctl daemon-reload
[root@node1 ~]# systemctl enable elasticsearch.service
Created symlink from /etc/systemd/system/multi-user.target.wants/elasticsearch.service to /usr/lib/systemd/system/elasticsearch.service.
更改elasticsearch主配置文件
[root@node1 ~]# cd /etc/elasticsearch/
[root@node1 elasticsearch]# ls
elasticsearch.yml jvm.options log4j2.properties scripts
[root@node1 elasticsearch]# cp elasticsearch.yml elasticsearch.yml.bak
[root@node1 elasticsearch]# ls
elasticsearch.yml elasticsearch.yml.bak jvm.options log4j2.properties scripts
[root@node1 elasticsearch]# vim elasticsearch.yml #删除前方#注释符,并修改
17/ cluster.name: my-elk-cluster #集群名字
23/ node.name: node1 #节点名字,node2上改为node2
33/ path.data: /data/elk_data #数据存放路径
37/ path.logs: /var/log/elasticsearch #日志存放路径
43/ bootstrap.memory_lock: false #不在启动的时候锁定内存
55/ network.host: 0.0.0.0 #提供服务绑定的IP地址,0.0.0.0代表所有地址
59/ http.port: 9200 #侦听端口为9200
68/ discovery.zen.ping.unicast.hosts: ["node1", "node2"] #集群发现通过单播实现
查看修改内容
[root@node1 elasticsearch]# grep -v "^#" /etc/elasticsearch/elasticsearch.yml
cluster.name: my-elk-cluster
node.name: node1
path.data: /data/elk_data
path.logs: /var/log/elasticsearch
bootstrap.memory_lock: false
network.host: 0.0.0.0
http.port: 9200
discovery.zen.ping.unicast.hosts: ["node1", "node2"]
创建数据存放路径并授权
[root@node1 elasticsearch]# mkdir -p /data/elk_data
[root@node1 elasticsearch]# chown elasticsearch.elasticsearch /data/elk_data/
启动elasticsearch是否开启成功
[root@node1 elasticsearch]# systemctl start elasticsearch.service # 启动
[root@node1 elasticsearch]# netstat -anpt | grep 9200 #开启时间需等待一会儿
[root@node1 elasticsearch]# netstat -anpt | grep 9200
tcp6 0 0 :::9200 :::* LISTEN 59533/java
3.41 集群检查健康和状态
真机打开http://20.0.0.11:9200/_cluster/health?pretty #检查集群健康状态
真机打开http://20.0.0.11:9200/_cluster/state?pretty #检查集群状态信息
3.42 编译安装node组件依赖包
安装elasticsearch-head插件
方便管理群集
[root@node1 elasticsearch]# yum install gcc gcc-c++ make -y #安装依赖环境
[root@node1 elasticsearch]# cd
[root@node1 ~]# tar zxvf node-v8.2.1.tar.gz -C /opt/
[root@node1 ~]# cd /opt/
[root@node1 opt]# ls
node-v8.2.1 rh
[root@node1 opt]# cd node-v8.2.1/
[root@node1 node-v8.2.1]# ls
android-configure BSDmakefile CODE_OF_CONDUCT.md configure doc LICENSE node.gypi test
AUTHORS BUILDING.md COLLABORATOR_GUIDE.md CONTRIBUTING.md GOVERNANCE.md Makefile README.md tools
benchmark CHANGELOG.md common.gypi deps lib node.gyp src vcbuild.bat
[root@node1 node-v8.2.1]# ./configure
[root@node1 node-v8.2.1]# make -j3 #个进程同时处理进程,配置写入文件,二进制编译,
[root@node1 node-v8.2.1]# make install
3.43 安装phantomjs前端框架
[root@node1 node-v8.2.1]# cd
[root@node1 ~]# tar jxvf phantomjs-2.1.1-linux-x86_64.tar.bz2 -C /usr/local/src/
拷贝到本机目录下,方便使用命令
[root@node1 ~]# cd /usr/local/src/phantomjs-2.1.1-linux-x86_64/bin/
[root@node1 bin]# ls
phantomjs
[root@node1 bin]# cp phantomjs /usr/local/bin/ #添加到本地可用命令
3.44 安装elasticsearch数据可视化工具
[root@node1 ~]# tar zxvf elasticsearch-head.tar.gz -C /usr/local/src/
[root@node1 ~]# cd /usr/local/src/elasticsearch-head/
[root@node1 elasticsearch-head]# ls
Dockerfile Gruntfile.js LICENCE package-lock.json README.textile test
Dockerfile-alpine grunt_fileSets.js node_modules plugin-descriptor.properties _site
elasticsearch-head.sublime-project index.html package.json proxy src
[root@node1 elasticsearch-head]# npm install #安装
3.45 编辑主配置文件
[root@node1 elasticsearch-head]# cd
[root@node1 ~]# vim /etc/elasticsearch/elasticsearch.yml #末尾添加
http.cors.enabled: true #开启跨域访问支持,默认为false
http.cors.allow-origin: "*" #跨域访问允许的域名地址
[root@node1 ~]# systemctl restart elasticsearch.service #重启服务
3.46 启动elasticsearch-head服务
[root@node1 ~]# cd /usr/local/src/elasticsearch-head/
[root@node1 elasticsearch-head]# ls
Dockerfile elasticsearch-head.sublime-project grunt_fileSets.js LICENCE package.json plugin-descriptor.properties README.textile src
Dockerfile-alpine Gruntfile.js index.html node_modules package-lock.json proxy _site test
[root@node1 elasticsearch-head]# npm run start & #切换到后台运行
[1] 105523
[root@node1 elasticsearch-head]#
> elasticsearch-head@0.0.0 start /usr/local/src/elasticsearch-head
> grunt server
Running "connect:server" (connect) task
Waiting forever...
Started connect web server on http://localhost:9100
^C
[root@node1 elasticsearch-head]# netstat -anpt | grep 9100
tcp 0 0 0.0.0.0:9100 0.0.0.0:* LISTEN 105533/grunt
[root@node1 elasticsearch-head]# netstat -anpt | grep 9200
tcp6 0 0 :::9200 :::* LISTEN 105447/java
在真机上浏览http://20.0.0.11:9100/
在elasticsearch后面的栏中输入http://20.0.0.11:9200,可以看到集群为健康绿色
查看node1
查看node2
至此,es群集生效
在node1建立索引
索引名为index-demo,类型为test
查看索引
node1上查看添加的索引
[root@node1 ~]# curl -XPUT 'localhost:9200/index-demo/test/1?pretty&pretty' -H 'content-Type: application/json' -d '{"user":"zhangsan","mesg":"hello world"}'
{
"_index" : "index-demo", #索引名(索引相当与数据据中的库)
"_type" : "test", #类型(类型相当于数据库中的表)
"_id" : "1",
"_version" : 1,
"result" : "created",
"_shards" : {
"total" : 2,
"successful" : 2,
"failed" : 0
},
"created" : true
}
-----------------------解析------------------------
-XPUT ‘localhost:9200:指定在本地
/index-demo/test/:索引中建立test
1?pretty&pretty’:问好后面跟一些参数
application/json:以json格式插入数据
查看信息
至此,证明es中可以存储数据,可以使用
3.47 安装logstash并做一些日志搜集输出到elasticsearch中
在apache主机上
安装apache
[root@apache ~]# yum -y install httpd
[root@apache ~]# systemctl start httpd
[root@apache ~]# netstat -anpt | grep httpd
tcp6 0 0 :::80 :::* LISTEN 60780/httpd
验证java环境
[root@apache ~]# java -version
openjdk version "1.8.0_131"
OpenJDK Runtime Environment (build 1.8.0_131-b12)
OpenJDK 64-Bit Server VM (build 25.131-b12, mixed mode)
安装logstash
[root@apache ~]# rpm -ivh logstash-5.5.1.rpm
启动logstash,并设置开机自启
[root@apache ~]# systemctl start logstash.service
[root@apache ~]# systemctl enable logstash.service
Created symlink from /etc/systemd/system/multi-user.target.wants/logstash.service to /etc/systemd/system/logstash.service.
创建软连接,将命令连接到本机bin目录下
[root@apache ~]# ln -s /usr/share/logstash/bin/logstash /usr/local/bin/
- logstash(apache)与elasticsearch(node)功能是否正常,做对接测试
方法一:Logstash这个命令测试
字段描述解释:
-f通过这个选项可以指定logstash的配置文件,根据配置文件配置logstash
-e后面跟着字符出该字符串可以被当做logstash的配置(如果是””,则默认使用stdin做为输入、stdout作为输出)
-t测试配置文件是否正确,然后退出
输入采用标准输入,输出采用标准输出,在apache服务器上
[root@apache ~]# logstash -e 'input { stdin{} } output { stdout{} }'
方法二:使用rubydebug显示详细输出,codec为一种编解码器
[root@apache ~]# logstash -e 'input { stdin{} } output { stdout{ codec=>rubydebug } }'
证实logstash可进行格式化输出
使用logstash将信息写入到elasticsearch
[root@apache ~]# logstash -e 'input { stdin{} } output { elasticsearch{ hosts=>["20.0.0.11:9200"] } }'
打开真机浏览器集群http://20.0.0.11:9100/
证实,数据出口导向可对接上es,并且成功完成分片及副本
3.48 在apache主机做对接配置
logstash配置文件主要由三部分组成:input、output、filter(根据需求)
查看apache日志
为other添加可读权限
[root@apache ~]# ll /var/log/messages
-rw-------. 1 root root 2465773 1月 7 18:47 /var/log/messages
[root@apache ~]# chmod o+r /var/log/messages
[root@apache ~]# ll /var/log/messages
-rw----r--. 1 root root 2468338 1月 7 18:47 /var/log/messages
[root@apache ~]# cd /etc/logstash/
[root@apache logstash]# ls
conf.d jvm.options log4j2.properties logstash.yml startup.options
[root@apache logstash]# vim logstash.yml
[root@apache logstash]# cd conf.d/
[root@apache conf.d]# vim system.conf
input {
file{
path => "/var/log/messages"
type => "system"
start_position => "beginning"
}
}
output {
elasticsearch {
hosts => ["20.0.0.11:9200"]
index => "system-%{+YYYY.MM.dd}"
}
}
[root@apache conf.d]# systemctl restart logstash.service
在真机浏览器上查看
格式皆为自己设定的格式
3.49 安装kibana
在node1上装kibana
[root@node1 ~]# rpm -ivh kibana-5.5.1-x86_64.rpm
配置kibana配置文件
[root@node1 ~]# cd /etc/kibana/
[root@node1 kibana]# cp kibana.yml kibana.yml.bak #备份kibana配置文件
[root@node1 kibana]# vim kibana.yml #修改并删除前面#注释符
2/ server.port: 5601
7/ server.host: "0.0.0.0"
21/ elasticsearch.url: "http://20.0.0.11:9200"
30/ kibana.index: ".kibana"
[root@node1 kibana]# systemctl start kibana.service #重启服务
[root@node1 kibana]# systemctl enable kibana.service #设置开机自启
Created symlink from /etc/systemd/system/multi-user.target.wants/kibana.service to /etc/systemd/system/kibana.service.
在真机浏览器访问20.0.0.11:5601
创建
查看信息
3.50 对接apache主机的apache日志文件(访问、错误的)
在apache主机
[root@apache conf.d]# cd /etc/logstash/
[root@apache logstash]# cd conf.d/
[root@apache conf.d]# vim apache_log.conf
input {
file{
path => "/etc/httpd/logs/access_log"
type => "access"
start_position => "beginning"
}
file{
path => "/etc/httpd/logs/error_log"
type => "error"
start_position => "beginning"
}
}
output {
if [type] == "access" {
elasticsearch {
hosts => ["20.0.0.11:9200"]
index => "apache_access-%{+YYYY.MM.dd}"
}
}
if [type] == "error" {
elasticsearch {
hosts => ["20.0.0.11:9200"]
index => "apache_error-%{+YYYY.MM.dd}"
}
}
}
[root@apache conf.d]# /usr/share/logstash/bin/logstash -f apache_log.conf
此处也可用
[root@apache conf.d]# logstash -f apache_log.conf #之前创建过软连接
真机访问es
此时真机浏览器访问访问apache,20.0.0.13
再次查看es
此时发现access和error都有了
apache的access和error查看
此时查看kibana,并创建新索引
创建access索引
ELK创建成功