返回首页

7.4 Kubernetes Events 与告警

本章你会学到什么

  • Events 在 Kubernetes 里到底扮演什么角色
  • 如何借助 Events 快速找到异常线索
  • Alertmanager 的核心能力与告警策略设计方法
  • 如何从“能看见问题”走向“能及时响应问题”

1. Events 的定位:它不是日志,也不是指标

Kubernetes API 对 Event 的定义非常明确:Event 是集群中某处发生的一次事件报告。同时官方也提醒,Events 具有有限保留时间,触发条件和消息文本也可能随着时间演化,因此 Event 应被视为“信息性、尽力而为、补充型数据”,而不是长期审计事实源。::cite[405]

这句话很重要,因为它说明了 Events 的定位:

  • 它不是长期日志仓库
  • 它不是趋势分析指标库
  • 它更像是 Kubernetes 现场故障的一串“即时提示卡片”

换句话说,Events 最擅长回答的是:刚刚发生了什么异常动作。

2. Events 最常见的使用场景

如果你刚接触 Kubernetes,最容易从 Events 获益的场景有 4 类:

2.1 Pod 起不来

例如:

  • FailedScheduling
  • FailedMount
  • ErrImagePull
  • ImagePullBackOff
  • BackOff
  • Unhealthy

这类问题往往不用先翻几十页日志,直接看 Events 就能获得第一批线索。

2.2 发布后服务异常

比如 Deployment 更新后一直不 Ready,Events 往往会告诉你:

  • 探针失败
  • 拉镜像失败
  • 节点资源不足
  • 卷挂载异常
  • 调度约束不满足

2.3 节点侧故障

例如节点磁盘压力、内存压力、网络问题、驱逐等,也经常会在 Events 里留下痕迹。

2.4 平台组件操作反馈

很多控制器动作都会生成 Events,比如:

  • HPA 扩缩容动作
  • Job 重试
  • Ingress / Service 控制器配置更新
  • 存储卷 attach / detach 过程

3. 为什么说 Events 是排障时的“第一现场”

相比日志和指标,Events 有两个很实用的特点:

  1. 语义更接近 Kubernetes 对象动作:比如“调度失败”“探针不健康”“镜像拉取失败”
  2. 离资源对象更近:你是在看 Pod、Node、Deployment 发生了什么,而不是先去猜测系统某一层的间接症状

因此,当某个工作负载突然异常时,一个很高效的顺序通常是:

  1. 先看 kubectl get pod
  2. 再看 kubectl describe pod
  3. 再看 kubectl events
  4. 最后再去联动日志与指标

4. 如何快速查看和筛选 Events

Kubernetes 官方 kubectl events 文档给出了最常见的查看方式:可以查看当前命名空间、全部命名空间、指定对象,还可以按 Warning / Normal 类型过滤,或开启 --watch 持续观察。::cite[406]

4.1 最常用命令

查看当前命名空间近期事件:

kubectl events

查看所有命名空间:

kubectl events --all-namespaces

只看某个 Pod:

kubectl events --for pod/web-pod-13je7 --watch

只看 Warning:

kubectl events --types=Warning

导出 YAML:

kubectl events -o yaml

4.2 排障时建议先看 Warning

大多数线上排障场景里,建议先跑:

kubectl events --all-namespaces --types=Warning

因为 Warning 往往更接近“需要你介入”的异常,而 Normal 更像系统正常动作回执。

4.3 Event 对象里值得重点关注的字段

Kubernetes Event API 文档指出,Event 中常见的关键信息包括:

  • eventTime:事件首次观察时间
  • message:面向人类的描述信息
  • reason:事件原因标签
  • series:连续重复事件的聚合信息

同时官方特别提醒:不要把某个 Reason 的存在与否当作严格、稳定、长期一致的契约。::cite[405]

5. 一套实用的 Events 排障方法

5.1 场景一:Pod Pending 很久

优先执行:

kubectl get pod -n prod
kubectl describe pod <pod-name> -n prod
kubectl events --for pod/<pod-name> -n prod --types=Warning

重点看这些提示:

  • FailedScheduling:通常是 CPU、内存、污点容忍、亲和性条件不满足
  • FailedMount:通常是 PVC / CSI / Secret / ConfigMap 挂载异常
  • FailedCreatePodSandBox:通常偏运行时或 CNI 问题

5.2 场景二:Pod 反复重启

建议联动:

  1. Events 看 BackOffUnhealthy
  2. kubectl logs --previous 看上一次退出日志
  3. Metrics 看内存是否触顶、是否 OOM
  4. 如有 tracing,再看请求入口是否异常放大

5.3 场景三:服务抖动,但不知道是局部还是系统性问题

建议先看全局 Warning Events:

kubectl events --all-namespaces --types=Warning

如果同一时间窗口内,很多命名空间都出现节点相关或存储相关 Warning,那么问题更可能在平台层;如果只有单一业务命名空间大量异常,则更可能是应用发布、配置或依赖问题。

6. Events 的边界:为什么还需要告警体系

Events 很适合“出事以后人工去看”,但不适合“自动盯住所有风险”。原因有 3 个:

  1. Events 保留时间有限,不适合长期沉淀。::cite[405]
  2. Events 很多是离散文本,不适合做稳定阈值判断。
  3. 你不可能靠人工持续盯着 kubectl events --watch

这就是为什么我们还需要告警系统:让系统自己识别值得关注的问题,并在合适的时间、用合适的方式通知到合适的人。

7. Alertmanager 是什么

Prometheus 官方文档指出,Alertmanager 负责处理来自 Prometheus 等客户端的告警,并完成去重(deduplicating)分组(grouping)路由(routing)静默(silencing)、**抑制(inhibition)**等工作。::cite[359]

这几个能力分别对应很真实的生产需求:

  • 去重:同一告警别重复炸你手机
  • 分组:一次事故中的 200 条实例告警,最好合并成 1 条通知
  • 路由:支付服务告警发给支付团队,平台告警发给 SRE
  • 静默:已知变更窗口里临时压住告警
  • 抑制:根因告警出现时,压制掉一串次生告警

8. Alertmanager 的核心设计:路由树

Prometheus Alertmanager 配置文档把 route 描述为一个路由树节点:所有告警先进入顶层路由,再根据匹配器进入子路由;在这个过程中,系统可以定义分组规则、等待时间、重复通知间隔等。::cite[360]

这意味着设计告警体系时,真正重要的不只是“规则写没写”,而是下面这 4 件事:

  1. 告警由谁接收
  2. 哪些告警应该聚合在一起
  3. 第一次通知要不要等待几分钟聚合更多事件
  4. 重复多久再提醒一次

9. 实操:一条 Prometheus 规则 + 一份 Alertmanager 路由配置

9.1 先定义一条告警规则

下面示例表示:如果某个应用的 5xx 错误率在 5 分钟窗口内超过 5%,就触发告警。

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: app-alert-rules
  namespace: monitoring
spec:
  groups:
    - name: app-availability
      rules:
        - alert: HighHttp5xxErrorRate
          expr: |
            sum(rate(http_requests_total{status=~"5.."}[5m])) by (namespace, app)
            /
            sum(rate(http_requests_total[5m])) by (namespace, app)
            > 0.05
          for: 5m
          labels:
            severity: critical
            team: app
          annotations:
            summary: "应用 5xx 错误率过高"
            description: "{{ $labels.namespace }}/{{ $labels.app }} 在过去 5 分钟内 5xx 错误率超过 5%"

9.2 再定义 Alertmanager 路由

Alertmanager 文档明确指出,通知接收器、分组、节流和静默等,都是通过路由树配置完成的。::cite[359]::cite[360]

下面是一份适合入门理解的示例:

global:
  resolve_timeout: 5m

route:
  receiver: default-receiver
  group_by: [cluster, namespace, alertname]
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 2h
  routes:
    - matchers:
        - severity="critical"
        - team="platform"
      receiver: platform-pager
    - matchers:
        - severity="critical"
        - team="app"
      receiver: app-pager
    - matchers:
        - severity="warning"
      receiver: team-chat

receivers:
  - name: default-receiver
    webhook_configs:
      - url: http://alert-router.monitoring.svc.cluster.local/default

  - name: platform-pager
    webhook_configs:
      - url: http://alert-router.monitoring.svc.cluster.local/platform

  - name: app-pager
    webhook_configs:
      - url: http://alert-router.monitoring.svc.cluster.local/app

  - name: team-chat
    webhook_configs:
      - url: http://alert-router.monitoring.svc.cluster.local/chat

inhibit_rules:
  - source_matchers:
      - severity="critical"
    target_matchers:
      - severity="warning"
    equal: [cluster, namespace, app, alertname]

9.3 这几个参数应该怎么理解

Alertmanager 配置文档里,group_bygroup_waitgroup_intervalrepeat_interval 都是核心参数。::cite[360]

你可以这么理解:

  • group_by:哪些标签相同就归为一组
  • group_wait:首次发送前等多久,给同批次告警留聚合时间
  • group_interval:同一组新增告警后,多久再发一次更新通知
  • repeat_interval:如果问题一直没恢复,多久重复提醒一次

10. 告警策略应该怎么设计

告警不是越多越好,而是越有行动价值越好。

10.1 最推荐的分类方式

可以按“影响面 + 紧急度”来设计:

级别 典型含义 示例
P1 / Critical 用户已明显受影响,需要立即响应 核心接口大面积 5xx、入口不可用
P2 / Warning 系统有异常趋势,需要尽快处理 错误率升高、Pod 重启增多
Info 变更或状态提醒 扩容完成、证书即将过期

10.2 哪些告警最值得先做

如果你刚开始建设告警体系,建议优先做下面 8 类:

  1. 入口服务不可用
  2. 核心接口错误率过高
  3. 核心接口 P95 / P99 延迟过高
  4. 节点 NotReady
  5. Pod 持续 CrashLoopBackOff
  6. Pod 持续 OOMKill
  7. 磁盘使用率过高
  8. 关键依赖(数据库、消息队列、缓存)不可达

10.3 告警设计最常见的 5 个坑

  1. 一个实例一条告警,完全不做聚合
  2. 平均值告警,结果真正的尖峰问题被淹没
  3. 没有 for 持续时间,瞬时抖动也报警
  4. 没有路由和团队归属,所有告警都发到同一个群
  5. 只会发,不会抑制,不会静默,最终导致告警疲劳

11. 从“能看见”到“能及时响应”

可观测性建设常常停留在“图做出来了、日志也能查到了”,但真正成熟的系统还要再迈一步:建立响应闭环

11.1 一个成熟闭环至少包括 4 个环节

  1. 发现:Metrics、Logs、Events、Traces 能看见异常
  2. 判断:Alertmanager 能区分严重程度和归属团队
  3. 通知:通过 IM、电话、工单、值班系统送达
  4. 复盘:故障后优化规则、图表、日志字段和 Runbook

11.2 一条很实用的实践建议

可以把 Signals 的角色分工记成一句话:

  • Events:告诉你 Kubernetes 刚刚做了什么、失败了什么
  • Metrics:告诉你系统趋势是否异常
  • Logs:告诉你具体报了什么错
  • Traces:告诉你问题卡在调用链哪里
  • Alertmanager:负责把“值得行动的问题”送到人面前

只有把这几者串成闭环,可观测性才真正从“看板工程”变成“响应工程”。

12. 本章小结

这一章你可以记住 5 句话:

  1. Events 是 Kubernetes 的即时异常线索,不是长期事实仓库。::cite[405]
  2. 排障时先看对象状态和 Events,通常能最快找到第一现场。::cite[406]
  3. Alertmanager 的核心价值在于去重、分组、路由、静默和抑制。::cite[359]
  4. 告警体系的关键不是“规则多”,而是“告警是否可行动”。
  5. 从能看见问题,到能及时响应问题,中间差的不是一个图表,而是一整套闭环机制。

📝 版权声明:本文为原创技术博客,转载请注明出处。

如文章中存在错误或不准确之处,欢迎在评论区指正,感谢您的阅读与支持!

上一篇

4.1 Kubernetes 网络模型

下一篇

1.3 快速上手:搭建本地实验环境