ELK日志分析系统
ELK(Elasticsearch、Logstash、Kibana):它是一套用于处理大规模日志和实时数据分析的开源解决方案。
1.ELK日志分析系统简介
集中式收集管理日志方案:rsyslog、shell/python脚本、ELK(elasticsearch+logstash+kibana)、Loki+promtail+grafana
(1)服务器数量较少时
1)不做任何日志集中管理,直接登录到服务器捞日志查看(缺点:当服务器不可用时,无法及时收集到日志)
2)通过 rsyslog 或 shell/python脚本 实现自动收集日志,集中保存到统一的日志服务器中
(2)服务器数量较多时
采用大型的日志系统 ELK/EFK ,实现自动日志收集、日志集中存储、日志图形展示等功能
(3)ELK组件
ELK平台是一套完整的日志集中处理解决方案,将 ElasticSearch、Logstash 和 Kibana 三个开源工具配合使用, 完成更强大的用户对日志的查询、排序、统计需求。
ELK组件 | |
---|---|
Logstash | 负责采集日志数据,还可通过插件模块对日志数据进行过滤、格式化处理,再输出给ElasticSearch |
ElasticSearch | 负责对日志数据进行分片、存储,并创建索引,方便全文检索 |
Kibana | 用于接入ElasticSearch的数据源,将日志数据进行图形化展示,方便用户通过浏览器查看、搜索、分析日志 |
Filebeat | 用于替代Logstash采集日志数据,优点:比Logstash更轻量,资源消耗更少 |
Fluentd | 也是Logstash的一种替代方案,可用于替代Logstash采集日志数据和过滤转换等功能,常用于收集K8S环境中的容器日志 |
Kafka/Redis | 作为消息队列MQ,实现流量销峰、缓冲、应用解耦等功能 |
ELK --> ELFK(ELF + filebeat)--> EFLFK(ELF + filebeat + Kafka)
(4)日志处理步骤
1.将日志进行集中化管理
2.将日志格式化(Logstash)并输出到Elasticsearch
3.对格式化后的数据进行索引和存储(Elasticsearch)
4.前端数据的展示(Kibana)
(5)日志服务器
提高安全性、集中存放日志、缺陷就是对日志的分析困难。
(6)完整日志系统基本特征
收集:能够采集多种来源的日志数据
传输:能够稳定的把日志数据解析过滤并传输到存储系统
存储:存储日志数据
分析:支持 UI 分析
警告:能够提供错误报告,监控机制
2.ELK Elasticsearch 集群部署(在Node1、Node2节点上操作)
(1)环境准备
#关闭防火墙
systemctl diable --now firewalld
setenforce 0
vim /etc/selinux/config
disabled
#设置Java环境
java -version
yum list java-1.8.0*
(2)部署 Elasticsearch 软件
(1)安装elasticsearch—rpm包
cd /opt/
rz -E 上传 elasticsearch-6.7.2.rpm
ls
yum localinstall -y elasticsearch-6.7.2.rpm
cd /etc/elasticsearch/
ls
//20.0.0.100
(2)修改elasticsearch主配置文件
cp elasticsearch.yml elasticsearch.yml.bak
ls
vim elasticsearch.yml
--17--取消注释,指定集群名字
cluster.name: my-elk-cluster
--23--取消注释,指定节点名字:Node1节点为node-1,Node2节点为node2 (不能重复)
node.name: node-1
node.master: true #是否master节点,false为否
node.data: true #是否数据节点,false为否
--35--取消注释,指定数据存放路径
path.data: /var/lib/elasticsearch
--39--取消注释,指定日志存放路径
path.logs: /var/log/elasticsearch
--45--取消注释,将系统内存锁定到es进程中,以保证es能够维护一定的内存空间,避免es使用swap交换分区
bootstrap.memory_lock: true
--57--取消注释,设置监听地址,0.0.0.0代表所有地址
network.host: 0.0.0.0
--61--取消注释,ES 服务的默认监听端口为9200
http.port: 9200 #指定es集群提供外部访问的接口
transport.tcp.port: 9300 #指定es集群内部通信接口
--71--取消注释,集群发现通过单播实现,指定要发现的节点,
以防止节点无意中加入集群,只有在同一台机器上运行的节点才会自动组成集群。
discovery.zen.ping.unicast.hosts: ["20.0.0.100:9300", "20.0.0.130:9300","20.0.0.140:9300"]
grep -v "^#" elasticsearch.yml
scp elasticsearch.yml 20.0.0.130:`pwd`
scp elasticsearch.yml 20.0.0.140:`pwd`
hostnamectl set-hostname es01
bash
//20.0.0.130
hostnamectl set-hostname es02
bash
vim elasticsearch.yml
node.name: node-2
//20.0.0.140
hostnamectl set-hostname es03
bash
vim elasticsearch.yml
node.name: node-3
(3)es 性能调优参数
//20.0.0.100
#优化最大内存大小和最大文件描述符的数量
vim /etc/security/limits.conf
* soft nofile 65536
* hard nofile 65536
* soft nproc 65536
* hard nproc 65536
* soft memlock unlimited
* hard memlock unlimited
vim /etc/systemd/system.conf
取消注释#
DefaultLimitNOFILE=65536
DefaultLimitNPROC=65536
DefaultLimitMEMLOCK=infinity
scp /etc/security/limits.conf 20.0.0.130:/etc/security/
scp /etc/systemd/system.conf 20.0.0.130:/etc/systemd/
scp /etc/security/limits.conf 20.0.0.140:/etc/security/
scp /etc/systemd/system.conf 20.0.0.140:/etc/systemd/
//20.0.0.100、20.0.0.130、20.0.0.140
vim /etc/sysctl.conf
vm.max_map_count = 262144
net.ipv4.tcp_syncookies = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_fin_timeout = 30
net.ipv4.tcp_keepalive_time = 1200
net.ipv4.ip_local_port_range = 1024 65535
net.ipv4.tcp_max_syn_backlog = 8192
net.ipv4.tcp_max_tw_buckets = 5000
net.core.somaxconn = 65535
sysctl -p
reboot
(4)启动elasticsearch是否成功开启
systemctl enable --now elasticsearch.service
netstat -lntp | grep 9200
systemctl status elasticsearch.service
cd /etc/elasticsearch/
ls
vim jvm.options
-Xms2g
-Xmx2g
systemctl restart elasticsearch.service
netstat -lntp | grep 9200
systemctl status elasticsearch.service
(5)查看节点信息
http://20.0.0.100:9200
http://20.0.0.130:9200
http://20.0.0.140:9200
#查看群集的健康情况,可以看到 status 值为 green(绿色),表示节点健康运行。
http://20.0.0.100:9200/_cluster/health?pretty
http://20.0.0.130:9200/_cluster/health?pretty
http://20.0.0.140:9200/_cluster/health?pretty
#检查群集状态信息
http://20.0.0.100:9200/_cluster/state?pretty
http://20.0.0.130:9200/_cluster/state?pretty
http://20.0.0.140:9200/_cluster/state?pretty
(3)安装 Elasticsearch-head 插件
//20.0.0.100
yum install gcc gcc-c++ make -y
cd /opt/
rz -E上传node-v8.2.1.tar.gz和phantomjs-2.1.1-linux-x86_64.tar.bz2
ls
(1)编译安装 node
tar xf node-v8.2.1.tar.gz
cd node-v8.2.1/
ls
./configure
make && make install
(2)安装 phantomjs
cd /opt/
tar xf phantomjs-2.1.1-linux-x86_64.tar.bz2
ls
cd phantomjs-2.1.1-linux-x86_64/
ls
ls bin/
cp bin/phantomjs /usr/local/bin/
(3)安装 Elasticsearch-head 数据可视化工具
cd /opt/
rz -E上传elasticsearch-head-master.zip
ls
unzip elasticsearch-head-master.zip
cd elasticsearch-head-master/
ls
npm install #安装依赖包
(4)修改 Elasticsearch 主配置文件
vim /etc/elasticsearch/elasticsearch.yml
......
--末尾添加以下内容--
http.cors.enabled: true #开启跨域访问支持,默认为 false
http.cors.allow-origin: "*" #指定跨域访问允许的域名地址为所有
systemctl restart elasticsearch
(5)启动 elasticsearch-head 服务
cd /opt/elasticsearch-head/
npm run start &
#elasticsearch-head 监听的端口是 9100
netstat -natp |grep 9100
netstat -natp |grep 9200
(6)通过 Elasticsearch-head 查看 Elasticsearch 信息
通过浏览器访问 http://20.0.0.100:9100/ 地址并连接群集。如果看到群集健康值为 green 绿色,代表群集很健康。
http://20.0.0.100:9100
http://20.0.0.100:9200 -->连接
(7)创建索引
API基本格式:http://ip:port/<索引>/<类型>/<文档id>
#通过命令创建一个测试索引,索引为 index-demo,类型为 test。
curl -X PUT 'localhost:9200/index-demo/test/1?pretty&pretty' \
-H 'content-Type: application/json' \
-d '{"user":"zhangsan","mesg":"hello world"}'
(4)Elasticsearch索引管理
1)命令行管理方式
创建索引
curl -X PUT 'http://ES-IP:9200/<索引名>/<类型>/<ID>?pretty&pretty' \
-H 'content-Type: application/json' -d '{"键1":"值1","键2":"值2"}'
删除索引
curl -X DELETE 'http://ES-IP:9200/<索引名>'
查看索引配置
curl -X GET 'http://ES-IP:9200/<索引名>/_settings'
修改索引配置
curl -X PUT 'http://ES-IP:9200/<索引名>/_settings' \
-H 'content-Type: application/json' -d '{"键":"值"}'
创建索引别名
curl -X POST 'http://ES-IP:9200/_aliases' \
-H 'Content-Type: application/json' -d '{"actions":[{"add":{"index":"索引名","alias":"索引别名"}}]}'
删除索引别名
curl -X POST 'http://ES-IP:9200/_aliases' \
-H 'Content-Type: application/json' -d '{"actions":[{"remove":{"index":"索引名","alias":"索引别名"}}]}'
2)使用Kibana接入Elasticsearch,可在Kibana的Web页面【管理】-【索引管理】中图形化管理索引
3.ELK Logstash 部署
//20.0.0.110
hostnamectl set-hostname nginx01
bash
1.安装logstash
cd /opt/
rz -E上传logstash-6.7.2.rpm
ls
yum localinstall -y logstash-6.7.2.rpm
cd /usr/share/logstash/
ls
cd bin/
ls
ln -s /usr/share/logstash/bin/logstash /usr/local/bin/
(1)测试 Logstash
Logstash 命令常用选项 | |
---|---|
-f | 通过这个选项可以指定 Logstash 的配置文件,根据配置文件配置 Logstash 的输入和输出流 |
-e | 从命令行中获取,输入、输出后面跟着字符串,该字符串可以被当作 Logstash 的配置(如果是空,则默认使用 stdin 作为输入,stdout 作为输出) |
-t | 测试配置文件是否正确 |
-w | 指定filter线程数量,默认线程数是 5 |
-l | 指定日志文件名称 |
(2)定义输入和输出流
#输入采用标准输入,输出采用标准输出(类似管道),新版本默认使用 rubydebug 格式输出
logstash -e 'input{stdin{}} output {stdout{}}'
www.baidu.com #键入内容(标准输入)
##安装Java环境
java -version
yum -y install java-1.8.0-openjdk*
#使用 Logstash 将信息写入 Elasticsearch 中
logstash -e 'input {stdin{}} output {elasticsearch{hosts=>["20.0.0.100:9200"]}}'
(4)定义 logstash配置文件
Logstash 配置文件基本由三部分组成:input、output 以及 filter(可选,根据需要选择使用)。
(1)logstash filter模块常用的插件
grok:将大文本字段分割成若干个小字段
内置正则匹配格式:%{内置正则:字段名}
自定义正则匹配格式:(?<字段名>自定义正则)
mutate:对logstash收集的日志事件的字段进行格式化处理,
比如rename(重命名字段)、add_field(增加字段)、remove_field(删除字段)、replace(修改字段的值)等
multiline:将多行日志内容合并成一个日志事件内容
pattern(通过正则表达式匹配行)
negate(false|true,是否取反。
false表示不取反,将正则表达式匹配的行按照what的设置进行合并
true表示取反,不将正则表达式匹配的行按照what的设置进行合并)
what(previous|next,previous表示向上合并,next表示向下合并)
date:将logstash收集日志事件的时间戳@timestamp与日志实际的打印时间进行格式统一
1)先配置grok插件分割出日志时间打印时间的字段
2)在date插件配置中用match匹配日志时间字段的时间格式
3)再用target输出给@timestamp字段,进行时间格式统一
//20.0.0.110
ls -l /var/log/messages
chmod a+r /var/log/messages #让 Logstash 可以读取日志
ls -l /var/log/messages
cd /etc/logstash/conf.d/
vim system.conf
input {
file{
path => "/var/log/messages"
type => "system"
start_position => "beginning"
sincedb_path => "/etc/logstash/sincedb_path/log_progress"
add_field => {"log_hostname" => "${HOSTNAME}"}
}
}
#filter{}
output {
elasticsearch { #输出到 elasticsearch
hosts => ["20.0.0.100:9200","20.0.0.130:9200","20.0.0.140:9200"]
#指定 elasticsearch 服务器的地址和端口
index => "syslog-%{+yyyy.MM.dd}" #指定输出到 elasticsearch 的索引格式
}
}
logstash -t -f system.conf
常用参数 | |
---|---|
path | 表示要收集的日志的文件位置,必须使用绝对路径,可使用通配符匹配。如果同时指定多个文件使用 , 号间隔 |
exclude | 排除不想监听的文件 |
type | 指定Event的type字段。若是输入ES时,没有指定document_type,那么这里的type将做为ES中index的type |
start_position | 可以设置为beginning或者end,beginning表示从头开始读取文件,end表示读取最新的,默认是end,这个要和ignore_older一起使用。该选项只在第一次启动logstash时有效 |
ignore_older | 表示了针对多久的文件进行监控,默认一天,单位为秒,可以自己定制,比如默认只读取一天内被修改的文件 |
sincedb_path | 表示文件读取进度的记录,每行表示一个文件,其中记录了inode、主设备号、次设备号以及读取的位置。默认为$HOME/.sincedb* |
sincedb_write_interval | 设置多长时间会写入读取的位置信息,单位为秒 |
add_field | 用于向Event中添加自定义的字段。这里使用了${HOSTNAME},即本机的环境变量 |
delimiter | 文件内容的行分隔符,默认按照"\n"进行Event封装 |
4.ELK Kibana 部署
//20.0.0.140
1.安装 Kibana
cd /opt/
rz -E 上传kibana-6.7.2-x86_64.rpm
ls
yum localinsatll -y kibana-6.7.2-x86_64.rpm
2.设置 Kibana 的主配置文件
cd /etc/kibana/
ls
cp kibana.yml kibana.yml.bak
vim /etc/kibana/kibana.yml
--2--取消注释,Kiabana 服务的默认监听端口为5601
server.port: 5601
--7--取消注释,设置 Kiabana 的监听地址,0.0.0.0代表所有地址
server.host: "0.0.0.0"
--28--取消注释,配置es服务器的ip,如果是集群则配置该集群中master节点的ip
elasticsearch.hosts: ["20.0.0.100:9200","20.0.0.130:9200","20.0.0.140:9200"]
--96--取消注释,配置kibana的日志文件路径(需手动创建),不然默认是messages里记录日志
logging.dest: /var/log/kibana.log
--113--取消注释,指定页面字符格式为中文
i18n.locale: "zh-CN"
3.创建日志文件,启动 Kibana 服务
touch /var/log/kibana.log
chown kibana:kibana !$
systemctl enable --now kibana.service
netstat -natp | grep 5601
http://20.0.0.140:5601
4.验证 Kibana
Management -> Index Pattern -> Create index pattern
管理 -> 索引模式
Index pattern 输入:system-* #在索引名中输入之前配置的 Output 前缀“system”
Next step -> Time Filter field name 选择 @timestamp -> Create index pattern
(1)将 nginx 服务器的日志(访问的、错误的)添加到 Elasticsearch 并通过 Kibana 显示
//20.0.0.110
vim /etc/logstash/conf.d/apache_log.conf
input {
file{
path => "/var/log/nginx/access_log"
type => "nginx_access"
start_position => "beginning"
sincedb_path => "/etc/logstash/sincedb_path/log_progress"
}
file{
path => "/var/log/nginx/error_log"
type => "nginx_error"
start_position => "beginning"
sincedb_path => "/etc/logstash/sincedb_path/log_progress"
}
}
#fillter {}
output {
if [type] == "nginx_access" {
elasticsearch {
hosts => ["20.0.0.100:9200","20.0.0.130:9200","20.0.0.140:9200"]
index => "nginx_access-%{+yyyy.MM.dd}"
}
}
if [type] == "nginx_error" { ##错误日志
elasticsearch {
hosts => ["20.0.0.100:9200","20.0.0.130:9200","20.0.0.140:9200"]
index => "nginx_error-%{+yyyy.MM.dd}"
}
}
}
logstash -t -f nginx_log.conf #检测是否有语法错误
浏览器访问 http://20.0.0.100:5601 登录 Kibana,单击“Index Pattern -> Create Index Pattern”按钮添加索引, 在索引名中输入之前配置的 Output 前缀 apache_access-,并单击“Create”按钮。在用相同的方法添加 apache_error-索引。
选择“Discover”选项卡,在中间下拉列表中选择刚添加的 apache_access-* 、apache_error-* 索引, 可以查看相应的图表及日志信息。
5.ELK优化
(1)logstash优化
1)加大服务器内存和JVM堆内存
2)用多实例做负载均衡
3)使用filebeat替代logstash采集日志数据
(2)elasticsearch优化
因为ES作为日志存储时的特性是:高并发写、读少、接受一定的延时、可容忍部分日志数据的丢失。所以ES会围绕以下几个方面进行优化:
1)对索引进行优化:优化fsync,适当加大刷盘间隔时间(index.translog.sync_interval,默认值为5s,可调整为30s或60s)
优化refresh,适当加大把内存数据写入Lucene的间隔时间(index.refresh_interval,默认值为1s,可调整为5s或10s)
优化merge,根据硬盘的性能适当调整merge的线程数(index.merge.scheduler.max_thread_count,默认值为max,可调整为1,设置为1可允许最多3个并发的merge线程数)
2)优化write线程池配置,减少拒绝任务的情况:修改ES配置文件elasticsearch.yml,设置write线程为 CPU核数+1
thread_pool:
write:
size: N #N为CPU核数+1
3)锁定内存,不让ES使用swap:swapoff -a ,关闭swap
修改内核参数 vm.swappiness=1,使系统尽量不使用swap
修改ES配置文件:bootstrap.memory_lock: true
,启动ES锁定内存
4)适当的减少索引的分片数、副本数
分片数:index.number_of_shards
,默认值为5,索引大小较小时,可调整分片数为3
副本数:index.number_of_replicas
,默认值为1,即每个索引会有一份额外的副本数据,对于日志数据不需要太高的安全性,有1个副本即可,所以可调整副本数为0
6.ELK 的工作原理
(1)在所有需要收集日志的服务器上部署 Logstash;或者先将日志进行集中化管理在日志服务器上,在日志服务器上部署 Logstash。
(2)Logstash 收集日志,将日志格式化并输出到 Elasticsearch 群集中。
(3)Elasticsearch 对格式化后的数据进行索引和存储。
(4)Kibana 从 ES 群集中查询数据生成图表,并进行前端数据的展示。