深色模式
K8s 可观测性总览:Metrics / Logs / Traces / Profiles / Events
摘要:本文面向生产 SRE / 平台工程师,建立 Kubernetes 可观测性的整体心智模型:五大信号是什么、谁产生、怎么采集、如何关联、何时该用哪一种。覆盖 Metrics/Logs/Traces 三支柱,并补齐 Profiles 与 Events 两个常被忽略的信号;给出 RED(速率/错误/时延)与 USE(利用率/饱和度/错误)方法的适用边界,以及它们与 SLO、错误预算的关联方式。适用 Kubernetes v1.28+。
适用版本与前提
- Kubernetes:v1.28+(内置组件
/metrics端点、OpenTelemetry 链路导出均稳定可落地) - 工具:
kubectl、metrics-server、kube-state-metrics、Prometheus、OpenTelemetry Collector - 前提:已具备集群读取权限;控制面组件以默认
--bind-address暴露/metrics
背景与问题
Kubernetes 把"单体应用"拆成大量短生命周期、随时迁移的 Pod。传统"登上机器看日志、top 看负载"的方式彻底失效:你不知道某次请求经过了多少服务、卡在哪一段、是哪个 Pod 崩了。可观测性(Observability)不是"多装几个 agent",而是让系统通过它自己吐出的信号,反推出内部状态的能力。
四句话建立直觉
- Metrics:系统"好不好"的聚合数字(速率、错误率、延迟)——回答"是否异常"。
- Logs:某一刻"发生了什么"的事实记录——回答"具体错在哪一行"。
- Traces:一次请求"穿越了哪些服务、耗时分布"——回答"慢在哪一段"。
- Profiles / Events:CPU/内存火焰图(为什么慢)与集群对象状态变更(谁动了配置)——补齐"为什么"和"谁"。
核心概念:五大信号
Kubernetes 官方文档将集群组件产生的信号归为 Metrics、Logs、Traces 三类(官方称为"three pillars of observability")。在生产实践中,还需要补上 Profiles 与 Events 两类,才能完整闭环。
| 信号 | 产生方 | 采集方式 | 回答的问题 | 存储后端举例 |
|---|---|---|---|---|
| Metrics | kubelet/cAdvisor、kube-state-metrics、应用 /metrics | pull(scrape) | 系统是否健康?趋势如何? | Prometheus / Thanos |
| Logs | 容器 stdout/stderr、控制面、审计 | push(agent tail) | 具体哪条记录出错? | Loki / Elasticsearch |
| Traces | 应用 SDK(OTLP)、控制面 span | push(OTLP) | 一次请求慢在哪一段? | Jaeger / Tempo |
| Profiles | 应用/运行时 continuous profiling | push/pull | CPU/内存被谁吃掉? | Pyroscope / Parca |
| Events | kube-apiserver、kubelet、控制器 | watch/持久化 | 谁改了对象、为何被驱逐? | events exporter / Loki |
版本相关
Kubernetes 自 v1.25+ 起可通过内置 gRPC exporter 或 OpenTelemetry Collector 出口 span(OTLP),将控制面组件 span 接入追踪后端;具体 exporter 开关随版本演进,请以目标版本 kube-apiserver/kube-scheduler 的 --tracing-* 参数文档为准。
架构与原理:典型采集链路
下图给出生产集群中三类主信号(外加 Events/Profiles)的流向。注意控制面组件天然暴露 Prometheus 格式指标,无需额外埋点。
原理要点:
- Metrics 是 pull 模型:Prometheus 周期性从
/metrics拉取,天然适配"被监控方无状态、监控方统一调度"。控制面组件(kube-apiserver、kube-controller-manager、kube-scheduler、kube-proxy、kubelet)都暴露/metrics,kubelet 还额外有/metrics/cadvisor、/metrics/resource、/metrics/probes。 - Logs 是 push 模型:容器运行时按 CRI 日志格式把 stdout/stderr 写入节点文件(默认
/var/log/pods/*/*/*.log),节点级 agent(Fluent Bit / Promtail)tail 后转发到中心存储。 - Traces 是 push 模型:应用通过 OpenTelemetry SDK 产生 span,经 OTLP 推给 Collector,再做采样、脱敏后落库。
- Events 易被忽视:
kubectl get events默认只保留 1 小时(由kube-apiserver的--event-ttl控制,默认 1h),事故复盘常已过期;生产应导出到持久存储。
RED 与 USE:两套互补的选指标方法
可观测性的最大陷阱是"什么都监控"。RED 与 USE 是两套检查清单式的选指标框架,互不替代。
- RED(Tom Wilkie,Weaveworks,2015):面向"请求驱动型服务",每个服务暴露 Rate(每秒请求数)/ Errors(失败请求数)/ Duration(延迟分布,用直方图取分位)。它衡量"用户爽不爽",是症状视角。
- USE(Brendan Gregg,2012):面向"每个资源",检查 Utilization(利用率)/ Saturation(饱和度,如队列长度、CPU 节流)/ Errors(错误事件)。它衡量"机器是不是瓶颈",是原因视角。
两者盲区的典型事故
某 checkout 服务 p99 延迟从 180ms 飙到 2.4s。RED 视角:duration 涨、rate 平、errors 从 0.1% 升到 2%——确认"用户受影响了",但不知道为什么。USE 视角扫一遍资源,发现数据库主机 CPU 96% 利用率、运行队列是核数的 3 倍(饱和度)、零硬件错误——瓶颈是数据库 CPU(可能 13:55 上了个无索引查询)。两者单独用都关不了事故,必须一起用:RED 定位"现象",USE 定位"根因"。
Google SRE 书的"四个黄金指标"(Latency/Traffic/Errors/Saturation)是更上层的伞:RED 约等于黄金信号去掉 Saturation,USE 补上资源侧的 Saturation。
标准 RED 与 USE 指标速查
RED(服务侧,来自 OTel http.server.request.duration 直方图或自定义计数器)
- Rate:
sum(rate(http_server_request_duration_seconds_count{service="x"}[5m])) - Errors:
sum(rate(...{code=~"5.."}[5m])) / sum(rate(...[5m])) - Duration p99:
histogram_quantile(0.99, sum by (le) (rate(http_server_request_duration_seconds_bucket{service="x"}[5m])))
USE(节点侧,来自 node-exporter / cAdvisor)
- Utilization:节点 CPU
1 - avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) - Saturation:容器 CPU 节流
rate(container_cpu_cfs_throttled_periods_total[5m])(K8s 中 limits 导致的节流是经典饱和度信号,利用率看不出来) - Errors:磁盘 I/O 错误
node_disk_io_errors_total、node_network_receive_errs_total
SLO 与错误预算:把"信号"接回"业务"
指标本身不是目的。SLO(Service Level Objective)用 SLI(可测量的指标)表达"用户能接受的可靠性",例如"30 天内 99.9% 的请求成功"。错误预算 = 1 − SLO = 0.1%,是允许失败的额度。
- 告警应基于症状(RED)而非原因(USE):高 CPU 不一定该叫醒人,但错误率突破 SLO 预算燃烧速度就该 page。
- 燃烧速率(Burn Rate)告警:衡量"预算消耗速度"。详见本分类
alerting.md。本章只需记住:RED 指标 → 计算 SLI → 对照错误预算 → 触发分级别(page/ticket)告警,这就是信号到行动的闭环。
生产危险
切忌把"CPU > 80%"直接配成 page 级告警。同一高 CPU,在计划内批处理时无害,在拖慢 checkout 时是事故。对原因类指标做 cause-based 告警会产生大量误报,训练团队忽略 pager,最终漏掉真正重要的那条。页面只留给 RED/SLO 症状。
生产实践:信号关联是价值所在
可观测性真正的 ROI 不在"采集",而在"关联"。三条落地纪律:
- 统一 label 体系:在所有信号里使用同一套
service、namespace、pod、cluster标签。Loki 与 Prometheus label 一致,才能"从指标尖峰一键跳到日志流"。 - Exemplar 打通 Metrics→Traces:Prometheus 直方图开启 exemplar,把 trace_id 写进样本;Grafana 面板可直接从指标跳到对应 trace。
- derived fields 打通 Logs→Traces:在 Loki 数据源配置从日志行提取 trace_id 的 derived field,点击跳转 Tempo/Jaeger。
验证
bash
# 1. 指标链路:控制面端点可达
kubectl get --raw /apis/metrics.k8s.io/v1/nodes | head
kubectl get --raw /metrics | head -5 # 需对 apiserver 端口可达
# 2. 日志链路:容器日志可读
kubectl logs deploy/example-app -n default --tail=20
# 3. 追踪链路:Collector 接收端口在监听
kubectl exec deploy/otel-collector -n monitoring -- \
ss -ltnp | grep -E '4317|4318'1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
回滚与清理
注意
可观测性组件多为 DaemonSet/StatefulSet,删除前确认不影响业务。下列命令仅清理本文假设的示例 namespace,勿对 monitoring 生产命名空间直接执行。
bash
kubectl delete ns observability-demo # 仅当为独立演示命名空间
kubectl delete --all servicemonitors -n demo1
2
2
故障排查
| 现象 | 可能原因 | 排查 |
|---|---|---|
Prometheus target 为 down | Service/Endpoints 不存在或端口名错 | kubectl get endpoints <svc>;核对 ServiceMonitor port 与 Service port 名称一致 |
| Loki 查询慢/贵 | label 含高基数动态值(user_id、request_id) | 将动态值移入日志行,label 只留静态维度 |
| 追踪断链 | 跨服务未透传 context | 检查 propagator 配置:tracecontext + baggage |
| Events 找不到 | 默认 --event-ttl=1h 已过期 | 部署 event exporter 持久化到 Loki |
性能、容量与成本
- Metrics 成本:时间序列基数 = 活跃 label 组合。一个
pod、le(直方图桶)组合爆炸即可拖垮 Prometheus。控制 label 基数优先于调采集间隔。 - Logs 成本:Loki 只索引 label 不索引内容,比 ES 便宜;但 Debug 级日志在繁忙服务上可能比其余信号加起来还贵,应在采集层(Alloy/Fluent Bit)丢弃。
- Traces 成本:默认 100% 采样不可持续,生产用 tail-based sampling(在 Gateway 层按错误/慢请求/概率保留)。
常见坑
- 把 Loki 当 SIEM / 合规归档用 → 成本与查询性能双输,合规日志另存。
- 延迟用平均值而非分位 → 掩盖用户真实感知的慢尾。
- ServiceMonitor
port写成数字而 Service 定义的是命名端口 → 抓取失败。 - 只在生产做 dashboard,staging 克隆 → 长期多份不同步,用 template variables 替代硬编码环境名。
替代方案与权衡
- Thanos / Cortex / Mimir:解决 Prometheus 单点容量与长期存储,适合多集群/长期留存;代价是架构复杂度与对象存储成本。
- Vendor 托管(Managed Prometheus / Grafana Cloud):省运维,代价是出口成本与锁定。
- eBPF 采集(Pixie 等):无需改代码即可拿指标/追踪,代价是内核版本依赖与权限要求。
FAQ
Q:Metrics 用 push 还是 pull? A:Prometheus 生态是 pull,优点是被监控方无状态、监控方统一调度与防抖;push 适合短生命周期 job(用 Pushgateway)。
Q:Profiles 和 Metrics 区别? A:Metrics 是聚合计数,Profiles 是函数级 CPU/内存占用(火焰图),用于定位"为什么慢/为什么占内存",频率低、体量小,生产价值在性能优化而非告警。
参考资料
- Kubernetes 官方文档 - Observability(概念),访问日期:2026-10-08。
- Kubernetes 官方文档 - Resource metrics pipeline,访问日期:2026-10-08。
- Grafana 文档 - Dashboard best practices(含 RED/USE 说明),访问日期:2026-10-08。
- Tom Wilkie - The RED Method(GrafanaCon 演讲),访问日期:2026-10-08。
- Brendan Gregg - USE Method,访问日期:2026-10-08。
- Google SRE Workbook - Alerting on SLOs(多窗口多燃烧速率),访问日期:2026-10-08。