本章你会学到什么
- 为什么 Kubernetes 需要一套完整的指标体系
- Prometheus 在 Kubernetes 中采集指标的常见方式
ServiceMonitor与PodMonitor的区别与使用场景- Grafana 仪表盘应该如何分层设计
- 从节点、Pod 到应用服务,哪些指标最值得盯
1. 为什么 Kubernetes 需要指标体系
在单机时代,排障往往靠 top、ps、应用日志就能快速定位问题;但 Kubernetes 是一个动态调度、资源共享、对象众多的分布式系统,单次故障往往会跨越节点、容器、工作负载、副本集、Service 甚至 Ingress。仅靠人工登录节点或偶尔执行一次 kubectl top,只能看到某个瞬时切面,无法形成持续的趋势观察。Kubernetes 官方也把指标、日志、追踪视为可观测性的三大支柱,用于理解集群内部状态、性能与健康度。::cite[419]
Kubernetes 自带的 Metrics API 主要提供节点与 Pod 的 CPU、内存等基础资源数据,适合 HPA、VPA 和 kubectl top 这类“轻量资源观察”场景;但如果你想进一步观察请求速率、错误率、延迟分位数、容器重启趋势、工作负载状态、控制器行为,甚至希望做长期趋势分析和告警,就需要引入 Prometheus 这样的完整指标系统。::cite[355]
1.1 指标体系到底解决什么问题
一个成熟的指标体系,通常同时解决下面 4 类问题:
- 看健康:节点是否吃满?Pod 是否频繁重启?服务错误率是否升高?
- 看趋势:今天的 CPU、内存、QPS、P95 延迟,和昨天、上周相比有没有异常?
- 看关联:是节点资源紧张导致 Pod 抖动,还是应用本身处理慢?
- 看动作:是否应该扩容、限流、回滚,还是先排查依赖链路?
换句话说,指标不是为了“做几个炫酷图表”,而是为了把“系统是否正常”从凭感觉,变成可量化、可对比、可告警的工程能力。
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,其中最常见的就是 ServiceMonitor 和 PodMonitor。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 并接入应用指标
下面用一个最常见的路线演示:
- 安装 Prometheus + Grafana 套件
- 部署一个暴露
/metrics的示例应用 - 用
ServiceMonitor和PodMonitor接入采集
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 实例会通过 serviceMonitorSelector 和 podMonitorSelector 去决定采集哪些对象。也就是说:你不只是写了 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 层来设计:
-
平台总览页
- 集群节点总数、不可用节点数
- 总 CPU/内存使用率
- Pod 总数、Pending Pod 数量
- 关键业务入口 QPS、错误率、P95
-
节点资源页
- 节点 CPU 利用率
- 内存工作集 / 可用内存
- 文件系统利用率
- 网络收发速率、丢包趋势
-
工作负载页
- Deployment Ready 副本 / 期望副本
- Pod 重启趋势
- 容器 CPU 节流比例
- OOMKill、Evicted、CrashLoopBackOff 关联视图
-
应用服务页
- 请求速率(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 类指标做好:
- 节点 CPU 利用率
- 节点内存利用率
- 节点磁盘使用率
- Pod 重启次数
- Pod / 容器内存工作集
- 容器 CPU 使用率与 throttling
- 应用请求错误率
- 应用 P95 / P99 延迟
只要这 8 类指标被稳定采集、图表清晰、告警合理,绝大多数“集群变慢、服务抖动、资源不够、发布异常”的问题,你都能比过去更快定位。
7. 一套适合练手的排障流程
当你接到“服务慢了”这类工单时,可以按下面顺序看:
- 先看应用页:QPS、错误率、P95 是否异常
- 再看工作负载页:副本是否不足,是否有 Pod 重启
- 继续看 Pod 明细:是否 OOMKill,是否 CPU 被节流
- 最后看节点页:是否节点资源打满或磁盘异常
这个顺序的本质是:先看用户症状,再看工作负载状态,最后回到基础设施。 这样排障会更符合真实故障传播路径。
8. 本章小结
这一章你可以记住 5 句话:
- Kubernetes 自带 Metrics API 够用来做基础资源观察,但不够支撑完整监控体系。::cite[355]
- Prometheus 是 Kubernetes 指标监控的事实标准方案之一,适合做长期时序存储、查询、告警。::cite[419]
ServiceMonitor适合标准服务采集,PodMonitor更灵活,适合直接采集 Pod。::cite[368]- Grafana 仪表盘不要“堆图”,要按总览、钻取、USE/RED 思路组织。::cite[413]
- 真正有价值的监控,不是图多,而是能回答“哪里坏了、为什么坏、下一步该做什么”。
📝 版权声明:本文为原创技术博客,转载请注明出处。
如文章中存在错误或不准确之处,欢迎在评论区指正,感谢您的阅读与支持!