在CentOS7上安装ELK单节点

1. ELK 简介

ELK 是 Elasticsearch、Logstash 和 Kibana 三种软件产品的首字母缩写。这三者都是开源软件,通常配合使用,而且又先后归于 Elastic.co 公司名下,所以被简称为 ELK Stack。已经成为目前最流行的集中式日志解决方案。

  • Elasticsearch:分布式搜索和分析引擎,具有高可伸缩、高可靠和易管理等特点。基于 Apache Lucene 构建,能对大容量的数据进行接近实时的存储、搜索和分析操作。通常被用作某些应用的基础搜索引擎,使其具有复杂的搜索功能;
  • Logstash:数据收集引擎。它支持动态的从各种数据源搜集数据,并对数据进行过滤、分析、丰富、统一格式等操作,然后存储到用户指定的位置;
  • Kibana:数据分析和可视化平台。通常与 Elasticsearch 配合使用,对其中数据进行搜索、分析和以统计图表的方式展示;
  • Filebeat:ELK 协议栈的新成员,一个轻量级开源日志文件数据搜集器,基于 Logstash-Forwarder 源代码开发,是对它的替代。在需要采集日志数据的 server 上安装 Filebeat,并指定日志目录或日志文件后,Filebeat 就能读取数据,迅速发送到 Logstash 进行解析,亦或直接发送到 Elasticsearch 进行集中式存储和分析。

常用架构

在需要收集数据的服务器上部署 Logstash,然后 Logstash 将解析好的数据发送到 Elasticsearch 中存储,最后在 Kibana 中查询、分析。

数据源 -> Logstash -> Elasticsearch -> Kibana

  • 缺点:Logstash 比较消耗 CPU 和内存资源,在计算资源不丰富的机器上会导致服务器性能下降,影响原本的服务。

Beats -> Logstash -> Elasticsearch -> Kibana

引入 Beats 作为日志收集器。Beats 将数据发送到 Logstash,经 Logstash 解析、过滤后发送到 Elasticsearch 存储,并最后在 Kibana 中分析、查询。

这种架构方式解决了 Logstash 在各个服务器节点上占用系统资源高的问题。相比 Logstash,Beats 所占系统的 CPU 和内存几乎可以忽略不计。另外,Beats 和 Logstash 之间支持 SSL/TLS 加密传输,客户端和服务器双向认证,保证了通信安全。

这种架构适合各服务器性能比较敏感的场景,或对数据安全性要求较高的场景。

目前 Beats 包括4种:

  • Packetbeat (搜集网络流量数据);
  • Topbeat (搜集系统、进程和文件系统级别的 CPU 和内存使用情况等数据);
  • Filebeat (搜集文件数据);
  • Winlogbeat (搜集 Windows 实践日志数据);

更多架构使用场景,参考官方文档。

2. 基于 Filebeat 架构的安装配置

测试环境,使用 Filebeat -> Logstash -> Elasticsearch -> Kibana 的架构方式来安装,采用单机部署,所有软件部署在一台机器上。

安装环境及版本:

  • 服务器信息:
    • CentOS 7.6
    • 4C-8G
  • 安装包版本:
    • elasticsearch-8.4.1-linux-x86_64.tar.gz
    • kibana-8.4.1-linux-x86_64.tar.gz
    • logstash-8.4.1-linux-x86_64.tar.gz
    • filebeat-8.4.1-linux-x86_64.tar.gz

注意:安装 ELK (Elastic Stack)时,涉及的所有版本需要相同,如上所示,4个软件版本都是 8.4.1 。

​ 安装顺序按照上面软件包列出的顺序,从上到下依次安装;

具体参考 官方安装 Elastic Stack 章节

本次安装采用官网压缩包的方式。

2.1. 安装 JDK(已经安装过,可以跳过)

安装 openJDK 即可。

1
yum install java-1.8.0-openjdk.x86_64

查看 java 安装情况

1
java -version
1
2
3
4
[es@elk1-2 opt]$ 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)

2.2. 安装配置 Elasticsearch

Elasticsearch 中包含了内置的 OpenJDK,可以不用单独安装 JDK。

下载 .tar.gz 安装包,并解压安装

1
tar zxvf elasticsearch-8.4.1-linux-x86_64.tar.gz -C /opt

设置 data 的目录

创建额外的 Elasticsearch 数据存储目录。

1
mkdir -p /opt/data/esdata

创建有目录的用户,并修改目录权限

1
useradd es -U -m

-U 创建一个与用户名相同的用户组,

-m 创建用户的家目录,

修改 Elasticsearch 安装目录和数据存储目录权限

1
2
chown -R es:es /opt/elasticsearch-8.4.1
chown -R es:es /opt/data/esdata

修改 Elasticsearch 配置文件

1
vim /opt/elasticsearch-8.4.1/config/elasticsearch.yml
1
2
3
4
5
cluster.name: test-es             #配置一个名称
node.name: es-server #本节点elasticsearch名称
network.host: 0.0.0.0 #允许访问
path.data: /opt/data/esdata #数据存放目录运行elasticsearch
ingest.geoip.downloader.enabled: false #这里为了解决后面提示的报错。

启动 Elasticsearch

1
2
3
# 需要在普通用户下执行启动命令,在 ELK 中 Elasticsearch 需要先于 Logstash 启动
su - es
/opt/elasticsearch-8.4.1/bin/elasticsearch -d

验证服务启动状态

查看端口

1
netstat -ntlp |grep 9200

查看页面请求

1
curl localhost:9200

正确请求结果如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
{
"name" : "es-server",
"cluster_name" : "test-es",
"cluster_uuid" : "aeWJbSOSRNeYEjqg3Nj3ow",
"version" : {
"number" : "8.4.1",
"build_flavor" : "default",
"build_type" : "tar",
"build_hash" : "2bd229c8e56650b42e40992322a76e7914258f0c",
"build_date" : "2022-08-26T12:11:43.232597118Z",
"build_snapshot" : false,
"lucene_version" : "9.3.0",
"minimum_wire_compatibility_version" : "7.17.0",
"minimum_index_compatibility_version" : "7.0.0"
},
"tagline" : "You Know, for Search"
}

2.3. 安装配置 Kibana

下载 .tar.gz 安装包,并解压安装

1
tar zxvf kibana-8.4.1-linux-x86_64.tar.gz -C /opt

修改 Kibana 配置文件

1
vim /opt/kibana-8.4.1/config/kibana.yml
1
2
3
4
5
6
7
8
9
10
11
12
# 这里云主机需要填写本地私有地址,不能填写 FIP,否则启动时会报错。
# 如果需要远程机器访问,需要填写 non-loopback address
server.host: 10.100.5.6
# elasticsearch的地址,如果elasticsearch与kibana安装在不同服务器上,需要手动指定地址
server.name: "es-kibana"
elasticsearch.hosts: ["http://localhost:9200"]
# 开启下面配置,日志写入指定日志文件
logging.appenders.default:
type: file
fileName: /opt/kibana-8.4.1/logs/kibana.log
layout:
type: json

启动 Kibana

1
/opt/kibana-8.4.1/bin/kibana &

2.4. 安装配置 Logstash

下载 .tar.gz 安装包,并解压安装

1
tar zxvf logstash-8.4.1-linux-x86_64.tar.gz -C /opt

测试 Logstash 能否正常运行

不修改配置前可以利用下面内容测试 Logstash 能否正常运行。

1
logstash-8.4.1/bin/logstash -e 'input {stdin {}} output {stdout{}}'

执行结果如下:

1
2
3
4
[2022-10-02T16:58:32,007][INFO ][logstash.javapipeline    ][main] Pipeline started {"pipeline.id"=>"main"}
The stdin plugin is now waiting for input:
[2022-10-02T16:58:32,060][INFO ][logstash.agent ] Pipelines running {:count=>1, :running_pipelines=>[:main], :non_running_pipelines=>[]}

出现上面打印信息后,即可以随意输入内容,回车后,就会有内容输出。例如:

1
2
3
4
5
6
7
8
9
10
11
12
hello world.
{
"@version" => "1",
"message" => "hello world.",
"host" => {
"hostname" => "elk1-2"
},
"@timestamp" => 2022-10-02T09:02:34.381131080Z,
"event" => {
"original" => "hello world."
}
}

另一种返回结果

1
logstash-8.4.1/bin/logstash -e 'input{stdin{}}output{stdout{codec => rubydebug}}'
1
2
3
4
[2022-10-02T17:09:07,932][INFO ][logstash.javapipeline    ][main] Pipeline started {"pipeline.id"=>"main"}
The stdin plugin is now waiting for input:
[2022-10-02T17:09:07,966][INFO ][logstash.agent ] Pipelines running {:count=>1, :running_pipelines=>[:main], :non_running_pipelines=>[]}

输入 hello world 返回结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
hello world
{
"@version" => "1",
"message" => "hello world",
"event" => {
"original" => "hello world"
},
"host" => {
"hostname" => "elk1-2"
},
"@timestamp" => 2022-10-02T09:09:37.414736483Z
}

修改 Logstash 配置文件

创建存放自定义输入输出的配置目录

1
mkdir -p /opt/logstash-8.4.1/conf.d/*.conf
1
2
#logstash动态加载的配置文件,所有自定义的输入、输出和过滤配置都放置在这个目录中并以.conf结尾
path.config: /opt/logstash-8.4.1/conf.d/*.conf

创建对接 filebeat 的配置文件并测试

1
2
3
4
5
6
7
8
9
10
11
input {
beats {
port => 5044
}
}
output {
elasticsearch {
hosts => ["http://0.0.0.0:9200"]
index => "%{[@metadata][beat]}-%{+YYYY.MM.dd}"
}
}

用以下命令,测试配置文件是否异常

1
2
cd /opt/logstash-8.4.1
bin/logstash -f /opt/logstash-8.4.1/conf.d/filebeat.conf --config.test_and_exit

输出如下表示配置文件正常:

1
2
3
4
[2022-10-03T19:51:05,381][INFO ][logstash.javapipeline    ] Pipeline `main` is configured with `pipeline.ecs_compatibility: v8` setting. All plugins in this pipeline will default to `ecs_compatibility => v8` unless explicitly configured otherwise.
Configuration OK
[2022-10-03T19:51:05,382][INFO ][logstash.runner ] Using config.test_and_exit mode. Config Validation Result: OK. Exiting Logstash

注意:logstash -f <文件> 这里文件不能使用相对路径,最好如上命令,使用绝对路径。否则输出日志中报错如下:

1
2
3
[2022-10-03T19:50:02,895][INFO ][logstash.config.source.local.configpathloader] No config files found in path {:path=>"/opt/logstash-8.4.1/logstash-8.4.1/conf.d/filebeat.conf"}
[2022-10-03T19:50:02,900][ERROR][logstash.config.sourceloader] No configuration found in the configured sources.

使用创建的 filebeat 文件启动 Logstash

1
/opt/logstash-8.4.1/bin/logstash -f /opt/logstash-8.4.1/conf.d/filebeat.conf &

启动后,检查 5044 端口是否启动

1
netstat -nltp |grep 5044

2.5. 在应用服务器上安装 filebeat 并与 Logstash 通信

下载 .tar.gz 安装包,并解压安装

1
tar zxvf filebeat-8.4.1-linux-x86_64.tar.gz -C /opt/

修改 filebeat 配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# ============================== Filebeat inputs ======
filebeat.inputs:

# filestream is an input for collecting log messages from files.
- type: filestream

# Unique ID among all inputs, an ID is required.
id: my-filestream-id-003

# Change to true to enable this input configuration.
enabled: true

# Paths that should be crawled and fetched. Glob based paths.
paths:
- /var/log/*.log

# ======================= Elasticsearch template setting =======================

setup.template.settings:
index.number_of_shards: 1

# =================================== Kibana ===================================
# This requires a Kibana endpoint configuration.
setup.kibana:

# Kibana Host
host: "10.12.1.84:5601"

# ------------------------------ Logstash Output -------------------------------
output.logstash:
# The Logstash hosts
hosts: ["10.12.1.84:5044"]

修改以上几个部分的内容,Output 部分因为我们是使用 filebeat -> Logstash 的形式,所以 Elasticsearch Output 部分的注释不打开。

上面配置文件内容,详细信息参考 Filebeat 官方文档的配置文件说明部分

其中,Inputs , Output 部分与数据搜集和输出有关。

启动 filebeat

1
2
cd /opt/filebeat-8.4.1-linux-x86_64
./filebeat -e -c /opt/filebeat-8.4.1-linux-x86_64/filebeat.yml > logs/filebeat-2022100102.log 2>&1

当日志出现如下与 Logstash 建立连接的日志内容时,表示 filebeat 搜集的内容可以发送到 Logstash 上了。

1
2
3
4
5
# filebeat 启动成功的日志,有与logstash的连接日志

{"log.level":"info","@timestamp":"2022-10-01T21:20:27.899+0800","log.logger":"publisher_pipeline_output","log.origin":{"file.name":"pipeline/client_worker.go","file.line":139},"message":"Connecting to backoff(async(tcp://10.12.1.84:5044))","service.name":"filebeat","ecs.version":"1.6.0"}
{"log.level":"info","@timestamp":"2022-10-01T21:20:27.900+0800","log.logger":"publisher_pipeline_output","log.origin":{"file.name":"pipeline/client_worker.go","file.line":147},"message":"Connection to backoff(async(tcp://10.12.1.84:5044)) established","service.name":"filebeat","ecs.version":"1.6.0"}

没有上面建立连接的信息,则 filebeat 无法将内容发到 Logstash 中。

3. 配置 Kibana 可视化

登录 Kibana UI,例如,http://10.12.1.84:5601

创建一个 Data View

添加索引

然后在 Discover 页面中查看通过 Filebeat 搜集经 Logstash 发送到 Elasticsearch 中的数据。

(这里需要截图,后面搞定图片存放再补充。)

安装参考链接

4. 部署中解决或未解决的问题

1. 配置 Elasticsearch 并启动服务后,测试服务状态时,请求失败

1
2
[es@elk1-2 elasticsearch-8.4.1]$ curl localhost:9200
curl: (52) Empty reply from server

查看日志,内容如下:

1
2
[2022-09-30T12:41:36,122][WARN ][o.e.x.s.t.n.SecurityNetty4HttpServerTransport] [es-server] received plaintext http traffic on an https channel, closing connection Netty4HttpChannel{localAddress=/[0:0:0:0:0:0:0:1]:9200, remoteAddress=/[0:0:0:0:0:0:0:1]:34442}
[2022-09-30T12:49:25,975][WARN ][o.e.x.s.t.n.SecurityNetty4HttpServerTransport] [es-server] received plaintext http traffic on an https channel, closing connection Netty4HttpChannel{localAddress=/127.0.0.1:9200, remoteAddress=/127.0.0.1:47816}

原因:

Elasticsearch 启动时默认配置并启用了一些安全特性。

从下面配置可知,自动配置以下安全配置:

  • Authentication and authorization are enabled, and a password is generated for the elastic built-in superuser.
  • Certificates and keys for TLS are generated for the transport and HTTP layer, and TLS is enabled and configured with these keys and certificates.
  • An enrollment token is generated for Kibana, which is valid for 30 minutes.

解决方法:

1.继续使用 http 访问

修改 elasticsearch.yml 配置文件,把安全认证开关从原先的 true 改为 false,实现免密登录。

1
2
3
4
5
6
xpack.security.enabled: false
# Enable encryption for HTTP API client connections, such as Kibana, Logstash, and Agents
xpack.security.http.ssl:
#enabled: true
enabled: false
keystore.path: certs/http.p12

保存并重启,重新访问就正常了。

2.利用本地证书,使用 https 请求

1
2
3
curl --cacert /opt/elasticsearch-8.4.1/config/certs/http_ca.crt -u elastic https://localhost:9200
Enter host password for user 'elastic':

输入elastic 密码

该密码在服务初始启动时会打印在日志中,如果没有该密码,可以通过下面的命令重设密码:

1
/opt/elasticsearch-8.4.1/bin/elasticsearch-reset-password -u elastic

该命令会自动生成一个随机密码。

参考如下链接

2. java.net.UnknownHostException: geoip.elastic.co

1
2
3
4
5
[2022-10-03T19:28:31,010][ERROR][o.e.i.g.GeoIpDownloader  ] [es-server] exception during geoip databases update
java.net.UnknownHostException: geoip.elastic.co
at sun.nio.ch.NioSocketImpl.connect(NioSocketImpl.java:564) ~[?:?]
at java.net.SocksSocketImpl.connect(SocksSocketImpl.java:327) ~[?:?]

解决方法:

修改 elasticsearch.yml 配置文件,添加如下配置:

1
ingest.geoip.downloader.enabled: false

参考如下链接How to disable geoip usage in 7.14.0

3. 如何通过日志查看是否有数据在传输

当执行 filebeat 输出到 logstash 时,查看 filebeat 日志内容如下:

1
2
3
4
5
6
7
8
9
10
11
# filebeat 产生的日志是 json 格式:
# 下面两条表示连接到 logstash 了。
{"log.level":"info","@timestamp":"2022-10-14T17:58:08.696+0800","log.logger":"publisher_pipeline_output","log.origin":{"file.name":"pipeline/client_worker.go","file.line":139},"message":"Connecting to backoff(async(tcp://10.12.1.84:5044))","service.name":"filebeat","ecs.version":"1.6.0"}
{"log.level":"info","@timestamp":"2022-10-14T17:58:08.698+0800","log.logger":"publisher_pipeline_output","log.origin":{"file.name":"pipeline/client_worker.go","file.line":147},"message":"Connection to backoff(async(tcp://10.12.1.84:5044)) established","service.name":"filebeat","ecs.version":"1.6.0"}

# 下面这条日志重点关注 "output" key,关注其中的 "acked" key,
# 如下 "acked":147456,表示响应的数据条数。
{"log.level":"info","@timestamp":"2022-10-14T17:58:38.564+0800","log.logger":"monitoring","log.origin":{"file.name":"log/log.go","file.line":185},"message":"Non-zero metrics in the last 30s","service.name":"filebeat","monitoring":{"metrics":{"beat":{"cpu":{"system":{"ticks":470,"time":{"ms":470}},"total":{"ticks":17010,"time":{"ms":17010},"value":17010},"user":{"ticks":16540,"time":{"ms":16540}}},"handles":{"limit":{"hard":4096,"soft":1024},"open":20},"info":{"ephemeral_id":"b1935073-06a5-4778-8f9a-ece8512390e8","name":"filebeat","uptime":{"ms":30459},"version":"8.4.1"},"memstats":{"gc_next":112098048,"memory_alloc":101215976,"memory_sys":138514456,"memory_total":1651565976,"rss":218279936},"runtime":{"goroutines":54}},"filebeat":{"events":{"active":4117,"added":151573,"done":147456},"harvester":{"open_files":0,"running":0}},"libbeat":{"config":{"module":{"running":0},"reloads":1,"scans":1},"output":{"events":{"acked":147456,"active":4096,"batches":74,"total":151552},"read":{"bytes":432},"type":"logstash","write":{"bytes":7930871}},"pipeline":{"clients":8,"events":{"active":4117,"published":151572,"retry":2048,"total":151573},"queue":{"acked":147456,"max_events":4096}}},"registrar":{"states":{"current":0}},"system":{"cpu":{"cores":4},"load":{"1":0.41,"15":0.09,"5":0.16,"norm":{"1":0.1025,"15":0.0225,"5":0.04}}}},"ecs.version":"1.6.0"}}

# 这里也同样关注 "output""acked" 的值,这里为 2 条。
{"log.level":"info","@timestamp":"2022-10-14T18:00:08.564+0800","log.logger":"monitoring","log.origin":{"file.name":"log/log.go","file.line":185},"message":"Non-zero metrics in the last 30s","service.name":"filebeat","monitoring":{"metrics":{"beat":{"cpu":{"system":{"ticks":580},"total":{"ticks":20380,"time":{"ms":10},"value":20380},"user":{"ticks":19800,"time":{"ms":10}}},"handles":{"limit":{"hard":4096,"soft":1024},"open":20},"info":{"ephemeral_id":"b1935073-06a5-4778-8f9a-ece8512390e8","uptime":{"ms":120458},"version":"8.4.1"},"memstats":{"gc_next":80603264,"memory_alloc":58914664,"memory_total":1957563536,"rss":219148288},"runtime":{"goroutines":54}},"filebeat":{"events":{"active":6,"added":8,"done":2},"harvester":{"open_files":0,"running":0}},"libbeat":{"config":{"module":{"running":0}},"output":{"events":{"acked":2,"active":0,"batches":1,"total":2},"read":{"bytes":6},"write":{"bytes":859}},"pipeline":{"clients":8,"events":{"active":6,"published":8,"total":8},"queue":{"acked":2}}},"registrar":{"states":{"current":0}},"system":{"load":{"1":0.19,"15":0.1,"5":0.18,"norm":{"1":0.0475,"15":0.025,"5":0.045}}}},"ecs.version":"1.6.0"}}

如果 acked 的值持续为 0 ,filebeat 一段时间后就会断开与 logstash 的连接。直到重新检测到数据。

  • 版权声明: 本博客所有文章除特别声明外,著作权归作者所有。转载请注明出处!
  • Copyrights © 2022-2023 ligongzhao
  • 访问人数: | 浏览次数:

请我喝杯咖啡吧~

支付宝
微信