ELK日志系统解析
ELK 日志系统(现常称为 Elastic Stack,由 Filebeat、Logstash、Elasticsearch、Kibana 组成)是一套用于 日志收集、清洗、存储、检索和可视化 的开源解决方案。
它的核心价值是将分散在多台服务器 / 应用中的日志 “汇聚成池、结构化处理、按需分析”,解决传统日志 “查起来难、用起来乱” 的痛点。
一、ELK 各组件的核心角色
可以把 ELK 类比成 “日志工厂”,每个组件对应一个生产环节,分工明确且环环相扣:
| 组件 | 核心角色(工厂类比) | 核心功能 |
|---|---|---|
| Filebeat | 日志采集员(前端) | 轻量级日志采集工具,部署在每台需要收集日志的服务器上,实时读取本地日志文件,发送给后续组件(如 Logstash/Elasticsearch)。 |
| Kafka【按需】 | 日志缓冲器(中间件) | 在大规模场景(如数千台服务器、每秒数万条日志)下,直接用 Filebeat 发送日志到 Logstash 可能出现 “日志丢失”(如 Logstash 宕机)。此时会引入 Kafka(消息队列) 作为 “缓冲层” |
| Logstash | 日志加工厂(中间件) | 接收 Filebeat 传来的原始日志,进行 “清洗加工”(如提取字段、过滤无用信息、格式转换),输出结构化日志到 Elasticsearch。 |
| Elasticsearch | 日志仓库 + 检索引擎(后端) | 分布式搜索引擎,存储结构化后的日志数据,支持毫秒级全文检索(如 “查询昨天 10 点报错的日志”),是 ELK 的 “数据核心”。 |
| Kibana | 日志可视化面板(前端) | 对接 Elasticsearch,提供可视化界面(如柱状图、折线图、日志列表),支持用户查询、分析日志,生成监控报表。 |
1. 高可用模式设计:

2. ELK 扩展场景:引入 Kafka 提升稳定性
在大规模场景(如数千台服务器、每秒数万条日志)下,直接用 Filebeat 发送日志到 Logstash 可能出现 “日志丢失”(如 Logstash 宕机)。此时会引入 Kafka(消息队列) 作为 “缓冲层”
优化流程为:
Filebeat → Kafka → Logstash → Elasticsearch → Kibana
Kafka 作用:
缓冲日志:Filebeat 将日志发送到 Kafka 后立即返回,无需等待 Logstash 处理;
解耦上下游:Logstash 宕机时,日志暂存 Kafka,恢复后从 Kafka 消费,避免丢失;
削峰填谷:应对日志流量突发(如秒杀活动导致日志量骤增),Kafka 平滑流量到 Logstash。
二、ELK 日志流转的完整原理
从 “原始日志” 到 “可查询的可视化图表”,ELK 需经过 4 个核心步骤,流程如下:
步骤 1:Filebeat 采集日志(前端采集)
- 部署位置:每台需要收集日志的服务器(如应用服务器、数据库服务器、Linux 主机)。
- 采集逻辑:
-
- 配置 “日志路径”(如 /var/log/nginx/access.log、/opt/app/logs/app.log);
-
- 实时监控日志文件变化(类似 tail -f),按行读取新产生的日志;
-
- 轻量级处理(如添加 “服务器 IP”“日志来源” 等元数据),避免占用过多服务器资源;
-
- 将日志发送到下游(默认发送给 Logstash,也可直接发送给 Elasticsearch,适合简单场景)。
关键优势:轻量(内存占用通常 < 100MB)、稳定(崩溃后自动重启)、支持多类型日志(文件日志、系统日志、容器日志等)。
步骤 2:Logstash 清洗日志(中间处理)
- 定位:通常部署在独立的服务器(或高可用模式采用集群),作为 “日志加工中心”。
- 核心流程(三阶段 Pipeline):
-
- Input(输入):接收 Filebeat 发送的日志(也支持接收 Kafka、Redis 等中间件的日志);
-
- Filter(过滤 / 加工):ELK 最核心的 “结构化” 环节,
格式转换:将非结构化日志(如纯文本)转为 JSON 格式(方便 Elasticsearch 存储和检索);
- Filter(过滤 / 加工):ELK 最核心的 “结构化” 环节,
-
- Output(输出):将加工后的结构化日志发送到 Elasticsearch(也可输出到 Kafka、文件等)。
关键优势:插件丰富(支持 200+ 插件,满足各种日志处理需求)、灵活定制(通过配置文件定义加工规则)。
步骤 3:Elasticsearch 存储与索引(后端存储)
- 定位:分布式存储与检索引擎,通常部署为集群(至少 3 节点,保证高可用)。
- 核心逻辑:
-
- 日志存储:接收 Logstash 传来的 JSON 格式日志,按 “索引(Index)” 组织数据(类似数据库的 “表”);
-
- 索引策略:通常按时间分片(如每天创建一个索引 log-2024-09-01、log-2024-09-02),方便后续按时间查询,也便于过期日志清理(如删除 30 天前的索引);
索引优化:Elasticsearch 会对日志字段建立 “倒排索引”(类似字典的 “拼音索引”),支持快速全文检索(如输入 “ERROR”,瞬间找到所有包含 “ERROR” 的日志);
高可用保障:通过 “分片(Shard)” 和 “副本(Replica)” 实现:
分片:将一个索引拆分为多个分片(如 5 个主分片),分散存储在不同节点,支持水平扩容;
副本:每个主分片创建 1+ 个副本(如 1 个副本),存储在不同节点,主分片故障时副本自动接管,确保数据不丢、服务不中断。
关键优势:检索速度快(毫秒级)、支持分布式(可扩展到数百节点)、高可用(副本 + 分片机制)。
步骤 4:Kibana 可视化查询(前端展示)
功能:
●提供日志搜索界面
●创建仪表板和可视化
●设置告警规则
常用功能:
●Discover:搜索和查看日志
●Dashboard:创建监控仪表板
●Index Patterns:管理日志索引模式
●Logs:查看 Kubernetes 应用日志
三、 通过ELK采集K8s集群中pod的日志并做可视化展示
step1:filebeat采集pod日志
●监控节点上的 /var/log/pods/ 目录(默认集群中pod日志存储位置)
●自动发现新的 Pod 并开始收集其日志
●添加 Kubernetes 元数据(如 Pod 名称、命名空间、标签等)
●将日志发送到 Logstash 进行进一步处理
配置要点:
vim filebeat-k8s.yml
#=======================k8s===========================
- type: log
enabled: true
fields:
service: k8s
role: pods
topic: log-k8s
fields_under_root: true
paths:
- /var/log/pods/*/*/*.log
tail_files: true
step2:Logstash 处理采集到的日志
典型处理流程:
1.接收来自 Filebeat 的日志
2.解析 JSON 格式的日志(如需要)
3.提取特定字段(如时间戳、日志级别等)
4.添加或删除字段
5.根据条件过滤或路由日志
示例配置:
注:这里对从filebeat接收到的k8s的日志进行特殊处理
vim logstash.conf
input {
beats {
port => 9696 // 监听9696端口,接收Filebeat发送的日志
}
}
filter {
// #### k8s 容器日志 ####
if [topic] == "log-k8s" { // 仅处理 topic 字段为 "log-k8s" 的日志
if [service] == "k8s" { //进一步筛选 service 字段为 "k8s" 的日志
grok{ // 使用 grok 解析日志内容
match => {
"message" => [
// # 模式1:提取时间戳、输出类型、日志级别、进程ID、来源等
"%{TIMESTAMP_ISO8601:date} %{WORD:output} %{WORD} %{NOTSPACE:level}%{NUMBER} %{NOTSPACE}%{SPACE}[T ]%{NUMBER:pid} %{NOTSPACE:source} %{GREEDYDATA:msg}",
// # 模式2(简化版):仅提取时间戳和消息
"%{TIMESTAMP_ISO8601:date} %{WORD:output} %{WORD} %{GREEDYDATA:msg}"
]
}
}
date { // 将原始时间戳转换为 @timestamp
match => ["date","ISO8601"] // 匹配 ISO8601 格式的时间
target => [ "@timestamp" ] // 存储到 Elasticsearch 的标准时间字段
}
}
}
else {
drop {} // # 丢弃所有不满足 topic=="log-k8s" 的日志
}
if [log][offset] {
mutate {
add_field => {
"offset" =>"%{[log][offset]}"
}
}
}
mutate {
remove_field => ["@version", "event", "log", "message"] // # 删除冗余字段
}
}
output {
# stdout {
# codec => rubydebug
# }
elasticsearch {
hosts => [
"es1:9200", // # ES集群地址
"es2:9200",
"es3:9200"
]
user => "elastic" // # 认证用户名
password => "6suq6twSe4Xk" // # 认证密码
index => "%{topic}-%{+YYYY.MM.dd}" // # 按天创建索引(如 log-k8s-2023.10.30)
}
}
功能说明:
●对 Kubernetes 容器日志进行结构化解析。
●提取关键字段(如时间戳、日志级别、进程ID等)。
●标准化时间字段。
Grok 模式说明:
●TIMESTAMP_ISO8601: 匹配 ISO8601 时间格式(如 2023-10-30T12:00:00.000Z)。
●WORD/NOTSPACE: 匹配单词或非空格字符。
●GREEDYDATA: 捕获剩余所有内容。
完整配置流程图

step3:Elasticsearch进行日志存储以及检索
功能:
●存储所有日志数据
●提供强大的搜索和聚合能力
●管理索引生命周期
示例配置
vim elasticsearch.yml
#-----------------------Cluster-------------------
cluster.name: TDP # 集群命名
cluster.max_shards_per_node: 10000
#-----------------------Node-------------------
node.name: 10.127.188.xxx
# -----------------------Paths-------------------
path.logs: /var/log/elasticsearch # 日志路径
path.data:
- /data01/elasticsearch
action.auto_create_index: true
#---------------Network----------------------
network.host: 10.127.188.xxx
# Set a custom port for HTTP
http.port: 9200
transport.port: 9300
network.host: 0.0.0.0
discovery.seed_hosts: ["node-1", "node-2"] # ES节点列表
# --------- 内存和堆大小配置,为 Elasticsearch 设置合适的堆大小,以避免内存溢出-------------
bootstrap.memory_lock: true
ES_JAVA_OPTS: "-Xms512m -Xmx512m"
检查集群状态
使用 Kibana 或直接通过 Elasticsearch 的 REST API 检查集群状态:
curl -X GET "localhost:9200/_cat/nodes?v&pretty"
step4: Kibana (日志可视化和分析)界面构建
功能:
●提供日志搜索界面
●创建仪表板和可视化
●设置告警规则
常用功能:
●Discover:搜索和查看日志
●Dashboard:创建监控仪表板
●Index Patterns:管理日志索引模式
●Logs:查看 Kubernetes 应用日志
配置要点(kibana.yml):
server.host: "0.0.0.0" # 允许外部访问
server.name: "k8s01" # 主机名
elasticsearch.hosts: ["http://es01:9200"] # ES地址
monitoring.ui.container.elasticsearch.enabled: true # 启用容器监控
xpack.security.enabled: true # 启用安全功能(若ES开启安全)
i18n.locale: "zh-CN" # 中文界面(可选)
Dashboard可视化界面集成:

登录要导入的Kibana,点击左下角齿轮图标-管理->已保存对象->导入
会在右侧弹出一个窗口。
这里采用ndjson形式导入收集的日志策略。
vim kibana.ndjson
{"attributes":{"buildNum":63337,"context:defaultSize":50,"context:step":50,"dateFormat":"YYYY-MM-DD HH:mm:ss.SSS","defaultIndex":null,"discover:rowHeightOption":-1,"discover:sampleRowsPerPage":500,"discover:sampleSize":5000,"fileUpload:maxFileSize":"1GB","isDefaultIndexMigrated":true,"timepicker:timeDefaults":"{\n \"from\": \"now-24h/h\",\n \"to\": \"now\"\n}"},"coreMigrationVersion":"8.8.0","created_at":"2023-09-23T16:24:07.183Z","id":"8.8.2","managed":false,"references":[],"type":"config","typeMigrationVersion":"8.7.0","updated_at":"2023-09-25T06:29:11.563Z","version":"WzI0ODgsMl0="}
{"attributes":{"fieldAttrs":"{\"msg\":{\"count\":2}}","fieldFormatMap":"{}","fields":"[]","name":"log-yarn-container-stderr","runtimeFieldMap":"{}","sourceFilters":"[]","timeFieldName":"@timestamp","title":"log-yarn-container-20*","typeMeta":"{}"},"coreMigrationVersion":"8.8.0","created_at":"2023-09-25T07:34:17.212Z","id":"d59f6539-5474-4681-8495-5836e17386b5","managed":false,"references":[],"type":"index-pattern","typeMigrationVersion":"8.0.0","updated_at":"2023-09-25T07:50:23.228Z","version":"WzI5MCwxXQ=="}
{"attributes":{"fieldAttrs":"{\"app_id\":{\"count\":1},\"cluster\":{\"count\":1},\"container_id\":{\"count\":1},\"hostname\":{\"count\":1},\"ip\":{\"count\":1},\"level\":{\"count\":1},\"msg\":{\"count\":1},\"role\":{\"count\":1},\"service\":{\"count\":1}}","fieldFormatMap":"{}","fields":"[]","name":"log-yarn-container-stdout","runtimeFieldMap":"{}","sourceFilters":"[]","timeFieldName":"@timestamp","title":"log-yarn-container-stdout-*","typeMeta":"{}"},"coreMigrationVersion":"8.8.0","created_at":"2023-09-25T07:47:06.731Z","id":"6f398493-35aa-4c6a-ad98-108856826395","managed":false,"references":[],"type":"index-pattern","typeMigrationVersion":"8.0.0","updated_at":"2023-09-25T07:49:39.486Z","version":"WzI4NiwxXQ=="}
{"attributes":{"fieldAttrs":"{}","fieldFormatMap":"{}","fields":"[]","name":"log-yarn-container-flink","runtimeFieldMap":"{}","sourceFilters":"[]","timeFieldName":"@timestamp","title":"log-yarn-container-flink-*","typeMeta":"{}"},"coreMigrationVersion":"8.8.0","created_at":"2023-09-25T07:46:46.699Z","id":"194f03ec-afa2-4a5d-9bfa-5649850f3e23","managed":false,"references":[],"type":"index-pattern","typeMigrationVersion":"8.0.0","updated_at":"2023-09-25T07:46:46.699Z","version":"WzI2OSwxXQ=="}
{"attributes":{"fieldAttrs":"{}","fieldFormatMap":"{}","fields":"[]","name":"log-yarn-container-mr","runtimeFieldMap":"{}","sourceFilters":"[]","timeFieldName":"@timestamp","title":"log-yarn-container-mr-*","typeMeta":"{}"},"coreMigrationVersion":"8.8.0","created_at":"2023-09-25T07:33:39.635Z","id":"4dcb2fed-b1bb-41f1-b65c-c819d240c350","managed":false,"references":[],"type":"index-pattern","typeMigrationVersion":"8.0.0",

日志系统原理以及k8s集群日志采集过程&spm=1001.2101.3001.5002&articleId=151117271&d=1&t=3&u=1a5c2cbf7b3d4061b2c60d4670640cae)
3万+

被折叠的 条评论
为什么被折叠?



