EFK 学习思路

本文面向完全没有用过 EFK 的人,从零开始建立一套完整的 EFK 日志排查能力。文章不会涉及运维搭建、集群部署,只聚焦一件事:

让你学会用 Kibana 查日志、用 Elasticsearch 理解存储、用 Fluentd 理解日志从哪来。

读完本文,你应该能够独立在 Kibana 里查到任何你需要的日志,并用它们排查问题。


一、先记住:你学 EFK,到底是为了什么?

很多人一听到 EFK,会下意识想到:

  • Elasticsearch 很复杂
  • Kibana 页面很多
  • Fluentd 配置看不懂
  • 感觉像运维或者平台同学才需要学

但如果你的工作经常要:

  • 看线上日志
  • 排查 Bug
  • 回溯故障时间点
  • 分析某个服务是否异常
  • 给别人提供日志证据

那你学 EFK,本质上是在学:

如何更快地从海量日志里找到问题。

先记住一句总口诀:

先搞清数据怎么进来,再学怎么查,再学怎么看趋势,最后学怎么拿日志支撑结论。

一句话理解:

EFK = 日志采集 + 日志存储 + 日志查询分析。


二、先建立整体脑图

2.1 EFK 分别是什么

组件 作用 你需要掌握到什么程度
Fluentd / Fluent Bit 采集日志、补充元数据、转发日志 明白工作原理与数据流
Elasticsearch 存储日志、建立索引、支持查询 概念理解与查询应用
Kibana 搜索日志、分析字段、做图表和看板 精通使用者

2.2 一张图记住数据流

应用日志
   │
   ├─ 容器标准输出 / 日志文件
   │
   ↓
Fluentd / Fluent Bit
   │   
   ├─ 采集日志
   ├─ 补充上下文信息(Pod、命名空间、标签等)
   └─ 转发到 Elasticsearch
   │
   ↓
Elasticsearch
   ├─ 按索引存储日志
   └─ 支持查询、聚合、过滤
   │
   ↓
Kibana
   ├─ 搜索日志
   ├─ 查看字段
   ├─ 做图表
   └─ 组装监控看板

2.3 你真正要形成的能力

学 EFK,不是去背每个组件的配置项,而是形成下面这四个能力:

  1. 知道日志是怎么流进来的
  2. 知道日志现在存在哪里
  3. 知道怎么快速把目标日志查出来
  4. 知道怎么把日志变成可分析、可汇报的信息

三、Kibana 学习思路(最重要,投入 80% 精力)

这是你最主要的战场。

因为在绝大多数日常工作里,你真正直接操作最多的,不是 Elasticsearch,也不是 Fluentd,而是 Kibana。

3.1 先明确目标:你要达到什么水平?

你的目标不是"会点页面点击",而是达到:

精通使用者级别:看到一个问题,能迅速用 Kibana 把相关日志捞出来、筛出来、看出规律、形成结论。

3.2 Kibana 最核心的四件事


四、Kibana 第一件事:会搜(KQL 查询语言详解)

这是基础中的基础。Kibana 的搜索核心是 KQL(Kibana Query Language),一套专为日志搜索设计的查询语言。

4.1 KQL 的基础语法

4.1.1 最简单的查询:字段精确匹配
field:value

这是 KQL 最基本的形式。

示例:

查询语句 含义
log.level:error 查找日志级别为 error 的日志
service.name:user-service 查找 user-service 服务的日志
kubernetes.pod.name:api-server-7d8f9 查找特定 Pod 的日志
kubernetes.namespace:production 查找生产命名空间的日志

注意:

  • 字段名和值之间用冒号 : 分隔
  • 值如果包含空格或特殊字符,用双引号括起来:message:"user login failed"

4.1.2 布尔组合:AND / OR / NOT

KQL 支持三种逻辑运算符,让你可以组合多个条件。

AND(且)—— 同时满足多个条件

field1:value1 AND field2:value2

示例:

log.level:error AND service.name:user-service

含义:查找 user-service 服务的 error 级别日志。

kubernetes.namespace:production AND log.level:error AND message:"timeout"

含义:查找生产环境中包含"timeout"的错误日志。


OR(或)—— 满足任意一个条件

field1:value1 OR field2:value2

示例:

log.level:error OR log.level:warn

含义:查找错误日志或警告日志。

service.name:user-service OR service.name:order-service

含义:查找 user-service 或 order-service 的日志。


NOT(非)—— 排除某个条件

NOT field:value

示例:

NOT log.level:debug

含义:排除 debug 级别的日志。

service.name:user-service AND NOT log.level:info

含义:查找 user-service 的日志,但排除 info 级别。


混合使用:

(service.name:user-service OR service.name:order-service) AND log.level:error

含义:查找 user-service 或 order-service 的错误日志。

log.level:error AND (message:"timeout" OR message:"connection failed")

含义:查找包含"timeout"或"connection failed"的错误日志。


4.1.3 通配符查询:模糊匹配

当记不全完整值时,用通配符。

* 代表任意多个字符

查询语句 匹配示例
service.name:user* user-service, user-api, user-db
kubernetes.pod.name:api-* api-server-1, api-server-2, api-gateway
message:*timeout* 任何包含 timeout 的日志

? 代表单个字符

查询语句 匹配示例
log.level:err?r error
kubernetes.pod.name:api-? api-1, api-2, api-a

4.1.4 范围查询:数值和日期

用于查询数值型或日期型字段。

大于 / 小于

response_time:>1000

含义:查找响应时间大于 1000 毫秒的日志。

http.status_code:>=500

含义:查找 HTTP 状态码大于等于 500 的日志(服务器错误)。

log.level:<info

含义:查找级别低于 info 的日志(如 debug、trace)。


区间范围

response_time:[1000 TO 5000]

含义:查找响应时间在 1000 到 5000 毫秒之间的日志。

http.status_code:[400 TO 499]

含义:查找所有客户端错误(4xx)。


4.1.5 存在性查询:判断字段是否存在

存在某个字段

http.status_code:*

含义:查找包含 http.status_code 字段的日志。

不存在某个字段

NOT http.status_code:*

含义:查找不包含 http.status_code 字段的日志。


4.1.6 短语查询:精确匹配整句话

当值包含空格时,用双引号。

message:"user login failed"

含义:查找 message 字段精确包含"user login failed"这句话的日志。

不带引号 vs 带引号的区别:

查询 含义
message:user login failed 搜索 user OR login OR failed(三个词任一出现)
message:"user login failed" 搜索完整短语"user login failed"

4.2 KQL 实战:常见查询组合

下面这些都是你工作中真正会用的查询。

场景 1:查某个服务的错误日志
service.name:user-service AND log.level:error
场景 2:查某个 Pod 在特定时间的日志
kubernetes.pod.name:api-server-7d8f9

然后在时间选择器里选择对应时间范围。

场景 3:查包含某个错误关键词的所有日志
message:"OutOfMemory" OR message:"timeout" OR message:"connection refused"
场景 4:查某个请求的完整调用链(有 traceId 时)
traceId:"abc123def456"
场景 5:查生产环境的所有 5xx 错误
kubernetes.namespace:production AND http.status_code:[500 TO 599]
场景 6:排除 debug 日志,只看 warn 及以上
(log.level:error OR log.level:warn) AND kubernetes.namespace:production
场景 7:查某个容器重启前后的日志

先查该容器的日志:

kubernetes.container.name:user-api

然后根据重启时间点,前后各扩展一段时间查看。


4.3 KQL 查询性能优化建议

KQL 查询本身很快,但以下情况会明显变慢:

  1. 时间范围太大:查一整年 vs 查 1 小时
  2. 通配符开头*timeouttimeout* 慢很多
  3. 全文模糊搜索message:*error*log.level:error
  4. 跨太多索引app-logs-* 匹配了 365 个索引 vs 指定日期

优化原则:

先缩时间,再缩范围,最后再模糊搜索。


五、Kibana 第二件事:会控时间

很多人查不到日志,不是因为不会搜,而是因为时间范围错了

5.1 时间选择器的位置

在 Kibana Discover 页面的右上角,你会看到一个时间选择器。

5.2 相对时间:查"最近"的日志

相对时间是以"现在"为起点,向前推算一段时间。

常用相对时间:

选项 含义
Last 15 minutes 最近 15 分钟
Last 30 minutes 最近 30 分钟
Last 1 hour 最近 1 小时
Last 24 hours 最近 24 小时
Last 7 days 最近 7 天

使用场景:

  • 线上问题正在发生:用 Last 15 minutes 或 Last 30 minutes
  • 回顾今天的问题:用 Last 24 hours
  • 分析一周趋势:用 Last 7 days

5.3 绝对时间:查"特定时间点"的日志

绝对时间是精确指定起止时间。

格式示例:

  • 开始时间:2026-04-03 10:00:00
  • 结束时间:2026-04-03 11:00:00

使用场景:

  • 故障发生在已知时间点(如 10:03),需要回溯前后
  • 需要对比两个不同时间段的日志
  • 需要精确提取某段时间的日志作为证据

5.4 快速调整时间范围的技巧

  • 放大:在时间轴上拖动选择更小范围,查看细节
  • 缩小:点击时间选择器,切换到更大范围(如从 15 分钟切到 1 小时)
  • 平移:在时间轴上左右拖动,查看相邻时间段

5.5 时间相关的常见错误

错误 正确做法
故障发生在 10:03,却查的是 Last 15 minutes(当前是 10:20) 切换到绝对时间,设置 10:00-10:10
查 Last 7 days,结果太多找不到重点 先缩小到故障发生的 1 小时
跨时区问题 确认 Kibana 显示的时间是你本地时间还是服务器时间

六、Kibana 第三件事:会看字段(字段详解)

日志不是只看 message 文本。

真正高效的人,都是靠字段过滤和字段组合排查问题。

6.1 什么是字段?

每一条日志在 Elasticsearch 里都是一个 JSON 文档,包含多个键值对。

示例日志(原始 JSON):

{
  "_index": "app-logs-2026.04.03",
  "_source": {
    "message": "user login failed: timeout",
    "log.level": "error",
    "service.name": "user-service",
    "timestamp": "2026-04-03T10:03:15.123Z",
    "kubernetes": {
      "pod.name": "user-service-7d8f9c8b5-xk2m9",
      "namespace": "production",
      "container.name": "user-service",
      "node.name": "node-01"
    },
    "host": {
      "ip": "10.0.1.15",
      "hostname": "worker-01"
    },
    "traceId": "abc123def456",
    "userId": "user_789"
  }
}

在这个例子里:

  • messagelog.levelservice.name 等都是字段
  • 每个字段有一个
  • 你可以用这些字段做精确过滤

6.2 常用字段详解

6.2.1 基础日志字段
字段名 含义 常见值 用途
message 日志正文内容 "user login failed" 查看具体日志内容
log.level 日志级别 debug, info, warn, error, fatal 快速过滤错误日志
timestamp 日志时间戳 2026-04-03T10:03:15.123Z 确认日志发生时间
logger.name 记录日志的类或模块 com.example.UserService 定位代码位置

6.2.2 服务标识字段
字段名 含义 常见值 用途
service.name 服务名称 user-service, order-service 按服务过滤日志
service.version 服务版本 1.2.3 排查版本相关问题
service.environment 环境标识 production, staging, development 区分环境

6.2.3 Kubernetes 相关字段(kubernetes.*)

这是 Fluentd 自动补充的元数据,对容器化环境排查问题至关重要

字段名 含义 示例值 用途
kubernetes.pod.name Pod 名称 user-service-7d8f9c8b5-xk2m9 精确定位到某个 Pod 实例
kubernetes.namespace 命名空间 production, default, kube-system 区分不同环境或业务域
kubernetes.container.name 容器名称 user-service 多容器 Pod 中区分容器
kubernetes.node.name 节点名称 node-01, worker-02 排查节点相关问题
kubernetes.pod.uid Pod 的唯一 ID a1b2c3d4-e5f6-7890-abcd-ef1234567890 Pod 重建后追溯
kubernetes.labels.app Pod 的 app 标签 user-service 按应用分组
kubernetes.labels.version Pod 的版本标签 v1.2.3 按版本分组
kubernetes.labels.tier Pod 的层级标签 backend, frontend 按架构层级分组
kubernetes.annotations.* Pod 的注解信息 自定义 查看额外元数据
kubernetes.docker.container_id Docker 容器 ID abc123... 关联 Docker 相关日志
kubernetes.host 宿主机 IP 192.168.1.10 关联宿主机信息

kubernetes. 字段的价值:*

原始日志里可能只有"报错了",但有了这些字段,你能回答:哪个 Pod?哪个命名空间?哪个容器?哪个节点?


6.2.4 主机相关字段(host.*)
字段名 含义 示例值 用途
host.name 主机名 worker-01 定位具体机器
host.ip 主机 IP 10.0.1.15 网络问题排查
host.hostname 主机完整主机名 worker-01.cluster.local 精确定位

6.2.5 网络相关字段(network.* / http.*)
字段名 含义 示例值 用途
http.request.method HTTP 请求方法 GET, POST, PUT, DELETE 分析请求类型分布
http.request.url 请求 URL /api/users/123 定位具体接口
http.response.status_code HTTP 响应状态码 200, 404, 500 快速筛选错误响应
http.response.body 响应体内容 {"error":"not found"} 查看详细错误
network.client.ip 客户端 IP 192.168.1.100 追踪来源
network.bytes 传输字节数 1024 分析流量大小

6.2.6 链路追踪字段(有链路追踪时)
字段名 含义 示例值 用途
traceId 整条链路的全局 ID abc123def456 串联一个请求的所有日志
spanId 当前调用的 Span ID span789 定位链路中的具体节点
parentId 父调用的 Span ID span456 理解调用关系
service.transaction.name 事务/操作名称 GET /api/users 按操作类型聚合

6.2.7 业务相关字段(根据你们系统定义)

这些字段取决于你们日志里打了什么:

字段名(示例) 含义 用途
userId 用户 ID 查某个用户的所有操作
orderId 订单 ID 查某个订单的完整流程
requestId 请求 ID 内部请求追踪
tenantId 租户 ID 多租户系统排查

6.3 如何在 Kibana 里查看字段列表

在 Kibana Discover 页面:

  1. 左侧边栏会显示Available fields(可用字段列表)
  2. 点击某个字段名,可以快速:
    • 添加到显示列
    • 作为过滤条件
    • 查看该字段的值分布

6.4 字段查询实战

场景 1:只看 error 和 warn 级别的日志
log.level:error OR log.level:warn
场景 2:查生产环境 user-service 的所有日志
kubernetes.namespace:production AND service.name:user-service
场景 3:查某个 Pod 的所有日志
kubernetes.pod.name:user-service-7d8f9c8b5-xk2m9
场景 4:查所有 HTTP 5xx 错误
http.response.status_code:[500 TO 599]
场景 5:查某个用户的所有操作日志
userId:"user_789"
场景 6:查某个请求的完整调用链
traceId:"abc123def456"
场景 7:查特定节点上的所有错误日志
kubernetes.node.name:node-01 AND log.level:error

6.5 字段的黄金组合

记住这几个常用组合,能解决 80% 的排查场景:

目标 字段组合
查某个服务的错误 service.name:X AND log.level:error
查某个 Pod 的日志 kubernetes.pod.name:X
查某个请求的完整链路 traceId:X
查某个用户的所有操作 userId:X
查生产环境的 5xx 错误 kubernetes.namespace:production AND http.status_code:[500 TO 599]

七、Kibana 第四件事:会做可视化和看板

当你已经能搜到日志后,下一步不是"盯着一条条文本看",而是学会看趋势。

7.1 为什么要做可视化?

单条日志适合定位问题,图表和看板适合发现模式

可视化能回答的问题:

  • 错误是不是在某个时间点突然激增?
  • 哪个服务的日志量异常高?
  • 错误级别分布是否正常?
  • 某个问题是不是持续存在还是偶发?

7.2 常用图表类型及创建方法

7.2.1 错误数量趋势图(折线图/面积图)

用途: 查看错误随时间的变化趋势。

创建步骤(Kibana Lens):

  1. 打开 Kibana → Visualize Library → Create new visualization → Lens
  2. 选择索引模式(如 app-logs-*
  3. 拖拽字段:
    • X 轴:@timestamp(自动按时间聚合)
    • Y 轴:Count(记录数)
  4. 添加过滤条件:log.level:error
  5. 保存为"错误趋势图"

查询语句配合:

kubernetes.namespace:production AND log.level:error

能看出的信息:

  • 错误从什么时候开始增多
  • 错误是否有周期性
  • 错误是否在某个操作后明显下降

7.2.2 各服务日志量柱状图

用途: 对比不同服务的日志量,找出异常。

创建步骤:

  1. X 轴:service.name(按服务分组)
  2. Y 轴:Count(记录数)
  3. 可选过滤:log.level:error(只看错误)

能看出的信息:

  • 哪个服务日志量最多
  • 哪个服务错误最多
  • 是否有服务日志量突然异常

7.2.3 日志级别分布图(饼图)

用途: 查看各级别日志的占比。

创建步骤:

  1. 切片字段:log.level
  2. 大小:Count

正常情况下的分布:

  • info 占大部分
  • warn 占小部分
  • error 应该很少

异常情况:

  • error 占比明显上升 → 有故障
  • warn 激增 → 有潜在问题
  • debug 太多 → 可能日志级别配置错误

7.2.4 HTTP 状态码分布图

用途: 分析接口响应健康度。

创建步骤:

  1. X 轴:http.response.status_code
  2. Y 轴:Count

能看出的信息:

  • 5xx 错误占比
  • 4xx 错误类型分布
  • 接口整体成功率

7.2.5 Top N 错误消息柱状图

用途: 找出最常见的错误类型。

创建步骤:

  1. X 轴:message(或自定义错误字段)
  2. Y 轴:Count
  3. 排序:Top 10
  4. 过滤:log.level:error

能看出的信息:

  • 哪类错误出现最频繁
  • 错误是否集中
  • 优先处理哪些错误

7.2.6 Pod 日志量热力图

用途: 查看各 Pod 的日志分布。

创建步骤:

  1. X 轴:kubernetes.pod.name
  2. Y 轴:Count
  3. 颜色深浅:日志量

能看出的信息:

  • 是否有 Pod 日志量异常(可能该实例有问题)
  • 负载均衡是否正常
  • 是否有 Pod 不输出日志(可能挂了)

7.3 仪表盘(Dashboard):把图表组装成看板

什么是仪表盘?

仪表盘是多个图表和搜索结果的集合,用于在一个页面查看完整信息。

创建步骤:

  1. 打开 Kibana → Dashboard → Create new dashboard
  2. 添加已保存的可视化图表
  3. 添加已保存的搜索
  4. 调整布局和大小
  5. 保存仪表盘

推荐的"故障排查仪表盘"配置:

区域 内容
顶部 时间选择器(全局)
左上 错误趋势图(最近 1 小时)
右上 日志级别分布饼图
左中 各服务错误量柱状图
右中 Top 10 错误消息
底部 原始日志列表(过滤后)

使用场景:

  • 故障发生时快速打开
  • 日常巡检
  • 给领导/团队展示问题
  • 作为 Bug 报告的附件

7.4 保存和分享

保存搜索
  1. 在 Discover 页面配置好查询条件
  2. 点击"Save"按钮
  3. 输入名称(如"user-service 错误日志")
  4. 下次直接在"Saved searches"里打开
分享链接
  1. 打开已保存的搜索或仪表盘
  2. 点击"Share"按钮
  3. 复制链接
  4. 粘贴到 Bug 报告或聊天中

分享链接的价值:

别人点开链接,看到的就是你配置好的查询条件和结果,无需重复操作。


八、Elasticsearch 详解:日志是如何存储和查询的

8.1 Elasticsearch 是什么?

一句话定义:

Elasticsearch(简称 ES)是一个分布式搜索和分析引擎,用来存储和检索大量数据。

在 EFK 里,它的角色是:

日志的存储数据库 + 查询引擎。


8.2 核心概念详解

8.2.1 索引(Index)

定义:

索引是 ES 存储数据的基本单位,可以理解成关系数据库里的"表"。

日志索引的命名习惯:

app-logs-2026.04.03
gateway-logs-2026.04.03
kubernetes-prod-2026.04.03

为什么按日期分索引?

  1. 方便按时间范围查询
  2. 方便删除旧日志(直接删索引)
  3. 查询性能更好(不用扫全量数据)

8.2.2 文档(Document)

定义:

文档是 ES 里存储的一条数据,格式是 JSON。

示例(一条日志文档):

{
  "timestamp": "2026-04-03T10:03:15.123Z",
  "message": "user login failed: timeout",
  "log.level": "error",
  "service.name": "user-service",
  "kubernetes.pod.name": "user-service-7d8f9c8b5-xk2m9",
  "kubernetes.namespace": "production"
}

8.2.3 字段映射(Mapping)

定义:

Mapping 定义了每个字段的类型(字符串、数字、日期等)和如何被索引。

常见字段类型:

类型 用途 示例
text 全文搜索的文本 message
keyword 精确匹配的字符串 service.name, log.level
long / integer 整数 http.status_code, response_time
date 日期时间 timestamp
object 嵌套对象 kubernetes, host

为什么区分 text 和 keyword?

特性 text keyword
分词 是(会被拆成单词) 否(整个字符串作为一个值)
用途 全文搜索 精确匹配、聚合、排序
示例 message:"user login" 会被分成 userlogin service.name:"user-service" 必须完全匹配

8.2.4 索引模式(Index Pattern)

定义:

索引模式是 Kibana 用来匹配一组索引的通配符表达式。

示例:

索引模式 匹配的索引
app-logs-* app-logs-2026.04.01, app-logs-2026.04.02, …
kubernetes-prod-* kubernetes-prod-2026.04.01, …
* 所有索引

为什么需要索引模式?

Kibana 需要知道去哪些索引里查数据。配置了索引模式后:

  • 可以跨多个索引查询
  • 可以看到这些索引里的所有字段

8.3 Elasticsearch 是如何处理查询的?

8.3.1 查询的基本流程
用户在 Kibana 输入查询
        ↓
Kibana 将查询转换成 ES DSL(查询语言)
        ↓
ES 接收查询,分析涉及哪些索引
        ↓
ES 在相关索引中查找匹配的文档
        ↓
ES 返回结果给 Kibana
        ↓
Kibana 展示结果

8.3.2 为什么有些查询快,有些查询慢?

快的查询:

  1. 时间范围小(只查几个索引)
  2. 字段精确匹配(log.level:error
  3. 使用了索引的字段(keyword 类型)

慢的查询:

  1. 时间范围大(查几百个索引)
  2. 全文模糊搜索(message:*error*
  3. 通配符开头(service.name:*user*
  4. 复杂聚合(多维度分组统计)

8.3.3 查询优化的基本原则

先缩范围,再精确过滤,最后再模糊搜索。

示例对比:

查询 性能 原因
message:*timeout*(全量搜索) 全文模糊,扫大量数据
log.level:error AND message:timeout 先过滤级别,再搜关键词
kubernetes.namespace:production AND log.level:error 很快 精确字段匹配

8.4 你需要掌握到哪里就够了?

必须理解的概念:

  • 日志存在索引里
  • 每条日志是一个 JSON 文档
  • 字段有不同类型(text / keyword)
  • 索引模式用来匹配一组索引
  • 查询范围越大越慢

无需深入的内容:

  • ES 集群部署
  • 分片和副本配置
  • 索引生命周期管理
  • Java API
  • 调优参数

九、Fluentd / Fluent Bit 详解:日志是怎么来到 ES 的

9.1 Fluentd / Fluent Bit 是什么?

一句话定义:

Fluentd / Fluent Bit 是一个日志收集和转发代理,负责把日志从应用收集起来,处理后发给 Elasticsearch。

两者关系:

特性 Fluentd Fluent Bit
定位 完整的日志收集平台 轻量级版本
资源占用 较高 很低
常见场景 服务器、K8s 节点 容器、边缘设备
配置复杂度 较高 较简单

日常工作里你不需要区分太细,知道它们干的是同一类工作就行。


9.2 Fluentd 在 EFK 链路中的位置

应用输出日志
   ↓
Fluentd 采集日志
   ↓
Fluentd 补充元数据(Pod、namespace 等)
   ↓
Fluentd 转发到 Elasticsearch
   ↓
Elasticsearch 存储
   ↓
Kibana 查询展示

9.3 Fluentd 补充了哪些元数据?

这是 Fluentd 最重要的价值——把"裸日志"变成"带上下文的日志"。

9.3.1 Kubernetes 元数据(容器环境)

Fluentd 会读取 K8s API,自动给每条日志加上:

{
  "kubernetes": {
    "pod.name": "user-service-7d8f9c8b5-xk2m9",
    "namespace": "production",
    "container.name": "user-service",
    "node.name": "node-01",
    "pod.uid": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "labels": {
      "app": "user-service",
      "version": "v1.2.3",
      "tier": "backend"
    }
  }
}

这些字段的来源:

  • pod.namenamespacecontainer.name:从容器运行时获取
  • labels:从 K8s Pod 定义获取
  • node.name:从 Pod 调度信息获取

9.3.2 主机元数据(服务器环境)
{
  "host": {
    "name": "worker-01",
    "ip": "10.0.1.15",
    "hostname": "worker-01.cluster.local"
  }
}

9.3.3 其他补充字段
{
  "@timestamp": "2026-04-03T10:03:15.123Z",  // 日志时间戳
  "log.level": "error",  // 日志级别(从日志内容解析)
  "service.name": "user-service"  // 服务名(根据配置添加)
}

9.4 为什么这些元数据对排查问题至关重要?

没有元数据的日志:

2026-04-03 10:03:15 ERROR user login failed: timeout

你只能知道:

  • 有个错误
  • 错误内容是登录超时

有了元数据的日志:

{
  "message": "user login failed: timeout",
  "log.level": "error",
  "service.name": "user-service",
  "kubernetes.pod.name": "user-service-7d8f9c8b5-xk2m9",
  "kubernetes.namespace": "production",
  "kubernetes.container.name": "user-service",
  "kubernetes.node.name": "node-01",
  "userId": "user_789"
}

你现在能回答:

  • 哪个服务?→ user-service
  • 哪个环境?→ production
  • 哪个 Pod?→ user-service-7d8f9c8b5-xk2m9
  • 哪个容器?→ user-service
  • 哪个节点?→ node-01
  • 哪个用户?→ user_789

这就是为什么 Fluentd 的价值不只是"搬运日志"。


9.5 你需要掌握到哪里就够了?

必须理解的内容:

  • Fluentd 负责采集和转发日志
  • Fluentd 给日志补充了 Kubernetes 元数据
  • 日志流向是:应用 → Fluentd → Elasticsearch → Kibana
  • kubernetes.* 字段是 Fluentd 加上的

无需深入的内容:

  • Fluentd 配置文件编写
  • 插件开发
  • 性能调优
  • 路由规则设计

十、Filebeat 详解:它是什么角色?

10.1 Filebeat 是什么?

一句话定义:

Filebeat 是一个轻量级的日志文件采集器,部署在服务器上,负责把日志文件"搬运"给 Fluentd 或 Elasticsearch。


10.2 Filebeat 在什么场景下会出现?

场景 1:服务器文件日志

  • 应用把日志写在服务器的 /var/log/app/ 目录下
  • Filebeat 监控这些文件
  • 有新日志就采集并转发

场景 2:容器日志(替代方案)

  • 某些架构里用 Filebeat 代替 Fluentd 采集容器日志
  • 但这种情况相对较少

10.3 Filebeat 和 Fluentd 的区别

特性 Filebeat Fluentd
定位 轻量级采集器 完整的日志处理平台
功能 采集 + 转发 采集 + 处理 + 路由 + 丰富
配置 简单 复杂
常见搭配 直接发 ES 或发给 Fluentd 发给 ES

典型架构:

应用日志文件
   ↓
Filebeat(采集)
   ↓
Fluentd(处理 + 补充元数据)
   ↓
Elasticsearch

应用日志文件
   ↓
Filebeat(采集 + 转发)
   ↓
Elasticsearch

10.4 你需要知道什么就够了?

必须知道的内容:

  • Filebeat 是轻量级日志采集器
  • 常用于采集服务器上的日志文件
  • 它可能出现在日志链路的最前端
  • 你不是主要操作它的人

无需深入的内容:

  • Filebeat 配置
  • 部署方式
  • 监控指标
  • 性能调优

十一、实战:完整排查流程演示

场景:用户反馈"登录有时候会失败"

步骤 1:确定时间范围

先问清楚:

  • 问题什么时候开始的?→ 今天上午 10 点左右
  • 现在还在发生吗?→ 是的,偶发

操作:

在 Kibana 时间选择器选择:

  • 绝对时间:2026-04-03 09:30:002026-04-03 11:00:00

步骤 2:确定服务范围和错误类型

查询:

service.name:user-service AND log.level:error

观察:

  • 错误日志数量
  • 错误消息内容
  • 错误发生的时间点

步骤 3:分析错误类型

假设看到以下错误:

message:"user login failed: timeout"
message:"user login failed: database connection refused"
message:"user login failed: token expired"

初步判断:

  • timeout → 可能是下游服务响应慢
  • database connection refused → 数据库连接问题
  • token expired → 认证服务问题

步骤 4:用字段缩小范围

查询超时错误:

service.name:user-service AND message:"timeout"

查看涉及的 Pod:

添加字段 kubernetes.pod.name,发现:

  • 错误集中在 user-service-7d8f9c8b5-xk2m9
  • 其他 Pod 没有或很少

初步结论:

可能是单个实例问题,不是全局问题。


步骤 5:检查该 Pod 的完整日志

查询:

kubernetes.pod.name:user-service-7d8f9c8b5-xk2m9

观察:

  • 该 Pod 是否频繁重启
  • 是否有内存/CPU 相关警告
  • 错误发生前是否有异常日志

步骤 6:查看错误趋势

创建一个简单的趋势图:

  • X 轴:时间(每 5 分钟)
  • Y 轴:错误数量

如果看到错误在某个时间点后激增:

可能该时间点有发布、配置变更、或下游服务异常。


步骤 7:查看链路追踪(如果有)

如果日志里有 traceId:

traceId:"abc123def456"

可以串联起:

  • 用户请求进入
  • 各服务处理过程
  • 哪里开始出错

步骤 8:保存和分享

操作:

  1. 保存当前查询:“登录超时问题排查”
  2. 创建分享链接
  3. 粘贴到 Bug 报告

Bug 报告示例:

标题:用户登录偶发超时

时间:2026-04-03 10:00-10:30
影响:约 5% 的登录请求超时
范围:集中在 user-service-7d8f9c8b5-xk2m9 实例

Kibana 查询链接:[链接]

初步判断:
- 错误集中在单个 Pod 实例
- 错误类型为下游服务超时
- 建议检查该实例网络和下游服务健康状态

十二、你最终应该达到的使用结果

如果这套学习思路走通了,你最后应该达到下面这个状态:

对 Kibana

你能做到:

  • 快速搜日志(熟练 KQL)
  • 熟练切时间范围
  • 会组合字段过滤
  • 会做常见图表
  • 会保存和分享结果

也就是:

达到精通使用者级别。


对 Elasticsearch

你能做到:

  • 知道日志存在索引里
  • 知道索引模式的作用
  • 知道为什么查询有时会慢
  • 知道 Kibana 背后在查 ES

也就是:

达到概念理解与查询应用级别。


对 Fluentd / Fluent Bit

你能做到:

  • 知道它负责采集和转发
  • 知道它会补元数据
  • 知道这些字段为什么对排查重要
  • 能说清日志数据流

也就是:

达到明白工作原理与数据流级别。


对 Filebeat

你能做到:

  • 知道它是文件日志采集器
  • 知道它可能出现在文件日志场景
  • 知道它不是你当前学习重点

也就是:

达到知道其存在与角色级别。


十三、最后记住这套口诀

EFK 总口诀

先懂链路,再会搜索,再看字段,再做分析。

Kibana

主战场在 Kibana,先把日志查准,再把趋势看懂。

Elasticsearch

知道日志存在哪,知道为什么能查,知道为什么有时查得慢。

Fluentd / Fluent Bit

知道日志怎么被收上来,知道上下文字段是谁加上的。

Filebeat

知道它是前置搬运工,但不是当前重点。


十四、给你的最终建议

不要把 EFK 学成"平台搭建知识",而要把它学成:

一套基于日志的排查能力。

真正重要的不是:

  • 会不会部署 ES 集群
  • 会不会写 Fluentd 配置
  • 会不会调 Kibana 插件

而是:

  • 出问题时,你能不能快速找到日志
  • 你能不能从字段里缩小范围
  • 你能不能从趋势里看出异常
  • 你能不能把日志证据组织成结论

当你能把"时间、查询、字段、趋势、分享"这五件事串起来,你的 EFK 使用能力就真正建立起来了。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐