Skip to content

14 — 可观测性体系深度教材

可观测性三大支柱:Metrics(指标)、Logging(日志)、Tracing(链路追踪)。本章覆盖 Prometheus/Grafana/Loki/Jaeger/OpenTelemetry 全套方案。


1. Prometheus 监控体系

1.1 架构

Prometheus 架构:
┌──────────────┐
│ Prometheus   │ ← 定期 pull 指标(15s 默认)
│ Server       │
├──────────────┤
│ TSDB         │ ← 时序数据库(本地存储)
├──────────────┤
│ Alertmanager │ ← 告警路由(邮件/钉钉/Slack)
└──────┬───────┘
       │ pull
┌──────▼───────┐ ┌────────────┐ ┌──────────────┐
│ node-exporter│ │ kube-state │ │ cAdvisor       │
│ (节点指标)    │ │ (K8s 状态) │ │ (容器指标)     │
└──────────────┘ └────────────┘ └──────────────┘

生产架构升级(kube-prometheus-stack):
  Prometheus Operator → 管理多个 Prometheus 实例
  Thanos/Cortex → 长期存储 + 跨集群查询 + 高可用

1.2 关键指标

promql
# 节点资源使用
node_cpu_seconds_total{mode="idle"}               # CPU 空闲率
node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes  # 内存可用率
node_filesystem_avail_bytes / node_filesystem_size_bytes     # 磁盘可用率

# Pod 资源使用
container_cpu_usage_seconds_total{namespace="production"}    # Pod CPU 使用
container_memory_working_set_bytes{namespace="production"}   # Pod 内存使用

# K8s 状态
kube_pod_status_phase{phase="Pending"}              # Pending Pod 数量
kube_node_status_condition{condition="Ready",status="false"} # NotReady 节点
kube_deployment_status_replicas_unavailable         # 不可用副本数

# 告警规则示例
- alert: HighCPUUsage
  expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
  for: 5m
  labels:
    severity: warning

1.3 生产告警配置

yaml
# Alertmanager 路由
route:
  receiver: default
  routes:
  - match:
      severity: critical
    receiver: pagerduty
    repeat_interval: 1h
  - match:
      severity: warning
    receiver: slack
    repeat_interval: 4h

receivers:
- name: pagerduty
  pagerduty_configs:
  - service_key: 'xxx'
- name: slack
  slack_configs:
  - api_url: 'https://hooks.slack.com/services/xxx'
    channel: '#alerts'

2. Grafana 看板

bash
# 推荐看板(Grafana Dashboard ID)
# 8588  - Kubernetes Cluster Monitoring
# 315   - Kubernetes cluster monitoring
# 13770 - Kubernetes / Compute Resources / Cluster
# 15757 - Kubernetes / Compute Resources / Namespace (Pods)
# 1860  - Node Exporter Full

# 生产看板层次:
# Level 1: 集群概览(节点/Pod 数量、资源总量)
# Level 2: 命名空间视图(各 NS 资源使用)
# Level 3: Pod 详情(CPU/内存/网络/磁盘)
# Level 4: 应用指标(QPS/延迟/错误率)

3. 日志体系 — Loki + Fluent Bit

日志流水线:
  应用日志 → Fluent Bit(采集) → Loki(存储) → Grafana(查询)

Loki 优势(vs ELK):
  - 不索引日志内容,只索引标签(资源占用低 10 倍)
  - 与 Grafana 深度集成
  - 支持 S3/MinIO 对象存储后端
yaml
# Fluent Bit 配置(DaemonSet)
[INPUT]
    Name tail
    Path /var/log/containers/*.log
    Parser cri
    Tag kube.*

[FILTER]
    Name kubernetes
    Match kube.*
    Merge_Log On

[OUTPUT]
    Name loki
    Match *
    Host loki.monitoring.svc
    Port 3100
    Labels {job="fluentbit"}
    Label_Keys $kubernetes_namespace_name,$kubernetes_pod_name
bash
# LogQL 查询示例
# 查看某 Pod 的日志
{namespace="production", pod=~"web-app.*"} |= "ERROR"

# 统计错误率
sum(rate({namespace="production"} |= "ERROR" [5m])) by (pod)

# 过滤特定容器
{namespace="production", pod="web-app-xxx", container="app"}

4. 链路追踪 — Jaeger + OpenTelemetry

OpenTelemetry 架构:
  应用 → OTel SDK(自动/手动埋点)→ OTel Collector → Jaeger/Tempo

OTel Collector 作用:
  - 接收(gRPC/HTTP)
  - 处理(采样、脱敏、过滤)
  - 导出(Jaeger、Tempo、Zipkin)
yaml
# OTel Collector 配置
receivers:
  otlp:
    protocols:
      grpc:
        endpoint: 0.0.0.0:4317
processors:
  batch:
    timeout: 5s
  memory_limiter:
    limit_mib: 512
exporters:
  jaeger:
    endpoint: jaeger-collector:14250
  tempo:
    endpoint: tempo:4317
service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [batch, memory_limiter]
      exporters: [jaeger, tempo]

5. 面试高频问题

Q: Prometheus 数据量大导致 OOM 怎么处理?

1. 降低采集频率:scrape_interval 从 15s 改为 30s
2. 指标过滤:metric_relabel_configs 丢弃不需要的指标
3. 减少 series:降低 label 基数(高基数 label 是元凶)
4. 分片:多个 Prometheus 实例按 namespace 分片
5. 长期存储:Thanos/Cortex 卸载历史数据到对象存储
6. 检查高基数:promtool check cardinality

Q: 如何设计告警分级?

P0(立即响应):集群不可用、核心服务全部挂掉
P1(15 分钟内):单服务不可用、节点故障
P2(1 小时内):资源使用率 >80%、证书即将过期
P3(24 小时内):Pod 重启次数异常、磁盘增长趋势