一、基本概念
ELK 是三个开源项目的首字母缩写,这三个项目分别是:Elasticsearch、Logstash 和 Kibana。
- Elasticsearch 是一个搜索和分析引擎。 Logstash
- 是服务器端数据处理管道,能够同时从多个来源采集数据,转换数据,然后将数据发送到诸如 Elasticsearch 等存储库中。
- Kibana 则可以让用户在 Elasticsearch 中使用图形和图表对数据进行可视化。
二、ELK日志系统数据流图如下
一个完整的集中式日志系统,需要包含以下几个主要特点:
- 收集-能够采集多种来源的日志数据 -
- 传输-能够稳定的把日志数据传输到中央系统 -
- 存储-如何存储日志数据
- 分析-可以支持 UI 分析
- 警告-能够提供错误报告,监控机制
三、ELK+kafka分布式日志流程图
为什么需要使用ELK+kafka实现分布式日志收集?
单纯使用EIK实现分布式日志收集缺点:
- 当产生日志的服务节点越来越多,Logstash也需要部署越来越多,扩展不好。
- 读取IO文件,可能会产生日志丢失。
- 读取文件不是实时性,中间需要引入到Kafka,日志实时发布到Kafka,Logstash订阅并实时获取消息。
zookeeper作为解决分布式一致性问题的工具而被kafka依赖。而分布式模式,即去中心化的集群模式,需要让消费者知道现在有哪些生产者(对于消费者而言,kafka就是生产者)是可用的。如果没了zk消费者如何知道呢?如果每次消费者在消费之前都去尝试连接生产者测试下是否连接成功,效率就会变得很低。
Kafka使用zk的分布式协调服务,将生产者,消费者,消息储存(broker,用于存储信息,消息读写等)结合在一起。同时借助zk,kafka能够将生产者,消费者和broker在内的所有组件在无状态的条件下建立起生产者和消费者的订阅关系,实现生产者的负载均衡。
四、配置图
五、步骤搭建如下
master部署Apache、mysql、kafka、zookeeper服务,并部署logstash
Slave1部署elasticsearch和kibana
Slave2部署elasticsearch
Proxy 部署elasticsearch
三台elasticsearch构成ELS群集
1、部署elasticsearch(这里以slave1为列)
1.1、由于之前配置好的hosts映射,主机名,防火墙
[root@slave1 ~]# rpm --import https://packages.elastic.co/GPG-KEY-elasticsearch
[root@slave1 yum.repos.d]# vi elasticsearch.repo
[elasticsearch-2.x]
name=Elasticsearch repository for 2.x packages
baseurl=http://packages.elastic.co/elasticsearch/2.x/centos
gpgcheck=1
gpgkey=http://packages.elastic.co/GPG-KEY-elasticsearch
enable=1
[root@slave1 yum.repos.d]# yum install elasticsearch -y
[root@slave1 yum.repos.d]# yum install java -y
[root@slave1 yum.repos.d]# java -version
1.2、修改配置文件
[root@slave1 yum.repos.d]# cd /etc/elasticsearch/
[root@slave1 elasticsearch]# ls
elasticsearch.yml logging.yml scripts
[root@slave1 elasticsearch]# cp -p elasticsearch.yml elasticsearch.yml.bak
[root@slave1 elasticsearch]# egrep -v "^$|^#" elasticsearch.yml
cluster.name: elk-cluster #集群名称
node.name: slave1 #当前节点名
path.data: /data/elk-data #数据存储位置(目录不存在,需要创建)
path.logs: /var/log/elasticsearch/ #日志文件存放的位置
bootstrap.memory_lock: false
## true:允许内存中的数据交还给SWAP,flase:不允许内存中的数据交还给SWAP。 选择false,因为swap分区实在硬盘上建立的,如果内存不够,数据溢出,分到硬盘上的话,会影响速度
network.host: 0.0.0.0 #监听地址,0.0.0.0表示网段
http.port: 9200 #ES端口号,外部通讯的端口。PS:9300是集群内部通讯端口
discovery.zen.ping.unicast.hosts: ["slave1", "slave2","proxy"] #集群中包含的节点名
[root@slave1 elasticsearch]# mkdir -p /data/elk-data
[root@slave1 elasticsearch]# id elasticsearch
uid=997(elasticsearch) gid=994(elasticsearch) 组=994(elasticsearch)
[root@slave1 elasticsearch]# chown elasticsearch.elasticsearch /data/elk-data/
1.3、开启服务并设置开机自启动
[root@slave1 elasticsearch]# systemctl start elasticsearch.service
[root@slave1 ~]# systemctl enable elasticsearch
[root@slave1 elasticsearch]# netstat -anpt | grep 9200
[root@slave1 elasticsearch]# netstat -anpt | grep 9200
tcp6 0 0 :::9200 :::* LISTEN 10128/java
1.4、网页测试
1.5、群集健康状态检查
1.6、群集属性状态,可以看到群集内部通信端口9300
2、安装elasticsearch-head插件(可视化工具,以slave1为列)
2.1、安装es_head插件
root@slave1-elasticsearch]#/usr/share/elasticsearch/bin/plugin install mobz/elasticsearch-head
安装位置:/usr/share/elasticsearch/plugins/head
2.2、验证插件
2.3、创建索引
创建一个索引信息,创建索引为index-demo,类型为test,可以看到成功创建,这里的数据会被存储到ES集群中。
[root@slave1 head]# curl -XPUT 'localhost:9200/index-demo/test/1?pretty&pretty' -H 'content-Type: application/json' -d '{"user":"zhangsan","mesg":"hello}'
刷新一下,可以看到存储的分片处理与备份,暂时不存在节点间的主备关系。加粗的是主文件的,细框的是备份文件,不论哪个节点宕机,存储都不会丢失,很安全,三个节点共10个分片
2.4、利用组件的复合查询进行索引的创建、查询、删除
创建索引index-demo2
提交后查看:
可看到分片存储情况
查询
设置主备节点,slave1为主,slave2为备,proxy为备
先关闭slave2、proxy的elasticsearch,重启slave1服务,再开启slave2、proxy (主备由先后开启服务决定),刷新查看分片情况:
3、elasticsearch的监控组件安装
3.1、生产环境中要修改
[root@slave1 ~]# vi /etc/security/limits.conf
* soft nofile 65535
* hard nofile 65535
3.2、解决锁内存
#解决de-01和node-02日志提示不让锁内存
#末尾插入
elasticsearch soft memlock unlimited
elasticsearch hard memlock unlimited
3.3、开启服务并设置开机自启动
systemctl stop elasticsearch.service
systemctl start elasticsearch.service
3.4、访问测试
访问:http://192.168.254.241:9200/_plugin/kopf/#!/cluster
4、 部署Apache、Mysql、zookeeper、kafka、logstash(master部署)
4.1、安装httpd
[root@master ~]# yum install httpd -y
4.1.1、启动并设置开机自启动
[root@master ~]# systemctl start httpd
[root@master ~]# systemctl enable httpd
4.1.2、查看日志
[root@master ~]# ll /var/log/httpd/
总用量 2544
-rw-r--r-- 1 root root 2588919 1月 7 15:10 access_log
-rw-r--r-- 1 root root 11353 1月 8 10:28 error_log
4.2、安装mysql
4.2.1、下载mysql_rpm包
wget http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm
rpm -ivh mysql-community-release-el7-5.noarch.rpm
4.2.2、添加mysql_repo源
[root@master ~]# ls -1 /etc/yum.repos.d/mysql-community*
/etc/yum.repos.d/mysql-community.repo
/etc/yum.repos.d/mysql-community-source.repo
4.2.3、下载mysql-server端
[root@master ~]#yum install mysql-server
4.2.4、启动服务并设置开机自启
[root@master ~]#systemctl start mysqld
[root@master ~]#systemctl enabled mysqld
4.2.5、登陆mysql、修改密码
直接输入 mysql 登陆设置密码:
mysql>use mysql
mysql>update user SET password=PASSWORD('000000') WHERE user='root' AND host = 'localhost';
mysql>grant all privileges on *.* TO 'root'@'%' IDENTIFIED BY '000000';
mysql>flush privileges;
4.3、安装zookeeper
Kafka环境依赖于Zookeeper,安装Kafka前需要安装Zookeeper。这里采用docker安装。
4.3.1、安装docker依赖包
[root@master ~]# yum -y install gcc && yum -y install gcc-c++
4.3.2、安装docker并配置加速器
[root@master ~]# yum install docker -y
[root@master ~]# vim /etc/docker/daemon.json
{
"registry-mirrors": ["https://xxxxxxx.mirror.aliyuncs.com"]
}
4.3.3、设置开机自启动
[root@master ~]# systemctl start docker
[root@master ~]# systemctl enable docker
[root@master ~]# systemctl status docker
4.3.4、下载zookeeper镜像
[root@master ~]# docker pull wurstmeister/zookeeper
4.3.5、运行zookeeper环境
[root@master ~]# docker run --privileged=true -d --name zookeeper -p 2181:2181 -t wurstmeister/zookeeper
[root@master ~]# docker ps
4.4、安装kafka
4.4.1、下载kafka镜像
[root@master ~]# docker pull wurstmeister/kafka
4.4.2、编写shell启动kafka
[root@master ~]# vim ka.sh
docker run --name kafka \
--privileged=true \
-p 9092:9092 \
-e KAFKA_BROKER_ID=0 \
-e KAFKA_ZOOKEEPER_CONNECT=192.168.254.240:2181 \
-e KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://192.168.254.240:9092\
-e KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092 \
-d wurstmeister/kafka
4.4.3、授权启动并验证
[root@master ~]# chmod o+x ka.sh
[root@master ~]# docker ps
4.4.4、进入kafka容器
[root@master ~]# docker exec -it kafka /bin/bash
4.4.5、创建topic主题验证
bash-5.1# /opt/kafka/bin/kafka-topics.sh --create --zookeeper 192.168.254.240:2181 --replication-factor 1 --partitions 1 --topic order_log
4.4.6、查询创建topic主题
bash-5.1# /opt/kafka/bin/kafka-topics.sh --list --zookeeper 192.168.254.240:2181
4.5、安装logstash
4.5.1、准备yum源
[root@master ~]# rpm --import https://packages.elastic.co/GPG-KEY-elasticsearch
[root@master ~]# cd /etc/yum.repos.d/
4.5.2、编写logstash本地源
[root@master yum.repos.d]# vim logstash.repo
[logstash-2.1]
name=Logstash repository for 2.1.x packages
baseurl=http://packages.elastic.co/logstash/2.1/centos
gpgcheck=1
gpgkey=http://packages.elastic.co/GPG-KEY-elasticsearch
enable=1
4.5.3、下载logstash
[root@master ~]# yum install logstash -y
[root@master ~]# ln -s /opt/logstash/bin/logstash /usr/local/bin/
4.5.4、开启服务并设置开机自启动
[root@master ~]# systemctl start logstash.service
[root@master ~]# systemctl enable logstash.service
4.5.5、下载java
[root@master ~]# yum install java -y
[root@master ~]# java -version
openjdk version "1.8.0_292"
OpenJDK Runtime Environment (build 1.8.0_292-b10)
OpenJDK 64-Bit Server VM (build 25.292-b10, mixed mode)
logstash(Apache)与elasticsearch (node)功能是否正常,做对接测试
4.5.6、命令单行操作
logstash字段描述解释:
-f通过这个选项可以指定logstash的配置文件,根据配置文件配置logstash
-e后面跟着字符串该字符串可以被当做logstash的配置(如果是””,则默认使用stdin 做为输入、stdout作为输出)
-t测试配置文件是否正确,然后退出
定义输入和输出流,类似管道,并验证输入输出
注:
-e 执行操作
input 标准输入
{ input } 插件
output 标准输出
{ stdout } 插件
[root@master ~]# /opt/logstash/bin/logstash -e 'input { stdin{} } output { stdout{} }'
Settings: Default filter workers: 1
Logstash startup completed
www.baidu.com
2022-01-14T07:36:47.483Z master www.baidu.com
www.taobao.com
2021-01-14T07:36:57.405Z master www.taobao.com
验证输出格式化,使用 rubydebug 显示详细信息输出,code为一种编解码
[root@master ~]# /opt/logstash/bin/logstash -e 'input { stdin{} } output { stdout {codec => rubydebug} }'
Settings: Default filter workers: 1
Logstash startup completed
user123
{
"message" => "user123",
"@version" => "1",
"@timestamp" => "2022-01-14T02:26:35.949Z",
"host" => "master"
}
使用logstash将信息写入elasticsearch输入输出对接
[root@master ~]# /opt/logstash/bin/logstash -e 'input { stdin{} } output { elasticsearch { hosts => ["192.168.254.241:9200"] } }'
Settings: Default filter workers: 1
Logstash startup completed
be brave
nevwe on can
hei test 123455
在slave1上查看elasticsearch网页,成功输出
写入ES和同时生成文本
[root@master ~]# /opt/logstash/bin/logstash -e 'input { stdin{} } output { elasticsearch { hosts => ["192.168.254.241:9200"] } stdout { codec => rubydebug } }'
Settings: Default filter workers: 1
Logstash startup completed
Life lies in struggle
{
"message" => "Life lies in struggle",
"@version" => "1",
"@timestamp" => "2022-01-14T02:35:35.322Z",
"host" => "master"
}
{
"message" => "",
"@version" => "1",
"@timestamp" => "2022-01-14T02:35:35.333Z",
"host" => "master"
}
Logstash的配置和文件编写
测试系统日志能否被采集
[root@master conf.d]# vim /etc/logstash/conf.d/system.conf
input {
file{
path => "/var/log/messages"
type => "system" #系统类型
start_position => "beginning"
}
}
output {
elasticsearch {
hosts => ["192.168.254.241:9200","192.168.254.242:9200","192.168.254.243:9200"]
index => "system-%{+YYYY.MM.dd}"
}
}
[root@master ~]# logstash -f /etc/logstash/conf.d/system.conf #指定logstash配置文 件,输出系统日志
重启slave1
[root@slave1 ~]# systemctl restart elasticsearch.service
刷新网页,查看索引数据,成功输出了系统日志
查看索引切片情况
4.5.7、多行模式
[root@slave1 ~] vim multiline.conf
input{
Stdin {
Codec => multiline {//多行模式。碰到指定模式之前,日志为无效。遇见模式时才将模式之前的信息,收集成日志。
pattren => “^\[” //模式
negate => true //无效
what => “previous” //之前
}
}
}
output{
stdout {
codec => “rubydebug”
}
}
Logstash通过订阅topic,获取日志并输入到ES(Input来源Kafka,Output到ES)
[root@master conf.d]# vim /etc/logstash/conf.d/kafka-logs.conf
input{
stdin{
}
}
output{
kafka{
topic_id =>"order_log"
bootstrap_servers => "192.168.254.240:9092"
batch_size => 5
}
stdout{
codec => "rubydebug"
}
}
测试是否能接收到日志
[root@master conf.d]# logstash -f /etc/logstash/conf.d/kafka-logs.conf
在kafka中查看写入数据:
bash-5.1# ./kafka-console-consumer.sh --bootstrap-server 192.168.254.240:9092 --from-beginning --topic order_log
5、在slave1上安装kibana
5.1、安装部署
[root@slave1 ~]# mkdir -p /usr/local/kibana
[root@slave1~]#wget https://download.elastic.co/kibana/kibana/kibana-4.3.1-linux-x64.tar.gz
[root@slave1 ~]# tar -zxvf kibana-4.3.1-linux-x64.tar.gz -C /usr/local/kibana/
5.2、修改配置文件
[root@slave1 ~]# vi /usr/local/kibana/kibana-4.3.1-linux-x64/config/kibana.yml
[root@slave1~]#egrep -v "^$|^#" /usr/local/kibana/kibana-4.3.1-linux-x64/config/kibana.yml
server.port: 5601 #服务器端口
server.host: "0.0.0.0" #监听地址
elasticsearch.url: "http://192.168.254.241:9200" #和ES建立联系
kibana.index: ".kibana" #建立索引
[root@slave1 ~]# yum install screen -y
5.3、启动并监听
[root@slave1 ~]# /usr/local/kibana/kibana-4.3.1-linux-x64/bin/kibana #启动监听
5.4、对接system系统日志
访问网页:
Discover里查看日志,图表式显示
5.5、对接Apache日志(master节点)
5.5.1、编写logstash ->apache_log
[root@master ~]# cat /etc/logstash/conf.d/apache-log.conf
input { #输入Apache日志
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 { #输出到ES
if [type] == "access" {
elasticsearch {
hosts => ["192.168.254.241:9200","192.168.254.242:9200","192.168.254.243:9200"]
index => "apache_access.%{+YYYY.MM.dd}"
}
}
if [type] == "error" {
elasticsearch {
hosts => ["192.168.254.241:9200","192.168.254.242:9200","192.168.254.243:9200"] index => "apache_error.%{+YYYY.MM.dd}"
}
}
}
#在logstash上输入Apache日志,输出到elasticsearch
5.5.2、启动脚本,查看索引
[root@master ~]# logstash -f /etc/logstash/conf.d/apache-log.conf #启动脚本
刷新ES网页,查看索引,建议先访问apache页面,否则可能刷新不出来
5.5.3、kibana创建Apache索引图表
5.6、对接mysql日志(master)
5.6.1、编写logstash->mysql_log
[root@master conf.d]# vim /etc/logstash/conf.d/mysql-log.conf
input { #输入mysql日志
file{
path => "/var/log/mysqld.log"
type => "access"
start_position => "beginning"
}
}
output { #输出到ES
if [type] == "access" {
elasticsearch {
hosts => ["192.168.254.241:9200"]
index => "mysql_access.%{+YYYY.MM.dd}"
}
}
}
#在logstash上输入Mysql日志,输出到elasticsearch
5.6.2、启动并对mysql进行操作,查看索引
[root@master ~]# logstash -f /etc/logstash/conf.d/mysql-log.conf #启动脚本
刷新ES网页,查看索引,先对mysql随便进行一个操作,否则可能刷新不出来
5.6.3、kibana创建mysql索引图表
5.7、对接kafka+logstash+es针对apache日志
利用kafka通过Logstash订阅topic,获取日志并输入到ES(Input来源Kafka,Output到ES),这里测试对接apache的access日志
5.7.1、编写dataTokafka.conf
[root@master conf.d]# vim /etc/logstash/conf.d/dataTokafka.conf
input {
file {
codec => plain {
charset => "UTF-8"
}
path => "/etc/httpd/logs/access_log"
discover_interval => 5
start_position => "beginning"
}
}
output {
kafka {
topic_id => "order_log"
codec => plain {
format => "%{message}"
charset => "UTF-8"
}
bootstrap_servers => "192.168.254.240:9092"
}
}
5.7.2、编写dataToElastic.conf
[root@master conf.d]# vim /etc/logstash/conf.d/dataToElastic.conf
input {
kafka {
type => "acces"
auto_offset_reset => "smallest"
codec => "plain"
group_id => "elas2"
topic_id => "order_log"
zk_connect => "192.168.254.240:2181"
}
}
filter {
if [type] == "acces" {
mutate {
split => { "message" => "|" }
add_field => {
"id" => "%{message[0]}"
"time" => "%{message[1]}"
"ip" => "%{message[2]}"
"user" => "%{message[3]}"
}
remove_field => [ "message" ]
}
}
}
output {
if [type] == "acces" {
elasticsearch {
index => "apache_acces.%{+YYYY.MM.dd}"
codec => plain {
charset => "UTF-8"
}
hosts => ["192.168.254.241:9200","192.168.254.242:9200","192.168.254.243:9200"]
}
}
}
5.7.3、启动循序解释
先启动dataTokafka,conf,监听access_log,然后在启动dataToElastic.conf,将kafka数据采集 到elasticsearch
[root@master ~]# logstash -f /etc/logstash/conf.d/dataTokafka.conf
[root@master ~]# logstash -f /etc/logstash/conf.d/dataToElastic.conf
5.7.4、启动并查看网页索引
网页中查看:
5.7.5、kabana创建索引