返回首页

7.1 Metrics:Prometheus + Grafana

本章你会学到什么

  • 为什么 Kubernetes 需要一套完整的指标体系
  • Prometheus 在 Kubernetes 中采集指标的常见方式
  • ServiceMonitorPodMonitor 的区别与使用场景
  • Grafana 仪表盘应该如何分层设计
  • 从节点、Pod 到应用服务,哪些指标最值得盯

1. 为什么 Kubernetes 需要指标体系

在单机时代,排障往往靠 topps、应用日志就能快速定位问题;但 Kubernetes 是一个动态调度、资源共享、对象众多的分布式系统,单次故障往往会跨越节点、容器、工作负载、副本集、Service 甚至 Ingress。仅靠人工登录节点或偶尔执行一次 kubectl top,只能看到某个瞬时切面,无法形成持续的趋势观察。Kubernetes 官方也把指标、日志、追踪视为可观测性的三大支柱,用于理解集群内部状态、性能与健康度。::cite[419]

Kubernetes 自带的 Metrics API 主要提供节点与 Pod 的 CPU、内存等基础资源数据,适合 HPA、VPA 和 kubectl top 这类“轻量资源观察”场景;但如果你想进一步观察请求速率、错误率、延迟分位数、容器重启趋势、工作负载状态、控制器行为,甚至希望做长期趋势分析和告警,就需要引入 Prometheus 这样的完整指标系统。::cite[355]

1.1 指标体系到底解决什么问题

一个成熟的指标体系,通常同时解决下面 4 类问题:

  1. 看健康:节点是否吃满?Pod 是否频繁重启?服务错误率是否升高?
  2. 看趋势:今天的 CPU、内存、QPS、P95 延迟,和昨天、上周相比有没有异常?
  3. 看关联:是节点资源紧张导致 Pod 抖动,还是应用本身处理慢?
  4. 看动作:是否应该扩容、限流、回滚,还是先排查依赖链路?

换句话说,指标不是为了“做几个炫酷图表”,而是为了把“系统是否正常”从凭感觉,变成可量化、可对比、可告警的工程能力。

2. Kubernetes 监控视角:从节点到应用

做 Kubernetes 监控时,不建议一上来就堆海量图表。更实用的方法,是按层次看指标。

2.1 四层监控视角

层级 关注对象 典型问题 关键指标
节点层 Node / kubelet / 宿主机 机器是否顶满、磁盘是否异常、网络是否拥塞 CPU、内存、磁盘、网络、文件系统使用率
容器 / Pod 层 Pod / Container Pod 是否频繁重启、是否被 OOMKill、是否节流 重启次数、CPU 使用率、CPU throttling、内存工作集、重启原因
工作负载层 Deployment / StatefulSet / DaemonSet 副本是否不足、滚动发布是否卡住 Ready 副本数、Unavailable 副本数、期望/实际副本差值
应用层 HTTP / RPC / MQ 服务 用户是否感知故障、延迟是否上升 QPS、错误率、P95/P99 延迟、饱和度、队列长度

2.2 一个简单原则:基础资源看 USE,服务体验看 RED

Grafana 官方在仪表盘设计中推荐优先使用 USE 和 RED 两种视角:USE 关注资源的利用率(Utilization)饱和度(Saturation)错误(Errors),更适合节点、磁盘、网络等基础设施;RED 关注服务的请求速率(Rate)错误(Errors)时延(Duration),更适合面向用户体验的服务监控。对于告警,Grafana 也明确建议优先对症状告警,也就是更偏向 RED 的视角。::cite[413]

因此,Kubernetes 里很常见的一种做法是:

  • 节点、容器、存储层:以 USE 为主
  • 应用服务、接口、业务入口:以 RED 为主
  • 业务系统总览页:同时保留 USE + RED,做从“资源”到“体验”的联动排查

3. Prometheus 在 Kubernetes 中如何采集指标

Prometheus 的经典工作方式是“拉取式采集(pull)”。在 Kubernetes 里,它会基于服务发现找到目标,再去抓取 /metrics 端点。相比手工维护静态目标列表,Prometheus Operator 把大量配置抽象成了 Kubernetes CRD,其中最常见的就是 ServiceMonitorPodMonitor。Prometheus Operator 官方文档也专门以它们作为 Kubernetes 监控入门方式。::cite[367]::cite[368]

3.1 先理解 Kubernetes 原生 Metrics API 的边界

Kubernetes 的 Metrics API 只提供节点与 Pod 的基础 CPU、内存指标,并由 metrics-server 统一从 kubelet 拉取,再提供给 HPA、VPA 与 kubectl top 使用。它非常适合自动扩缩容和快速查看资源消耗,但它并不是完整的时序监控平台。::cite[355]

所以在生产里,你通常会同时保留两条线:

  • 轻量资源线:metrics-server + Metrics API + HPA/VPA
  • 完整可观测线:Prometheus + kube-state-metrics + node exporter + 应用自定义指标

3.2 ServiceMonitor 是什么

ServiceMonitor 面向 Service 做发现。它的思路是:先让应用通过 Service 暴露一个带名字的 metrics 端口,然后让 Prometheus 根据 Service 的标签匹配到目标,最后去拉取该 Service 对应后端 Pod 的指标。Prometheus Operator 官方文档给出的示例也是先创建 Service,再通过 ServiceMonitor 进行选择。::cite[368]

适合场景:

  • 应用已经有稳定的 Service 暴露方式
  • 希望把指标采集入口和服务访问方式统一起来
  • 更适合长期维护、对接规范清晰的业务服务

3.3 PodMonitor 是什么

PodMonitor 直接基于 Pod 标签 发现目标,不依赖 Service。Prometheus Operator 文档明确指出,PodMonitor 可以绕过 Service,直接根据 Pod 标签抓取。::cite[368]

适合场景:

  • 不想额外创建 Service,只想采集 Pod 级指标
  • 某些批处理任务、短生命周期组件没有长期稳定的 Service
  • 你希望把采集粒度直接落到 Pod 上

3.4 ServiceMonitor 和 PodMonitor 怎么选

对比项 ServiceMonitor PodMonitor
发现对象 Service Pod
是否依赖 Service 依赖 不依赖
配置入口 通过 Service 标签选择 通过 Pod 标签选择
适用场景 常规业务服务、长期运行服务 Job、Sidecar、临时组件、无需 Service 的场景
运维体验 与服务暴露方式更统一 更灵活,控制粒度更细

实战里,你可以把它理解成一句话:“有标准服务入口时优先 ServiceMonitor;没有 Service 或更强调灵活性时用 PodMonitor。”

4. 实操:部署 kube-prometheus-stack 并接入应用指标

下面用一个最常见的路线演示:

  1. 安装 Prometheus + Grafana 套件
  2. 部署一个暴露 /metrics 的示例应用
  3. ServiceMonitorPodMonitor 接入采集

4.1 安装监控栈

如果你只是想快速搭起一套教学环境,最省事的方式通常是安装 kube-prometheus-stack

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

kubectl create namespace monitoring

helm upgrade --install kube-prom-stack prometheus-community/kube-prometheus-stack \
  --namespace monitoring

安装完成后,Prometheus、Alertmanager、Grafana、node exporter、kube-state-metrics 等常见组件会一起就位。生产环境里,你再根据保留周期、存储、认证、告警接收器做二次定制即可。

4.2 部署一个示例应用

下面这个示例应用假设会在 :8080/metrics 暴露 Prometheus 指标。

apiVersion: v1
kind: Namespace
metadata:
  name: observability-demo
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-api
  namespace: observability-demo
  labels:
    app: demo-api
spec:
  replicas: 2
  selector:
    matchLabels:
      app: demo-api
  template:
    metadata:
      labels:
        app: demo-api
    spec:
      containers:
        - name: demo-api
          image: ghcr.io/example/demo-api:1.0.0
          ports:
            - name: http
              containerPort: 8080
          readinessProbe:
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 10
          livenessProbe:
            httpGet:
              path: /livez
              port: 8080
            initialDelaySeconds: 10
            periodSeconds: 20
---
apiVersion: v1
kind: Service
metadata:
  name: demo-api
  namespace: observability-demo
  labels:
    app: demo-api
spec:
  selector:
    app: demo-api
  ports:
    - name: http-metrics
      port: 8080
      targetPort: 8080

4.3 用 ServiceMonitor 接入采集

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: demo-api
  namespace: monitoring
  labels:
    team: platform
spec:
  namespaceSelector:
    matchNames:
      - observability-demo
  selector:
    matchLabels:
      app: demo-api
  endpoints:
    - port: http-metrics
      path: /metrics
      interval: 15s
      scrapeTimeout: 10s

4.4 用 PodMonitor 接入采集

如果你不想依赖 Service,也可以这样写:

apiVersion: monitoring.coreos.com/v1
kind: PodMonitor
metadata:
  name: demo-api-direct
  namespace: monitoring
  labels:
    team: platform
spec:
  namespaceSelector:
    matchNames:
      - observability-demo
  selector:
    matchLabels:
      app: demo-api
  podMetricsEndpoints:
    - port: http
      path: /metrics
      interval: 15s
      scrapeTimeout: 10s

4.5 让 Prometheus 选中这些 Monitor

Prometheus Operator 文档强调,Prometheus 实例会通过 serviceMonitorSelectorpodMonitorSelector 去决定采集哪些对象。也就是说:你不只是写了 Monitor 资源,还得确保 Prometheus 本身能选中它们。::cite[368]

下面给一个最小可读示例:

apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
  name: platform
  namespace: monitoring
spec:
  serviceMonitorSelector:
    matchLabels:
      team: platform
  podMonitorSelector:
    matchLabels:
      team: platform
  serviceMonitorNamespaceSelector: {}
  podMonitorNamespaceSelector: {}
  replicas: 1

5. Grafana 仪表盘应该怎么设计

Grafana 官方建议尽量减少认知负担,使用模板变量避免仪表盘泛滥,并通过分层与 drill-down 的方式,把“总览 → 集群 → 命名空间 → 工作负载 → Pod”串起来。::cite[413]

5.1 一个实用的分层方案

可以按下面 4 层来设计:

  1. 平台总览页

    • 集群节点总数、不可用节点数
    • 总 CPU/内存使用率
    • Pod 总数、Pending Pod 数量
    • 关键业务入口 QPS、错误率、P95
  2. 节点资源页

    • 节点 CPU 利用率
    • 内存工作集 / 可用内存
    • 文件系统利用率
    • 网络收发速率、丢包趋势
  3. 工作负载页

    • Deployment Ready 副本 / 期望副本
    • Pod 重启趋势
    • 容器 CPU 节流比例
    • OOMKill、Evicted、CrashLoopBackOff 关联视图
  4. 应用服务页

    • 请求速率(RPS/QPS)
    • 错误率(4xx/5xx 或业务错误码)
    • 延迟(P50/P95/P99)
    • 上游 / 下游依赖失败率

5.2 常见图表类型怎么选

图表类型 适合展示 示例
Stat / Gauge 当前状态值 节点 Ready 数、错误率、磁盘使用率
Time series 趋势变化 CPU、内存、QPS、P95 延迟
Bar gauge 横向比较 命名空间资源消耗 Top N
Heatmap 分位分布 延迟分布、请求耗时密度
Table 状态列表 重启最多的 Pod、错误最多的服务

5.3 设计仪表盘时最容易犯的错误

  • 把所有指标都堆到一页,导致看板信息过载
  • 每个集群、每个节点、每个应用都单独复制一套 Dashboard
  • 只展示资源使用率,不展示错误率和延迟
  • 只看平均值,不看分位数和异常峰值
  • 告警直接绑在“看着很热闹”的图表上,而不是绑在有行动价值的指标上

6. 从节点、Pod 到应用,关键监控指标清单

下面这张表是比较适合入门阶段直接落地的一版“必看指标清单”。

层级 指标建议 为什么重要
节点 CPU 利用率、Load、内存使用率、磁盘使用率、磁盘 inode、网络吞吐 节点资源见底会影响调度与稳定性
Pod Pod 重启次数、容器 CPU / 内存、OOMKill、容器节流、Pending 时长 最能直观看到工作负载是否健康
工作负载 Ready 副本、Unavailable 副本、滚动发布状态、HPA 当前/目标副本 能快速判断控制器是否按预期工作
应用 QPS、错误率、P95/P99 延迟、队列长度、连接数、缓存命中率 最接近用户体验与业务影响
平台组件 apiserver 请求延迟、etcd 延迟、调度器延迟、控制器队列积压 有助于判断问题是在业务侧还是控制面

6.1 入门阶段建议先盯住这 8 个指标

如果你还没有形成自己的监控标准,建议先把下面 8 类指标做好:

  1. 节点 CPU 利用率
  2. 节点内存利用率
  3. 节点磁盘使用率
  4. Pod 重启次数
  5. Pod / 容器内存工作集
  6. 容器 CPU 使用率与 throttling
  7. 应用请求错误率
  8. 应用 P95 / P99 延迟

只要这 8 类指标被稳定采集、图表清晰、告警合理,绝大多数“集群变慢、服务抖动、资源不够、发布异常”的问题,你都能比过去更快定位。

7. 一套适合练手的排障流程

当你接到“服务慢了”这类工单时,可以按下面顺序看:

  1. 先看应用页:QPS、错误率、P95 是否异常
  2. 再看工作负载页:副本是否不足,是否有 Pod 重启
  3. 继续看 Pod 明细:是否 OOMKill,是否 CPU 被节流
  4. 最后看节点页:是否节点资源打满或磁盘异常

这个顺序的本质是:先看用户症状,再看工作负载状态,最后回到基础设施。 这样排障会更符合真实故障传播路径。

8. 本章小结

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

  1. Kubernetes 自带 Metrics API 够用来做基础资源观察,但不够支撑完整监控体系。::cite[355]
  2. Prometheus 是 Kubernetes 指标监控的事实标准方案之一,适合做长期时序存储、查询、告警。::cite[419]
  3. ServiceMonitor 适合标准服务采集,PodMonitor 更灵活,适合直接采集 Pod。::cite[368]
  4. Grafana 仪表盘不要“堆图”,要按总览、钻取、USE/RED 思路组织。::cite[413]
  5. 真正有价值的监控,不是图多,而是能回答“哪里坏了、为什么坏、下一步该做什么”。

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

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

上一篇

4.4 Ingress 与网关

下一篇

8.2 Kubernetes 高可用架构