一、ELK 是什么(先建立整体印象)
ELK 是一套集中收集、存储、查询、展示日志的工具组合,由三个组件组成:
| 组件 | 全称 | 角色 | 大白话类比 |
|---|---|---|---|
| Elasticsearch | 分布式搜索分析引擎 | 存数据 + 查数据 | 仓库 + 搜索引擎 |
| Logstash | 数据收集引擎 | 收集 + 加工日志 | 快递分拣中心(搬运工) |
| Kibana | 可视化平台 | 展示 + 分析数据 | 仓库的可视化管理大屏 |
数据流向(必须记住):
text
Logstash(收集加工) → Elasticsearch(存储检索) → Kibana(可视化展示)
为什么要用 ELK? 单台服务器用 grep/awk 还能凑合;但企业里几十个服务分散在几十台机器上,人工一台台查效率极低。ELK 就像"快递集中管理中心":统一收件 → 集中入仓 → 快速搜索统计。
完整日志系统的五大特征: 收集、传输、存储、分析(UI)、告警。
二、Elasticsearch(E)知识点
2.1 一句话理解
基于 Lucene 的分布式搜索和分析引擎,Java 开发,提供 RESTful API(HTTP 即可访问)。可以理解为"能快速搜索数据的分布式数据库"。
2.2 核心功能
- 全文搜索:快速搜文本(日志、文章)
- 实时分析:写入后几乎马上可查
- 分布式扩展:加节点即可提升性能
- REST 接口:HTTP 操作,简单
2.3 核心概念(重点,必须掌握)
| 概念 | 含义 | 类比关系型数据库 |
|---|---|---|
| Cluster 集群 | 一组 ES 服务器协同工作 | 数据库实例群 |
| Node 节点 | 一个 ES 实例(一台服务器) | 一台数据库服务器 |
| Index 索引 | 一个数据集合 | 表 |
| Document 文档 | 最小数据单元(JSON) | 一行数据 |
| Shard 分片 | 把索引拆开存,提升性能与并行度 | 表分区 |
| Replica 副本 | 分片的备份,防丢失、容错 | 冗余备份 |
2.4 优缺点
- ✅ 查询快(全文搜索)、支持海量数据、易扩展、查询灵活
- ❌ 占内存大、DSL 查询学习成本高、集群运维复杂
2.5 常用端口
- 9200:HTTP API 端口(浏览器/curl 访问)
- 9300:集群内部通信端口
三、Logstash(L)知识点
3.1 一句话理解
"数据搬运 + 加工工厂"。Ruby 编写、运行在 JVM 上,插件丰富,从多种数据源收集数据,过滤加工后发给 ES。
3.2 核心流程(最重要)
text
input(输入) → filter(过滤加工) → output(输出)
- input:从哪来?日志文件、数据库、Kafka/MQ、系统日志(类比:收快递)
- filter:做什么?清洗、提取字段(IP、状态码)、格式转换(类比:拆包、贴标签)
- output:发到哪?Elasticsearch(最常见)、文件、数据库、Kafka(类比:发货)
3.3 主要特点
- 插件多:想接什么数据都行
- 能加工:不只是搬运,还能清洗、正则解析、字段拆分合并
- 输出灵活:可与各种系统集成
- 可扩展:插件体系(input/filter/output/codec)
- 实时性强:日志几乎马上可见
3.4 常用命令选项
-f:指定配置文件-e:直接从命令行给配置(空则 stdin→stdout)-t:测试配置文件是否正确后退出
3.5 其他采集组件(对比记忆)
| 组件 | 特点 | 类比 |
|---|---|---|
| Filebeat | 轻量级日志采集器,性能远好于 JVM 上的 Logstash,常替代之 | 快递员(只收 + 发) |
| Fluentd | 比 Logstash 更省资源,Kubernetes 中常用(EFK 架构,DaemonSet 运行) | 更轻量的分拣中心 |
| Kafka/Redis 等消息队列 | 削峰、缓冲防丢、应用解耦 | 中转仓库 |
常见组合: Filebeat → Logstash → Elasticsearch(ELFK 架构)。Filebeat + Logstash 的好处:Logstash 基于磁盘的自适应缓冲系统可减轻 ES 持续写入压力、可从多种数据源提取、可发送到多个目的地、可组成复杂处理管道。
四、Kibana(K)知识点
4.1 一句话理解
ES 的"可视化窗口"。本身不存数据,只负责查询和展示。
4.2 主要功能
- 数据可视化:折线图、柱状图、饼图、地图
- 仪表板(Dashboard):多个图表集中一屏(CPU、错误数、访问量、状态码)
- 日志查询与搜索:按 IP、时间段、状态码、关键字筛选(海量日志的"搜索框")
- 时间序列分析:观察"什么时候出问题、是否在扩大"
- 监控与告警:如错误超 100 条报警
- 安全与权限控制:不同用户看不同数据
- 地图与报表:地理展示、导出报表
4.3 工作原理
日志由 Logstash/Beats 收集 → 存入 ES → 用户在 Kibana 查询 → Kibana 向 ES 取结果 → 图表展示。ES 负责存和查,Kibana 负责看和分析。
五、部署环境规划(实验拓扑)
| 节点 | 主机名/IP | 配置 | 部署服务 |
|---|---|---|---|
| Node1 | 192.168.10.13 | 2C/4G | Elasticsearch(集群)+ Kibana |
| Node2 | 192.168.10.14 | 2C/4G | Elasticsearch(集群) |
| Apache | 192.168.10.15 | - | Logstash + Apache/httpd |
| Filebeat | 192.168.10.16 | - | Filebeat(ELFK 实验用) |
官网下载(中文):下载并配置 Elastic 产品 | Elastic
六、部署前置:环境准备(所有节点)
bash
# 关闭防火墙与 SELinux
systemctl stop firewalld
systemctl disable firewalld
setenforce 0
配置主机名解析(所有节点都加)
cat >> /etc/hosts <<EOF
192.168.10.13 node1
192.168.10.14 node2
192.168.10.15 apache
192.168.10.16 filebeat
EOF
七、Elasticsearch 集群部署(Node1、Node2 都执行)
7.1 安装软件并注册服务
bash
rpm -ivh elasticsearch-7.17.0-x86_64.rpm
systemctl daemon-reload
systemctl enable elasticsearch
7.2 编写主配置文件
新手建议直接覆盖写入(先备份)。Node1(192.168.10.13)上执行:
yaml
cluster.name: my-elk
node.name: node1
path.data: /data/elk_data
path.logs: /var/log/elasticsearch
bootstrap.memory_lock: false
network.host: 0.0.0.0
http.port: 9200
discovery.seed_hosts: ["192.168.10.13", "192.168.10.14"]
cluster.initial_master_nodes: ["node1", "node2"]
Node2(192.168.10.14)上执行 ------唯一区别是 node.name: node2,其余完全相同。
配置项含义(逐行理解):
cluster.name:集群名,两节点必须一致才能组成一个集群node.name:节点名,区分两台机器path.data / path.logs:数据、日志存放路径bootstrap.memory_lock: false:启动时不锁定内存network.host: 0.0.0.0:监听所有地址http.port: 9200:ES 默认端口discovery.seed_hosts:集群发现(单播)的节点列表cluster.initial_master_nodes:首次启动时的候选主节点
7.3 创建数据目录并授权
bash
mkdir -p /data/elk_data
chown -R elasticsearch:elasticsearch /data/elk_data
7.4(可选)调整 JVM 内存
bash
vim /etc/elasticsearch/jvm.options
# 修改为(2C/4G 实验环境建议 1g)
-Xms1g
-Xmx1g
7.5 启动并验证
bash
systemctl start elasticsearch
systemctl status elasticsearch
curl http://192.168.10.13:9200/_cluster/health?pretty
浏览器验证:
- 节点信息:
http://192.168.10.13:9200、http://192.168.10.14:9200 - 集群健康:
http://192.168.10.13:9200/_cluster/health?pretty
健康状态颜色(记住):
- 🟢 green:健康,数据和副本都没问题
- 🟡 yellow:数据完整,但副本有问题
- 🔴 red:数据不完整
7.6 插入测试索引(理解 REST API 写法)
bash
curl -X PUT "localhost:9200/index-demo1/_doc/1" -H 'Content-Type: application/json' -d'
{
"name": "zhangsan",
"age": 20
}'
命令拆解:
curl:命令行发 HTTP 请求的工具-X PUT:PUT = 创建或覆盖(ID=1 不存在则创建,存在则覆盖)localhost:9200:ES 地址 + 端口index-demo1:索引名(类比"数据集合")_doc:文档类型(7.x 统一固定用_doc,6.x 才有自定义 type)1:文档 ID(主键,不写则 ES 自动生成)-H:请求头,告诉 ES 传的是 JSON-d:请求体,真正的数据
查询验证:
bash
curl -X GET "localhost:9200/index-demo1/_doc/1?pretty"
八、Logstash 部署(Apache 节点 192.168.10.15)
8.1 安装环境与软件
bash
rpm -ivh logstash-7.17.0-x86_64.rpm
systemctl enable logstash
8.2 命令行快速测试
bash
/usr/share/logstash/bin/logstash -e 'input { stdin {} } output { stdout {} }'
8.3 编写配置文件收集系统日志
配置文件由三部分组成:input(采集)、filter(处理,可选)、output(输出) ,位于 /etc/logstash/conf.d/。
bash
vim /etc/logstash/conf.d/system-log.conf
内容:
ruby
input {
file {
path => "/var/log/messages"
type => "system-log"
start_position => "beginning"
}
}
output {
elasticsearch {
hosts => ["http://192.168.10.13:9200"]
index => "system-%{+YYYY.MM.dd}"
}
}
bash
# 测试语法并启动
/usr/share/logstash/bin/logstash -t -f /etc/logstash/conf.d/system-log.conf
systemctl start logstash
8.4 收集 Apache 日志(access + error 分开存)
bash
yum -y install httpd
systemctl start httpd
vim /etc/logstash/conf.d/apache-log.conf
ruby
input {
file {
path => "/var/log/httpd/access_log"
type => "apache-access"
start_position => "beginning"
}
file {
path => "/var/log/httpd/error_log"
type => "apache-error"
start_position => "beginning"
}
}
filter {
if [type] == "apache-access" {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}" }
}
}
}
output {
if [type] == "apache-access" {
elasticsearch {
hosts => ["http://192.168.10.13:9200"]
index => "apache_access-%{+YYYY.MM.dd}"
}
}
if [type] == "apache-error" {
elasticsearch {
hosts => ["http://192.168.10.13:9200"]
index => "apache_error-%{+YYYY.MM.dd}"
}
}
}
这个配置是学习 filter 条件判断 的好例子:根据日志路径打
log_type标签,输出时按标签分流到不同索引。
九、Kibana 部署(Node1 节点 192.168.10.13)
9.1 安装
bash
rpm -ivh kibana-7.17.0-x86_64.rpm
systemctl enable kibana
9.2 修改主配置文件
bash
vim /etc/kibana/kibana.yml
需要改的 4 处:
yaml
server.port: 5601
server.host: "0.0.0.0"
elasticsearch.hosts: ["http://192.168.10.13:9200"]
i18n.locale: "zh-CN"
9.3 启动与验证
bash
systemctl start kibana
systemctl status kibana
ss -lntp | grep 5601
浏览器访问 http://192.168.10.13:5601。
9.4 首次使用:创建索引模式(新手必做步骤)
Kibana 里"看日志"的前提是先建索引模式(Index Pattern):
- 左侧菜单 → Stack Management(堆栈管理)
- 索引模式 → 创建索引模式
- 输入索引名通配符,如
system-*(对应之前 Logstash output 里的前缀) - 下一步 → 时间筛选字段选 @timestamp
- 创建后进入 **Discover(发现)**页面即可看到日志
- 在右侧"Available Fields"中点 host 旁的 add,可按主机字段分类展示
之后每次新增索引(如 apache_access-*、apache_error-*、filebeat-*)都重复同样步骤。
十、Filebeat + ELK(ELFK)部署(进阶)
10.1 架构变化
text
Filebeat(客户端采集) → Logstash(过滤加工) → Elasticsearch(存储) → Kibana(展示)
好处:Filebeat 很轻量,在客户端只做采集转发,重活(过滤加工)交给 Logstash,减轻整体压力。
10.2 Filebeat 节点(192.168.10.16)操作
bash
tar -zxvf filebeat-7.17.0-linux-x86_64.tar.gz -C /usr/local/
cd /usr/local/filebeat
修改配置(二进制安装路径为 /usr/local/filebeat/filebeat.yml):
yaml
filebeat.inputs:
- type: log
enabled: true
paths:
- /var/log/messages
fields:
service_name: filebeat-messages
fields_under_root: true
output.logstash:
hosts: ["192.168.10.15:5044"]
bash
./filebeat -e -c filebeat.yml
10.3 Logstash 节点(192.168.10.15)新建接收配置
bash
vim /etc/logstash/conf.d/filebeat.conf
ruby
input {
beats {
port => 5044
}
}
output {
elasticsearch {
hosts => ["http://192.168.10.13:9200"]
index => "filebeat-%{+YYYY.MM.dd}"
}
}
bash
systemctl restart logstash
ss -lntp | grep 5044
10.4 Kibana 验证
访问 http://192.168.10.13:5601 → Stack Management → 索引模式 → 创建 → 输入 filebeat-* → 时间字段 @timestamp → 创建 → Discover 查看日志。
十一、新手常见坑与检查清单
- 集群组不起来 :检查两台节点
cluster.name是否一致、/etc/hosts解析是否配好、discovery.seed_hosts是否指向对方 IP。 - ES 启动失败 :最常见是
/data/elk_data没有授权chown elasticsearch:elasticsearch,或内存不足(调小 JVM 堆内存)。 - health 是 yellow:单节点集群时副本分片无法分配,属于正常现象,不影响学习。
- Kibana 页面打不开 :确认 5601 端口在监听、
elasticsearch.hosts写的是 ES 地址(带 http:// 前缀)。 - Kibana Discover 看不到日志 :90% 是没创建索引模式,或索引模式名与 ES 里实际索引(先
curl _cat/indices?v确认)不匹配。 - Logstash 收不到日志 :检查日志文件读取权限(
chmod +r /var/log/messages)、-t先测语法。 - Filebeat 字段引用不到 :确认
fields_under_root: true,否则在 Logstash 里要用%{[fields][service_name]}而不是%{[service_name]}。 - 7.x 版本写法 :文档类型统一用
_doc;集群配置用discovery.seed_hosts+cluster.initial_master_nodes(老版教程里的discovery.zen.ping.unicast.hosts是旧写法)。
十二、一页速记
- ELK = 收(L)+ 存(E)+ 看(K)
- 数据流:
Logstash → Elasticsearch:9200 → Kibana:5601 - ES 类比:Index=表、Document=行、Shard=分区、Replica=备份
- Logstash 三段式:
input → filter → output - 健康色:green 好 / yellow 副本缺 / red 数据丢
- 端口速查:ES 9200(HTTP)/9300(集群),Kibana 5601,Filebeat → Logstash 5044
- 部署顺序:环境准备 → ES 集群 → Logstash → Kibana →(Filebeat)