可观测性由三条互补的数据线构成:日志记录离散事件(发生了什么),指标提供可聚合的数值序列(现在怎么样),追踪还原单个请求的全链路(经过了哪里、慢在哪一跳)。三支柱各自回答不同问题,合起来才能拼出故障现场的完整图景。
声明跑起来之后,第一件事是装眼睛。第3章排障案例里用过的 kubectl logs 其实只是日志支柱的最小切片;本节把三条数据线各自的采集链路、查看姿势与适用问题讲全——并说清为什么只盯其中一条必然留下盲区。
**日志:离散事件的流水账。**第一现场工具是 kubectl logs,三个高频参数各对应一种取证场景:
# 场景一:看当前输出并持续跟随(发布会盯屏用) kubectl logs -f deployment/orders-api -n production --tail=50 # [INFO ] order created id=98123 latency_ms=42 # [WARN ] payment slow partner=payB latency_ms=1800 # 场景二:看上一轮容器的临终日志(CrashLoop 取证的唯一途径,1.3 节用过) kubectl logs orders-api-7b6d4c9f8-t2m9p -n production -p --tail=10 # FATAL cannot connect to db: dial timeout # 场景三:多容器 Pod 指定容器(sidecar 场景,1.3 节的 log-shipper) kubectl logs orders-with-sidecar -c log-shipper -n production --tail=5 # shipped 128 lines to central platform
单机日志只是应急手段,规模化后日志的采集靠 DaemonSet 部署的采集器(4.3 节的 node-logger 正是它):每节点一份,统一送往集中平台检索。应用侧要守两条纪律:输出到标准输出与标准错误(kubelet 只接管这两条流);一行一事带级别与上下文,让检索有抓手。
**指标:可聚合的数值序列。**采集链路三层:cAdvisor 在节点上量容器(3.3 节解剖图里的配角)、指标服务在集群聚合并暴露接口、监控栈(如 Prometheus 加 Grafana)抓取存储与告警。kubectl 也能直接问指标服务要快照:
# 看 Pod 的实时资源用量(对比 3.1 节的"申报量"与"实用量") kubectl top pods -n production # NAME CPU(cores) MEMORY(bytes) # orders-api-6d9f7c8b5-2vxk7 351m 486Mi # orders-api-6d9f7c8b5-9mjq4 368m 502Mi # 申报 500m 与 512Mi,实用约七成:报价合理,不浪费也不冒险 kubectl top nodes # NAME CPU(cores) CPU% MEMORY(bytes) MEMORY% # node-a 1820m 45% 9.2Gi 61%
top 的价值在对照:申报与实用的差距,既是 3.1 节报价单的验收,也是 HPA 自动扩缩的依据。告警规则围绕两类核心指标配置:资源类(利用率、饱和度)发现容量风险,业务类(请求速率、错误率、时延)发现用户可感的问题。
**追踪:单个请求的全链路。**日志与指标都在讲"面",追踪讲"点":给每个请求发一个追踪号,跨服务传递并记录每跳的耗时,串成瀑布。它回答的是日志和指标都答不了的问题——"这次下单为什么慢了 2 秒":是网关排队、订单服务本身、还是等支付方响应。落地需要应用埋点(或服务网格边车代埋),数据汇入追踪平台(如 Jaeger 或 Tempo 类)后可视化。
| 支柱 | 回答 | 数据形态 | 典型工具链 | 盲区 |
|---|---|---|---|---|
| 日志 | 发生了什么 | 离散文本事件 | kubectl logs 加集中采集 | 无法聚合看趋势 |
| 指标 | 现在怎么样 | 数值时间序列 | 指标服务加监控栈 | 单个请求的细节 |
| 追踪 | 经过哪里多慢 | 跨服务调用链 | 埋点加追踪平台 | 依赖埋点质量与采样 |
背景:用户反馈下单偶发慢(正常 300 毫秒,偶发 2 秒以上,占比约 1%),指标大盘只有平均时延,看不出所以然。
操作:三支柱按各自强项分工——
# 第一步:指标定位面——错误率正常,P99 时延尖刺集中在每日 02:00 与 14:00 # 第二步:追踪定位点——筛时延大于 2 秒的请求,取一条链路看瀑布 # trace 4f2a: gateway 12ms → orders-api 2010ms → db 8ms → payment 1900ms # 瀑布显示:订单服务本身只花 110ms,等待支付接口占 1900ms # 第三步:日志定位因——按追踪号反查订单服务与支付服务日志 kubectl logs -n production deployment/orders-api --since=2h | grep 4f2a # [WARN ] trace=4f2a payment call slow partner=payB latency_ms=1902 retry=1 # 支付方 B 在上述时段有慢查询,超时重试一次后成功
结果:责任方锁定为支付通道 B 的周期性慢查询,与集群无关;订单服务按 3.4 节的教训本就未把外部依赖纳入 liveness,故无重启连锁。
解读:三个支柱在破案中的分工教科书式清晰——指标圈时间与范围(何时何面),追踪锁定环节(哪一跳),日志还原因果(为什么)。只用其中一个都会走弯路:只有指标会怀疑集群,只有日志会被海量噪声淹没,只有追踪看不到 1% 的占比面。
变式:定时任务的偶发失败适合"日志加指标"组合(任务完成时长曲线加失败日志);东西向流量异常(5.3 节策略误伤)则要指标(连接失败计数)与 NetworkPolicy 的审计日志配合。三支柱不是奢侈品,是排障效率的复利投资。
💡 关键直觉:可观测性不是为了"监控"而监控,而是让你在故障时能回答三个问题各一次——发生了什么(日志)、影响多大(指标)、根因在哪(追踪)。回答不了这三个问题的一切面板都是装饰。
看得见了,下一节把这份视力用起来:一套四层排查手册,让"声明与现状不一致"的每一类故障都有固定的诊断序列与判读口径。