#作者:张桐瑞
下篇:《ELK 统一日志分析系统部署与实践指南(下)》
链接: [https://blog.csdn.net/qq_40477248/article/details/151118627?spm=1001.2014.3001.5501)
1 ELK 技术栈概述
在当今复杂的 IT 架构中,日志数据分散在各类服务器、应用程序和网络设备中,传统的日志查看方式(如直接登录服务器查看本地日志文件)已无法满足高效运维、故障排查和业务分析的需求。ELK Stack(Elasticsearch、Logstash、Kibana、Beats)作为一套成熟的开源日志分析解决方案,能够实现日志的集中采集、过滤清洗、存储检索、可视化分析,帮助运维人员和开发人员快速定位问题、优化系统性能,为业务决策提供数据支撑。
1.1ELK 核心组件详解
1.1.1 Elasticsearch(ES)
Elasticsearch 是基于 Lucene 构建的分布式搜索引擎,同时具备强大的日志存储能力,其核心特点如下:
- 分布式架构:支持水平扩展,可通过增加节点实现存储容量和查询性能的提升,满足海量日志数据的存储需求。
- 实时检索:采用倒排索引技术,能够在秒级甚至毫秒级内完成对海量日志数据的查询,快速定位关键信息。
- 高可用性:通过分片(Shard)和副本(Replica)机制保障数据安全。分片将索引数据拆分存储在不同节点,副本则是分片的备份,当主分片所在节点故障时,副本可自动升级为主分片,确保服务不中断。
- 多数据类型支持:支持结构化、半结构化和非结构化数据,能够灵活适配不同格式的日志(如 Apache 访问日志、应用程序 JSON 日志等)。
在 ELK 架构中,Elasticsearch 主要承担日志存储和日志检索两大核心任务,所有经过处理的日志最终都会写入 Elasticsearch,并通过其提供的 RESTful API 实现日志的查询操作。
1.1.2 Logstash
Logstash 是一款开源的日志数据处理工具,作为 ELK 架构中的 “数据管道”,其核心功能是对采集到的原始日志进行过滤、清洗、转换和丰富,具体能力包括:
- 多源数据接入:支持从 Beats、文件、数据库、消息队列(如 Kafka)等多种数据源采集日志数据。
- 灵活的过滤插件:提供丰富的过滤插件(如 Grok、Mutate、Date 等),可实现日志格式解析(如将非结构化的 Apache 日志解析为结构化字段)、数据清洗(如去除无用字段、修正错误数据)、字段新增(如添加时间戳、服务器标识)等操作。
- 多目标数据输出:可将处理后的日志数据输出到 Elasticsearch、文件、Kafka 等目标存储或中间件,满足不同场景下的数据流转需求。
Logstash 在架构中起到 “承上启下” 的作用,一方面接收来自 Beats 等采集器的原始日志,另一方面将处理后的标准化日志传递给 Elasticsearch 进行存储,确保写入 Elasticsearch 的数据具备高质量和可用性。
1.1.3 Kibana
Kibana 是 ELK 架构中的可视化前端工具,为用户提供直观、交互性强的 Web UI 界面,主要功能包括:
- 日志数据探索:支持通过索引模式关联 Elasticsearch 中的日志数据,提供实时的日志浏览、筛选和搜索功能,用户可根据时间范围、字段条件快速定位所需日志。
- 多样化可视化图表:提供折线图、柱状图、饼图、热力图、地图等多种可视化组件,可基于日志数据生成业务指标(如接口访问量、错误率)、系统性能(如 CPU 使用率、内存占用)等维度的图表。
- 自定义仪表盘:支持将多个可视化图表组合成自定义仪表盘,实时展示关键业务和系统指标,方便运维人员和业务人员快速掌握系统运行状态。
- 高级分析功能:支持时序分析、聚合分析等高级功能,可对日志数据进行深度挖掘,如分析用户访问行为、排查系统性能瓶颈等。
1.1.4Beats
Beats 是基于 Golang 开发的轻量级日志采集工具集,具有资源占用低、部署灵活的特点,能够在各类服务器和设备上采集日志数据并发送给 Logstash 或 Elasticsearch。根据采集场景的不同,Beats 包含多个子产品:
- Filebeat:专注于采集应用程序日志,如 Web 服务器(Apache、Nginx)日志、应用程序(Java、Python)输出日志等。支持日志文件监听、断点续传(避免日志丢失)、多目标输出(可同时发送给 Logstash 和 Elasticsearch)等功能。
- Topbeat:现更名为 Metricbeat 的系统模块,主要用于采集系统级别的 metrics 数据,如 CPU 使用率、内存占用、磁盘 IO、网络流量等,帮助运维人员监控服务器硬件资源状态。
- Winlogbeat:专门针对 Windows 服务器设计,用于采集 Windows 事件日志,如系统日志、安全日志、应用程序日志等,解决 Windows 环境下的日志采集难题。
- Packetbeat:通过抓取网络数据包,采集网络设备(如路由器、交换机)和网络应用(如 HTTP、MySQL、Redis)的网络流量数据,可用于分析网络性能、排查网络故障、监控网络安全事件。
1.2 ELK 工作流程
ELK 架构的典型工作流程如下,各组件协同工作,实现日志从采集到分析的全流程管理:
- 日志采集:在目标服务器(如 Web 服务器、应用服务器、Windows 服务器)上部署对应的 Beats 工具(如 Filebeat、Winlogbeat),Beats 实时监听日志文件或系统事件,采集原始日志数据。
- 日志过滤与转换:Beats 将采集到的原始日志发送给 Logstash,Logstash 通过配置的过滤规则(如 Grok 模式)对日志进行解析、清洗和转换,将非结构化日志转换为结构化数据(如提取 Apache 日志中的客户端 IP、请求方法、响应状态码等字段)。
- 日志存储与检索:Logstash 将处理后的标准化日志数据发送给 Elasticsearch,Elasticsearch 将日志数据存储在分布式索引中,并建立倒排索引,支持高效的日志检索。
- 日志可视化与分析:Kibana 通过连接 Elasticsearch,读取索引中的日志数据,用户通过 Kibana 的 Web UI 界面进行日志浏览、搜索、筛选,并基于日志数据创建可视化图表和仪表盘,实现日志的可视化分析和监控。
2 ELK部署
2.1 环境描述
本次部署采用 4 台 Linux 服务器(CentOS 7 系统),各服务器的角色、IP 地址和安装组件如下表所示,确保所有服务器之间网络互通(关闭防火墙或开放相关端口):
服务器IP地址 | 主机名 | 角色 | 安装组件 |
---|---|---|---|
192.168.183.10 | es-master.linux.com | Elasticsearch 主节点 | JDK 15、Elasticsearch 7.6.2、Kibana 7.6.2、Logstash 7.6.2 |
192.168.183.11 | es-node01.linux.com | Elasticsearch 数据节点 | JDK 15、Elasticsearch 7.6.2 |
192.168.183.12 | es-node02.linux.com | Elasticsearch 数据节点 | JDK 15、Elasticsearch 7.6.2 |
192.168.183.13 | web_server.linux.com | Web 服务器 + 日志采集端 | HTTPD(Apache)、Filebeat 7.6.2 |
2.1.1 软件版本说明
为确保各组件兼容性,本次部署统一采用 Elastic Stack 7.6.2 版本,相关软件包如下:
- JDK:jdk-15.0.2_linux-x64_bin.tar.gz(Elasticsearch 7.6.2 推荐使用 JDK 11 及以上版本)
- Elasticsearch:elasticsearch-7.6.2-linux-x86_64.tar.gz
- Kibana:kibana-7.6.2-linux-x86_64.tar.gz
- Logstash:logstash-7.6.2.tar.gz
- Filebeat:filebeat-7.6.2-linux-x86_64.tar.gz
- HTTPD:httpd-2.4.6-97.el7.centos.x86_64(可通过 CentOS 官方 YUM 源安装)
# 关闭firewalld防火墙
systemctl stop firewalld
systemctl disable firewalld
# 关闭SELinux
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
2.1.2 安装JDK
在 es-master 节点上传 JDK 安装包(jdk-15.0.2_linux-x64_bin.tar.gz),并解压到/usr/local目录:
[root@es-master ~]# tar xf jdk-15.0.2_linux-x64_bin.tar.gz -C /usr/local/
[root@es-master ~]# ls /usr/local/
bin etc games include jdk-15.0.2 lib lib64 libexec sbin share src
配置 JDK 环境变量:编辑/etc/profile文件,添加 JDK 路径:
[root@es-master ~]# vim /etc/profile
export JAVA_HOME=/usr/local/jdk-15.0.2
export PATH=$PATH:$JAVA_HOME/bin
使环境变量生效,并验证 JDK 安装:
[root@es-master ~]# source /etc/profile
[root@es-master ~]# java -version
java version "15.0.2" 2021-01-19
Java(TM) SE Runtime Environment (build 15.0.2+7-27)
Java HotSpot(TM) 64-Bit Server VM (build 15.0.2+7-27, mixed mode, sharing)
[root@es-master ~]# scp -r /usr/local/jdk-15.0.2/ root@192.168.140.11:/usr/local/
[root@es-master ~]# scp -r /usr/local/jdk-15.0.2/ root@192.168.140.12:/usr/local/
[root@es-master ~]# rsync -av /etc/profile root@192.168.140.11:/etc/profile
[root@es-master ~]# rsync -av /etc/profile root@192.168.140.12:/etc/profile
2.1.3 域名解析
为避免因 IP 地址变更导致服务不可用,所有服务器需配置主机名与 IP 地址的映射关系,操作如下:
在 es-master 节点编辑/etc/hosts文件:
[root@es-master ~]# vim /etc/hosts
在文件末尾添加以下内容(注意:文档中 IP 地址存在 192.168.183.x 和 192.168.140.x 两种,此处以 192.168.140.x 为例,实际部署需根据实际网络环境调整):
127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4
::1 localhost localhost.localdomain localhost6 localhost6.localdomain6
192.168.140.10 es-master.linux.com es-master
192.168.140.11 es-node01.linux.com es-node01
192.168.140.12 es-node02.linux.com es-node02
192.168.140.13 web_server.linux.com web_server
将配置好的/etc/hosts文件同步到其他节点,避免重复编辑:
[root@es-master ~]# scp /etc/hosts root@192.168.140.11:/etc/
[root@es-master ~]# scp /etc/hosts root@192.168.140.12:/etc/
[root@es-master ~]# scp /etc/hosts root@192.168.140.13:/etc/
2.1.4 三个ES节点系统参数优化
编辑/etc/security/limits.conf文件,设置全局文件描述符和进程数限制:
[root@es-master ~]# tail /etc/security/limits.conf
* soft nofile 65536
* hard nofile 65536
* soft noproc 2048
* hard noproc 4096
编辑/etc/security/limits.d/20-nproc.conf文件,调整用户进程数限制(CentOS 7 默认存在此文件,需确保配置一致)
[root@es-master ~]# cat /etc/security/limits.d/20-nproc.conf
# Default limit for number of user's processes to prevent
# accidental fork bombs.
# See rhbz #432903 for reasoning.
* soft nproc 4096
root soft nproc unlimited
编辑/etc/sysctl.conf文件,添加虚拟内存和文件系统参数:
[root@es-master ~]# tail -n 2 /etc/sysctl.conf
vm.max_map_count=262144
fs.file-max=655360
使内核参数生效
[root@es-master ~]# sysctl -p
vm.max_map_count = 262144
fs.file-max = 655360
2.1.5 创建elk用户
elasticsearch不允许以root用户启动,需要一个普通用户
[root@es-master ~]# ansible es -m user -a 'name=elk state=present'
[root@es-master ~]# ansible es -m shell -a 'id elk'
2.1.6 规划软件安装目录
[root@es-master ~]# mkdir -p /app/elk
[root@es-master ~]# tar xf elasticsearch-7.6.2-linux-x86_64.tar.gz -C /app/elk/
[root@es-master ~]# tar xf kibana-7.6.2-linux-x86_64.tar.gz -C /app/elk/
[root@es-master ~]# tar xf logstash-7.6.2.tar.gz -C /app/elk/
[root@es-master ~]# chown -R elk.elk /app/elk/
[root@es-master ~]# ansible '~192.168.140.1[12]' -m shell -a 'mkdir -p /app/elk'
[root@es-master ~]# ansible '~192.168.140.1[12]' -m copy -a 'src=/app/elk/elasticsearch-7.6.2 dest=/app/elk owner=elk group=elk'
2.1.7 配置es集群
2.1.7.1节点类型说明:
Master node
1)负责集群自身的管理操作;例如创建索引、添加节点、删除节点
2)node.master: true
Data node
1)负责数据读写
2)建议实际部署时,使用高内存、高硬盘的服务器
3)node.data: true
Ingest node
1)预处理节点
2)负责数据预处理(解密、压缩、格式转换)
Client node
1)负责路由用户的操作请求
2)node.master: false
3)node.data: false
2.1.7.2 es-master.linux.com
[root@es-master ~]# su - elk
[elk@es-master ~]$ mkdir /app/elk/elasticsearch-7.6.2/data
[elk@es-master ~]$ cp /app/elk/elasticsearch-7.6.2/config/elasticsearch.yml /app/elk/elasticsearch-7.6.2/config/elasticsearch.yml.bak
[elk@es-master ~]$ vim /app/elk/elasticsearch-7.6.2/config/elasticsearch.yml
cluster.name: es
node.name: es-master
path.data: /app/elk/elasticsearch-7.6.2/data/
path.logs: /app/elk/elasticsearch-7.6.2/logs
network.host: 192.168.140.10
http.port: 9200
transport.tcp.port: 9300 //集群内部通信用
discovery.seed_hosts: ["192.168.140.10:9300", "192.168.140.11:9300", "192.168.140.12:9300" ]
cluster.initial_master_nodes: ["192.168.140.10:9300"]
node.master: true
node.data: true
node.ingest: false
node.ml: false
cluster.remote.connect: false
http.cors.enabled: true
http.cors.allow-origin: true
2.1.7.3 es-node01.linux.com
[root@es-node01 ~]# su - elk
[elk@es-node01 ~]$ mkdir /app/elk/elasticsearch-7.6.2/data
cluster.name: es
node.name: es-node01
path.data: /app/elk/elasticsearch-7.6.2/data
path.logs: /app/elk/elasticsearch-7.6.2/logs
network.host: 192.168.140.11
http.port: 9200
transport.tcp.port: 9300
discovery.seed_hosts: ["192.168.140.10:9300", "192.168.140.11:9300", "192.168.140.12:9300"]
cluster.initial_master_nodes: ["192.168.140.10:9300"]
node.master: false
node.data: true
node.ingest: false
node.ml: false
cluster.remote.connect: false
http.cors.enabled: true
http.cors.allow-origin: "*"
2.1.7.4 es-node02.linux.com:
cluster.name: es
node.name: es-node02
path.data: /app/elk/elasticsearch-7.6.2/data
path.logs: /app/elk/elasticsearch-7.6.2/logs
network.host: 192.168.140.12
http.port: 9200
transport.tcp.port: 9300
discovery.seed_hosts: ["192.168.140.10:9300", "192.168.140.11:9300", "192.168.140.12:9300"]
cluster.initial_master_nodes: ["192.168.140.10:9300"]
node.master: false
node.data: true
node.ingest: false
node.ml: false
cluster.remote.connect: false
http.cors.enabled: true
http.cors.allow-origin: "*"