监控与告警体系:指标采集、日志收集、告警规则与通知

节点故障的快速定位与集群自愈,前提是“看得见”。监控与告警体系承担着感知集群状态、记录异常痕迹、触发响应动作的三重职责。一个设计良好的监控体系,不是简单堆砌几个开源工具,而是围绕指标(Metrics)、日志(Logs)、告警(Alerts)三条主线,构建从数据采集到人工介入的完整闭环。本章聚焦这三条主线的落地方法、关键规则与常见误区。

4.1 核心原理:三类数据,三种视角

监控体系处理的数据可分为三类,它们各自回答不同的问题,互为补充,缺一不可:

  • 指标(Metrics):周期性采样的数值,如 CPU 使用率、请求延迟、队列深度。指标擅长反映“系统当前是否健康”,数据量小、存储成本低,适合长期保存与趋势分析。
  • 日志(Logs):离散的、带时间戳的事件记录,如错误堆栈、访问记录、状态变更。日志能回答“故障发生时到底发生了什么”,信息量最大,但数据量也最大,需要索引与检索策略。
  • 链路追踪(Traces):一次请求跨多个服务的完整路径。在微服务架构中,追踪是定位“慢调用到底慢在哪个环节”的唯一高效手段。本章以指标与日志为主,追踪作为补充提及。

下图展示了这三类数据在监控体系中的流转路径与协作关系:

节点指标 CPU / 内存 / 磁盘 业务指标 QPS / 延迟 / 错误率 应用日志 错误 / 警告 / 访问 链路追踪 采集与存储层 Prometheus Thanos / Victoria ELK / Loki Jaeger / Zipkin 告警规则引擎 阈值 / 表达式 可视化面板 Grafana / Kibana 通知渠道 钉钉 / 邮件 / Webhook 自愈动作 触发

从图中可以看出,指标与日志在采集后分别进入时序数据库与日志索引系统,再向上支撑告警规则与可视化。告警触发后不仅通知人,也可联动自愈组件执行预定义动作。理解这条链路,是配置监控体系的第一步。

4.2 方法流程:从采集到告警的落地步骤

搭建一套可用的监控告警体系,建议按以下五个步骤推进:

  1. 确定监控对象与指标:先列出集群中的所有节点角色(如控制平面节点、工作节点、存储节点),再为每个角色定义关键指标。例如,工作节点必须监控 kubelet 状态、容器重启次数、节点磁盘压力;控制平面需额外关注 API Server 延迟与 etcd 同步耗时。
  2. 部署采集器:指标采集常用 Prometheus 生态,通过 node_exporter 采集节点指标,通过 kube-state-metrics 获取集群对象状态。日志采集则使用 Filebeat 或 Promtail 将节点日志转发至 Elasticsearch 或 Loki。
  3. 配置存储与保留策略:时序数据需设置合理的保留周期(如 15 天),日志数据则按级别区分保留时长(如错误日志 30 天,访问日志 7 天)。
  4. 编写告警规则:基于采集到的指标,使用 PromQL 或类似查询语言定义异常条件。规则应包含:告警名称、触发条件表达式、持续时间、严重级别与标签。
  5. 配置通知路由:将告警发送至 Alertmanager,由它根据标签匹配路由到不同渠道(如严重级别为 critical 的发给值班组长,warning 的发给运维群)。

以下是一个典型的 Prometheus 告警规则片段,用于检测节点磁盘即将写满的情况:

groups:
  - name: node_alerts
    rules:
      - alert: NodeDiskWillFill
        expr: (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"}) * 100 < 10
        for: 5m
        labels:
          severity: critical
          team: ops
        annotations:
          summary: "节点 {{ $labels.instance }} 磁盘剩余不足 10%"
          description: "当前可用空间 {{ $value | humanizePercentage }},请立即清理或扩容。"

这段规则的含义是:当根分区可用空间占比低于 10% 且持续 5 分钟时,触发 critical 级告警。注意 for: 5m 的作用——它避免了因瞬时抖动而误报,这是生产环境中必须养成的习惯。

4.3 案例场景:一次节点内存泄漏的定位过程

某日 14:20,运维人员收到一条告警:NodeMemoryUsageHigh,提示 node-03 内存使用率超过 90% 已持续 10 分钟。以下是利用监控体系逐步定位的过程:

步骤 操作 数据来源 发现
1 查看内存使用曲线 Grafana 节点面板 内存从 13:00 开始线性增长,无回落
2 按进程排序内存占用 节点上执行 top 某 Java 进程 RSS 达 12GB,远超堆设置
3 检索该进程日志 Loki 中按 Pod 名过滤 频繁出现 OutOfMemoryError 与 GC 超时日志
4 检查容器重启次数 kube-state-metrics 该 Pod 过去 1 小时重启 6 次,均因 OOMKilled

最终确认是应用存在内存泄漏,且未设置合理的 JVM 堆上限,导致容器不断被 cgroup 杀掉。整个过程从收到告警到定位根因,耗时约 15 分钟。如果没有日志检索与指标曲线的配合,仅靠登录服务器逐条排查,可能需要数小时。

建议:在配置告警时,为每个规则附带一条“定位指引”注解,例如“先查 kubectl describe pod 的 Last State,再检索日志关键字 OOM”。这能显著缩短新人的排障时间。

4.4 误区与复盘:告警疲劳与无效通知

监控体系最常见的失败模式不是“没监控”,而是“告警太多,没人看”。以下三个误区值得深刻反思:

  • 阈值设置过于敏感:例如 CPU 使用率超过 50% 就告警,导致日常波动频繁触发。正确的做法是区分“持续异常”与“瞬时抖动”,利用 for 子句拉长观察窗口,或使用更稳健的表达式(如基于过去 15 分钟的平均值)。
  • 缺少告警分级与路由:所有告警都发给同一个群,重要告警被淹没。应至少区分 critical(立即处理)、warning(工作时间处理)、info(记录即可)三个级别,并分别路由到不同对象。
  • 只告警不记录动作:告警发出后,处理结果没有回写到监控系统。建议在告警管理平台中关联工单号或处理记录,便于事后复盘哪些告警是无效的、哪些规则需要调整。

一个实用的复盘方法是:每周统计告警总数、误报率、平均响应时间。如果误报率超过 30%,说明规则需要优化;如果某类告警从未触发过人工处理,考虑将其降级或删除。监控体系本身也需要持续迭代,它与集群一样,是一个需要“自愈”的活系统。

注意:不要将告警通知渠道作为唯一依赖。当集群全面故障时,Alertmanager 所在的节点可能同时宕机。建议配置二级通知(如短信或电话),并确保告警组件本身具备高可用部署。