部署ELK+Filebeat日志收集分析系统
需求背景:
- 业务发展越来越庞大,服务器越来越多
- 各种访问日志、应用日志、错误日志量越来越多,导致运维人员无法很好的去管理日志
- 开发人员排查问题,需要到服务器上查日志,不方便
- 运营人员需要一些数据,需要我们运维到服务器上分析日志
1、环境准备
1.1 环境规划
环境准备的机器
IP地址 | 主机名 | 部署服务 |
---|---|---|
192.168.1.128 | es-01 | elasticsearch、kibana |
192.168.1.129 | es-02 | elasticsearch、logstash |
192.168.1.130 | es-03 | elasticsearch、filebeat |
架构图
1.2 软件版本下载
注意:这边根据实际情况
3台机器全部安装jdk1.8,因为elasticsearch是java开发的
jdk 1.8.0_131
elasticsearch-7.13.2-linux-x86_64.tar.gz
kibana-7.13.2-linux-x86_64.tar.gz
logstash‐7.13.2‐linux‐x86_64.tar.gz
filebeat‐7.13.2‐linux‐x86_64.tar.gz
安装包下载
https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.13.2-linux-x86_64.tar.gz
https://artifacts.elastic.co/downloads/kibana/kibana-7.13.2-linux-x86_64.tar.gz
https://artifacts.elastic.co/downloads/logstash/logstash-7.13.2-linux-x86_64.tar.gz
https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.13.2-linux-x86_64.tar.gz
2、部署ElasticSearch集群
2.1 安装ElasticSearch
三个节点都需安装
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-7.13.2-linux-x86_64.tar.gz
tar zxf elasticsearch-7.13.2-linux-x86_64.tar.gz -C /usr/local/
mv /usr/local/elasticsearch-7.13.2 /usr/local/elasticsearch
2.1.1 配置es-01节点
[[email protected] ~]# grep '^[a-z]' /usr/local/elasticsearch/config/elasticsearch.yml
cluster.name: my-es
node.name: node-1
node.master: true
node.data: true
path.data: /data/elasticsearch/data
path.logs: /data/logs/elasticsearch
network.host: 192.168.1.128
http.port: 9200
discovery.seed_hosts: ["192.168.1.128","192.168.1.129","192.168.1.130"] #指定集群成员,用于主动发现他们, 所有成员都要写进来,包括自己,每个节点中应该写一样的信息
cluster.initial_master_nodes: ["node-1"]
http.cors.enabled: true # 是否支持跨域,默认为false
http.cors.allow-origin: "*" # 当设置允许跨域,默认为*,表示支持所有域名,如果我们只是允许某些网站能访问,那么可以使用正则表达式。比如只允许本地地址。 /https?:\/\/localhost(:[0-9]+)?/
2.1.2 配置es-02节点
只是配置文件中node.name、node.master和network.host不同,其他操作方式一致
[[email protected] ~]# grep '^[a-z]' /usr/local/elasticsearch/config/elasticsearch.yml
cluster.name: my-es
node.name: node-2
node.master: false
node.data: true
path.data: /data/elasticsearch/data
path.logs: /data/logs/elasticsearch
network.host: 192.168.1.129
http.port: 9200
discovery.seed_hosts: ["192.168.1.128","192.168.1.129","192.168.1.130"]
cluster.initial_master_nodes: ["node-1"]
http.cors.enabled: true
http.cors.allow-origin: "*"
2.1.3 配置es-03节点
只是配置文件中node.name、node.master和network.host不同,其他操作方式一致
[[email protected] ~]# grep '^[a-z]' /usr/local/elasticsearch/config/elasticsearch.yml
cluster.name: my-es
node.name: node-3
node.master: false
node.data: true
path.data: /data/elasticsearch/data
path.logs: /data/logs/elasticsearch
network.host: 192.168.1.130
http.port: 9200
discovery.seed_hosts: ["192.168.1.128","192.168.1.129","192.168.1.130"]
cluster.initial_master_nodes: ["node-1"]
http.cors.enabled: true
http.cors.allow-origin: "*"
2.2 创建目录及用户
三台机器都需创建
groupadd elastic && useradd elastic -g elastic -p elasticsearch
mkdir -p /data/elasticsearch/data /data/logs/elasticsearch
chown -R elastic:elastic /data/elasticsearch/data /data/logs/elasticsearch/ /usr/local/elasticsearch
2.3 启动集群ElasticSearch
su elastic -c "/usr/local/elasticsearch/bin/elasticsearch -d"
检查集群环境日志是否正常
2.4 查看集群状态
[[email protected] ~]# curl "http://192.168.1.128:9200/_cluster/health?pretty"
{
"cluster_name" : "my-es",
"status" : "green", # 为green则代表健康没问题,如果是yellow或者red则是集群有问题
"timed_out" : false, # 是否有超时
"number_of_nodes" : 3, # 集群中的节点数量
"number_of_data_nodes" : 3, # 集群中data节点的数量
"active_primary_shards" : 0,
"active_shards" : 0,
"relocating_shards" : 0,
"initializing_shards" : 0,
"unassigned_shards" : 0,
"delayed_unassigned_shards" : 0,
"number_of_pending_tasks" : 0,
"number_of_in_flight_fetch" : 0,
"task_max_waiting_in_queue_millis" : 0,
"active_shards_percent_as_number" : 100.0
}
检查没有问题后,我们的es集群就搭建完成了,很简单。
3、部署Kibana
3.1 安装Kibana
[[email protected] ~]# https://artifacts.elastic.co/downloads/kibana/kibana‐7.13.2‐linux‐x86_64.tar.gz
[[email protected] ~]# tar zxf kibana-7.13.2-linux-x86_64.tar.gz -C /usr/local/
[[email protected] ~]# mv /usr/local/kibana-7.13.2-linux-x86_64/ /usr/local/kibana
3.2 配置主配置文件
[[email protected] ~]# grep '^[a-z]' /usr/local/kibana/config/kibana.yml
server.port: 5601
server.host: "192.168.1.128" # 配置监听ip
server.name: "elk-application"
elasticsearch.hosts: ["http://192.168.1.128:9200"] # # 配置es服务器的ip,如果是集群则配置该集群中主节点的ip
logging.dest : /data/logs/kibana/kibana.log # 配置kibana的日志文件路径,不然默认是messages里记录日志
i18n.locale: "zh-CN" # 设置页面的字体为中文
3.3 创建用于运行 kibana 的普通用户
默认情况下, kibana 不允许使用 root 用户运行,所以这里创建一个普通用户
[[email protected] ~]# groupadd kibana && useradd kibana -g kibana -p kibana
3.4 创建程序使用到的目录并赋予权限
[[email protected] ~]# mkdir /data/logs/kibana /run/kibana
[[email protected] ~]# chown -R kibana:kibana /usr/local/kibana /data/logs/kibana/ /run/kibana
3.5 启动kibana服务,并检查进程和监听端口
[[email protected] ~]# nohup su kibana -c "/usr/local/kibana/bin/kibana" &
[[email protected] ~]# ps aux|grep kibana
root 91686 0.0 0.1 191744 2340 pts/1 S 13:37 0:00 su kibana -c /usr/local/kibana/bin/kibana
kibana 91688 8.3 2.3 614116 44604 ? Ssl 13:37 0:00 /usr/local/kibana/bin/../node/bin/node /usr/local/kibana/bin/../src/cli/dist
kibana 91700 90.4 5.9 899460 111544 ? Rl 13:37 0:04 /usr/local/kibana/node/bin/node --preserve-symlinks-main --preserve-symlinks /usr/local/kibana/src/cli/dist
root 91716 0.0 0.0 112720 980 pts/0 S+ 13:37 0:00 grep --color=auto kibana
[[email protected] ~]# netstat -lntp |grep 5601
tcp 0 0 192.168.1.128:5601 0.0.0.0:* LISTEN 91700/node
注:由于kibana是使用node.js开发的,所以进程名称为node
然后在浏览器里进行访问,如:
http://192.168.1.128:5601/
,由于我们并没有安装x-pack,所以此时是没有用户名和密码的,可以直接访问的:
到此我们的kibana就安装完成了,很简单,接下来就是安装logstash,不然kibana是没法用的。
4、部署Filebeat
4.1 Filebeat 安装
[[email protected] ~]# wget https://artifacts.elastic.co/downloads/beats/filebeat/filebeat-7.13.2-linux-x86_64.tar.gz
[[email protected] ~]# tar zxf filebeat-7.13.2-linux-x86_64.tar.gz -C /usr/local/
[[email protected] ~]# mv /usr/local/filebeat-7.13.2-linux-x86_64/ /usr/local/filebeat
Filebeat启动管理
1.前台运行
采用前台运行的方式查看 Filebeat 获取的日志结果
2.后台运行
使用 nohup 方式启动 Filebeat 到后台 ,日志结果可查看 nohup.out 文件
使用 systemd 管理的后台方式启动 Filebeat 进程不能查看输出日志,测试阶段误用
配置 systemd 方式的 Filebeat 启动管理文件
[[email protected] filebeat]# vim /usr/lib/systemd/system/filebeat.service
[Unit]
Description=Filebeat sends log files to Logstash or directly to Elasticsearch.
Wants=network-online.target
After=network-online.target
[Service]
ExecStart=/usr/local/filebeat/filebeat -c /usr/local/filebeat/filebeat.yml
Restart=always
[Install]
WantedBy=multi-user.target
[[email protected] filebeat]# systemctl daemon-reload
[[email protected] filebeat]# systemctl start filebeat
4.2 Filebeat 简单使用
准备测试数据
94.16.136.28 - - [04/Jun/2021:16:28:22 +0800] "POST /captcha/getPic HTTP/1.1" "-" 200 22062 "https://xxx.com/index" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)Chrome/90.0.443
0.212 Safari/537.36" "-" "192.168.0.75:1800" "0.090" 0.090
配置 Filebeat 的输入和输出
[[email protected]-03 ~]# cat /usr/local/filebeat/filebeat.yml
filebeat.inputs:
- type: log
enabled: true
paths:
- /data/logs/nginx/*.log # 指定需要收集日志的路径,支持通配符可以写多个
filebeat.config.modules:
path: ${path.config}/modules.d/*.yml # 内置的收集日志的模块配置文件的存放路径
reload.enabled: false # 当模块的配置文件有更新时,此程序是否要自动加载, false 不加载, true 加载
setup.template.settings:
index.number_of_shards: 1
output.logstash: # 输出到 logstash
hosts: ["192.168.1.129:5044"]
processors:
- add_host_metadata: # 添加此主机的源数据信息到输出数据中,比如 IP MAC OS 等信息
when.not.contains.tags: forwarded
- add_cloud_metadata: ~
- add_docker_metadata: ~
- add_kubernetes_metadata: ~
运行观察日志输出
找不到配置文件可使用
-c
指定配置文件位置
[[email protected] ~]# /usr/local/filebeat/filebeat -c /usr/local/filebeat/filebeat.yml
Filebeat 进程日志
filebeat 本身运行日志默认位置 /usr/local/filebeat/logs/filebeat
要修改 Filebeat 的日志路径,可以添加如下内容在配置文件 filebeat.yml 中实现
# ================================== Logging ===================================
# Sets log level. The default log level is info.
# Available log levels are: error, warning, info, debug
#logging.level: debug
path.logs: /var/log/ # 添加此行即可
这样设置后, filebeat 启动后,日志的目录是 /var/log/ , 日志的文件名为 filebeat , 每次启动或者重启程序会生
成一个新的日志文件 filebeat , 旧的日志命名为 filebeat.1 依次类推。
4.3 专用日志搜集模块
查看可启用的模块列表
[[email protected] ~]# /usr/local/filebeat/filebeat -c /usr/local/filebeat/filebeat.yml modules list
Enabled:
nginx
Disabled:
activemq
apache
auditd
模块配置文件存储位置
[[email protected] modules.d]# pwd
/usr/local/filebeat/modules.d
[[email protected] modules.d]# ls
......
禁用模块
[[email protected] modules.d]# /usr/local/filebeat/filebeat -c /usr/local/filebeat/filebeat.yml modules disable 模块名
启用模块
[[email protected] modules.d]# /usr/local/filebeat/filebeat -c /usr/local/filebeat/filebeat.yml modules enable 模块名
情景 1:使用模块默认的日志路径
修改
modules.d/nginx.yml
文件内容如下:
‐ module: nginx
access:
enabled: true
error:
enabled: true
nginx 模块搜集日志的默认路径是 :
/var/log/nginx/access.log*
/var/log/nginx/error.log*
情景 2:使用非默认路径(适用于所有的模块)
假如所要搜集的日志真实路径和日志收集模块默认的路径不一致,可以配置
var.paths:
属性进行配置。
var.paths
接收的值是一个包含一个以上的日志绝对路径列表。接收的值是一个数组
用于给日志文件设置自定义路径的。如果不设置此选项, Filebeat 将根据您的操作系统选择路径选择使用默认值
可以使用如下方式配置:
‐ module: nginx
access:
enabled: true
var.paths: ["/data/nginx/log/nginx/access.log*", "/data/nginx/log/error.log*"]
或者下面的方式 :
‐ module: nginx
access:
enabled: true
var.paths:
‐ "/data/nginx/log/nginx/access.log*"
‐ "/data/nginx/log/error.log*"
⚠ 注意:
var.paths
指定的路径,是以追加的方式和模块默认路径合并到一起的,也就是说假如模块的默认路径有
具体的日志文件
/var/log/nginx/access.log
。 这里 var.paths 也配置了路径
/tmp/accesslog
,那么最终
Filebeat 收集的日志路径将会是 :
- /var/log/nginx/access.log
- /tmp/accesslog
测试:调用模块进行测试:
./filebeat -e
配置 output
Filebeat 是用于搜集日志,之后把日志推送到某个接收的系统中的,这些系统或者装置在 Filebeat 中称为
output
output 类型 :
- console 终端屏幕
- elasticsearch 存放日志,并提供查询
- logstash 进一步对日志数据进行处理
- kafka 消息队列
⚠ filebeat 运行的时候,以上的 output 只可配置其中的一种。
具体配置方式是编辑主配置文件 :
/usr/local/filebeat/filebeat.yml
注意:注释掉其他的 output
输出到 console
输出完整 JSON 数据
‐ module: nginx
access:
enabled: true
var.paths: ["/data/nginx/log/nginx/access.log*", "/data/nginx/log/error.log*"]
==========================================================
‐ module: nginx
access:
enabled: true
var.paths:
‐ "/data/nginx/log/nginx/access.log*"
‐ "/data/nginx/log/error.log*"
output.console:
pretty: true
进入到 filebeat 的安装目录下,执行命令前台运行
./filebeat
如果只想输出完整 Json 数据中的某些字段
output.console:
codec.format:
string: '%{[@timestamp]} %{[message]}'
其他输出目标:
输出到 elasticsearch
output.elasticsearch:
hosts: ['http://192.168.1.128:9200', 'http://192.168.1.129:9200']
输出到 logstash
output.logstash:
hosts: ["192.168.1.129:5044"]
5、部署Logstash
5.1 安装logstash
[[email protected] ~]# wget https://artifacts.elastic.co/downloads/logstash/logstash-7.13.2-linux-x86_64.tar.gz
[[email protected] ~]# tar zxf logstash-7.13.2-linux-x86_64.tar.gz -C /usr/local/
[[email protected] ~]# mv /usr/local/logstash-7.13.2/ /usr/local/logstash
5.2 测试运行
运行最基本的 Logstash 管道来测试 Logstash 安装。
Logstash 管道具有两个必需元素 input 和output ,以及一个可选元素 filter 。输入插件使用来自源的数据,过滤器插件根据你的指定修改数据,输出插件将数据写入目标。
进入 Logstash 的安装主目录下执行:
[[email protected] logstash]# ./bin/logstash -e ""
-e 选项用于设置 Logstash 处理数据的输入和输出
-e '' 等同于 -e input { stdin { type => stdin } } output { stdout { codec => rubydebug } }
input { stdin { type => stdin } }
表示 Logstash 需要处理的数据来源来自于标准输入设备
output { stdout { codec => rubydebug } }
表示 Logstash 把处理好的数据输出到标准输出设备
稍等片刻,当看到屏幕上输出如下字样,即可尝试使用键盘输入 hello 字样
[2021-08-15T07:37:10,525][INFO ][logstash.agent ] Successfully started Logstash API endpoint {:port=>9600}
输入 hello 即会立刻输出配格式化后的数据信息
-
字段对应的值是 Logstash 接收到的一行完整的数据message
-
是版本信息,可以用于建立索引使用@version
-
处理此数据的时间戳,可以用于建立索引和搜索@timestamp
-
就是之前type
中设置的值,这个值可以任意修改,但是, type 是内置的变量,不能修改,用于建立索引和条件判断等input
-
表示从那个主机过来的数据hosts
5.3 配置输入和输出
生产中, Logstash 管道要复杂一些:它通常具有一个或多个输入,过滤器和输出插件。
本部分中,将创建一个 Logstash 管道,该管道使用标准输入来获取 Apache Web 日志作为输入,解析这些日志以从
日志中创建特定的命名字段,然后将解析的数据输出到标准输出(屏幕上)。并且这次无需在命令行上定义管道配
置,而是在配置文件中定义管道。
创建任意一个文件,并写入如下内容,作为 Logstash 的管道配置文件
[[email protected] logstash]# vim /usr/local/logstash/config/first -pipeline.conf
input {
stdin { }
}
output {
stdout {}
}
配置文件语法测试
bin/logstash ‐f config/first‐pipeline.conf ‐‐config.test_and_exit
或
-t
- -f 用于指定管道配置文件。
运行如下命令启动 Logstash
[[email protected] logstash]# bin/logstash ‐f config/first‐pipeline.conf
启动后复制如下内容到命令行中,并按下回车键
使用 Grok 过滤器插件解析 Web 日志
现在有了一个工作管道,但是日志消息的格式不是理想的。你想解析日志消息 ,以便能从日志中创建特定的命名字段。为此,应该使用 grok 过滤器插件。
使用 grok 过滤器插件,可以将非结构化日志数据解析为结构化和可查询的内容。
grok 会根据你感兴趣的内容分配字段名称,并把这些内容和对应的字段名称进行绑定。
这里使用的模式是
%{COMBINEDAPACHELOG}
{COMBINEDAPACHELOG
使用以下模式从 Nginx 日志中构造行:
并且这里要想实现修改配置文件之后自动加载它,不能配置
input
为
stdin
。 所以, 这里使用了
file
,创建示例日志文件
56.32.126.78 - - [04/Jun/2021:16:28:22 +0800] "POST /a/gsg HTTP/1.1" "-" 200 22062 "https://xxxx.com/index" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)Chrome/90.0.4430.212 Safari/537.36" "-" "192.168.0.75:1820" "0.090" 0.090
修改好的管道配置文件如下:
[[email protected] logstash]# vim config/first-pipeline.conf
input {
file {
path => ["/data/logs/nginx/access.log"]
start_position => "beginning"
}
}
filter {
grok { # 对 web 日志进行过滤处理,输出结构化的数据
# 在 message 字段对应的值中查询匹配上 COMBINEDAPACHELOG
match => { "message" => "%{COMBINEDAPACHELOG}"}
}
}
output {
stdout {}
}
match => { "message" => "%{COMBINEDAPACHELOG}"}
的意思是: 当匹配到 “message” 字段时,用户模式
"COMBINEDAPACHELOG}"
进行字段映射。
配置完成后,再次进行验证
[[email protected] logstash]# ./bin/logstash -f config/first-pipeline.conf
下面输出的内容
会发现原来的非结构化数据,变为结构化的数据了。
原来的 message 字段仍然存在,假如你不需要它,可以使用 grok 中提供的常用选项之一:
remove_filed 来移除这个字段。 remove_field 可以移除任意的字段,它可以接收的值是一个数组。
rename 可以重新命名字段
修改后管道配置文件如下:
[[email protected] logstash]# cat /usr/local/logstash/config/first-pipeline.conf
input {
file {
path => ["/data/logs/nginx/access.log"]
start_position => "beginning"
}
}
filter {
grok { match => { "message" => "%{COMBINEDAPACHELOG}"} }
# 重写字段
mutate { rename => { "clientip" => "cip" } }
# 去掉没用字段
mutate { remove_field => ["message","input_type","@version","@timestamp"] }
}
output {
stdout {}
}
增加新日志,再次测试,你会发现 message 不见了 ,而且 clientip 重命名成了 cip :
5.4 配置logstash从filebeat 读取数据存储到es集群
[[email protected]-02 logstash]# cat config/first-pipeline.conf
input {
# file {
# path => ["/data/logs/nginx/access.log"]
# start_position => "beginning"
# }
beats {
port => 5044
}
}
filter {
grok { match => { "message" => "%{COMBINEDAPACHELOG}"} }
# mutate { rename => { "clientip" => "cip" } }
# mutate { remove_field => ["message","input_type","@version","@timestamp"] }
}
output {
stdout {
codec => rubydebug
}
if [log][file][path] == "/data/logs/nginx/access.log" {
elasticsearch {
hosts => ["192.168.1.128:9200","192.168.1.129:9200","192.168.1.130:9200"]
index => "%{[host][hostname]}‐nginx‐access-%{+YYYY.MM.dd}"
codec => "json"
}
} else if [log][file][path] == "/data/logs/nginx/error.log" {
elasticsearch {
hosts => ["192.168.1.128:9200","192.168.1.129:9200","192.168.1.130:9200"]
index => "%{[host][hostname]}‐nginx‐error-%{+YYYY.MM.dd}"
codec => "json"
}
}
}
5.5 启动logstash并观察日志
[[email protected] logstash]# ./bin/logstash -f config/first-pipeline.conf --config.reload.automatic
观察日志的输出,已经从filebeat读取了数据并存到了es集群中
5.6 查看elasticsearch集群是否增加了对应的索引库
es集群已经生成了es-03‐nginx‐error-2021.08.23及es-03‐nginx‐access-2021.08.23索引库
到此为止logstash已经成功从filebeat读取到日志数据,然后传入到elasticsearch集群不同的索引库
6、在kibana上关联elasticsearch索引库浏览日志数据
6.1 在kibana上添加nginx-access索引模式
使用浏览器访问 http://ip:5601
6.1.1 创建索引模式
6.1.2 填写索引名
6.1.3 添加一个时间筛选字段
6.1.4 创建成功
6.2 查询nginx-access索引日志数据
参考:文章