监控最佳实践

监控最佳实践

本节总结 Kubernetes 监控的最佳实践和常用技巧。

监控方法论

RED 方法(服务监控)

适用于面向用户的服务:

  • Rate(速率): 请求速率(QPS)
  • Errors(错误): 错误率
  • Duration(时长): 响应时间(P50、P95、P99)
# Rate - 请求速率
rate(http_requests_total[5m])

# Errors - 错误率
rate(http_requests_total{status_code=~"5.."}[5m]) 
/ 
rate(http_requests_total[5m])

# Duration - P95 延迟
histogram_quantile(0.95, 
  rate(http_request_duration_seconds_bucket[5m])
)

USE 方法(资源监控)

适用于基础设施资源:

  • Utilization(利用率): 资源使用百分比
  • Saturation(饱和度): 资源排队长度
  • Errors(错误): 错误计数
# Utilization - CPU 利用率
rate(container_cpu_usage_seconds_total[5m])

# Utilization - 内存利用率
container_memory_usage_bytes 
/ 
container_spec_memory_limit_bytes

# Saturation - 磁盘 I/O 等待
rate(node_disk_io_time_seconds_total[5m])

# Errors - 网络丢包
rate(node_network_transmit_drop_total[5m])

四个黄金信号

Google SRE 提出的监控指标:

  1. 延迟(Latency): 请求响应时间
  2. 流量(Traffic): 请求量
  3. 错误(Errors): 失败请求率
  4. 饱和度(Saturation): 资源使用率

告警设计原则

1. 告警分级

labels:
  severity: critical  # 需要立即处理
  severity: warning   # 需要关注,可能影响服务
  severity: info      # 信息性告警

Critical 告警

  • 服务完全不可用
  • 数据丢失风险
  • 安全事件

Warning 告警

  • 错误率上升
  • 延迟增加
  • 资源使用率高

Info 告警

  • 配置变更
  • 部署完成
  • 定期报告

2. 告警设计模式

症状告警(推荐)

告警用户可见的问题:

- alert: HighErrorRate
  expr: |
    rate(http_requests_total{status_code=~"5.."}[5m]) 
    / 
    rate(http_requests_total[5m]) > 0.05
  annotations:
    summary: "用户体验受影响:错误率 {{ $value | humanizePercentage }}"

原因告警(辅助)

告警根本原因:

- alert: HighCPUUsage
  expr: rate(container_cpu_usage_seconds_total[5m]) > 0.9
  annotations:
    summary: "Pod {{ $labels.pod }} CPU 使用率过高"

3. 降噪技巧

# 1. 合理设置 for 时间,避免短暂波动
- alert: HighLatency
  expr: latency > 2
  for: 10m  # 持续 10 分钟才告警

# 2. 合理设置阈值
- alert: HighMemory
  expr: memory_usage > 0.85  # 85% 而不是 80%
  for: 5m

# 3. 使用 group_by 聚合告警
route:
  group_by: ['alertname', 'cluster']
  group_wait: 30s
  group_interval: 5m

# 4. 抑制规则:Critical 告警触发时抑制 Warning
inhibit_rules:
- source_match:
    severity: critical
  target_match:
    severity: warning
  equal: ['alertname']

指标命名规范

Prometheus 命名约定

<namespace>_<name>_<unit>_<suffix>

# Counter(累计值)
http_requests_total
http_request_errors_total

# Gauge(瞬时值)
memory_usage_bytes
cpu_usage_ratio

# Histogram(分布)
http_request_duration_seconds
http_request_size_bytes

# Summary(摘要)
rpc_duration_seconds

标签最佳实践

# ✅ 推荐
http_requests_total{
  method="GET",
  status_code="200",
  endpoint="/api/users"
}

# ❌ 不推荐
# 1. 高基数标签(会产生大量时序)
http_requests_total{user_id="user123"}

# 2. 标签值变化太快
http_requests_total{request_id="abc123"}

# 3. 在指标名称中包含标签信息
http_requests_total_200

常用 PromQL 查询

基础查询

# 即时查询
http_requests_total

# 范围查询
http_requests_total[5m]

# 速率计算(Counter)
rate(http_requests_total[5m])

# 增量计算
increase(http_requests_total[1h])

# 聚合函数
sum(http_requests_total) by (status_code)
avg(http_request_duration_seconds) by (pod)
max(memory_usage_bytes) by (namespace)

高级查询

# 错误率
sum(rate(http_requests_total{status_code=~"5.."}[5m])) 
/ 
sum(rate(http_requests_total[5m]))

# P95 延迟
histogram_quantile(0.95, 
  sum(rate(http_request_duration_seconds_bucket[5m])) by (le)
)

# 可用性(SLA)
sum(rate(http_requests_total{status_code!~"5.."}[30d]))
/
sum(rate(http_requests_total[30d]))

# Top 5 内存使用
topk(5, container_memory_usage_bytes)

# Pod 重启次数
increase(kube_pod_container_status_restarts_total[1h]) > 0

# 预测(线性回归)
predict_linear(node_filesystem_free_bytes[1h], 4 * 3600) < 0

Dashboard 设计

层级结构

Level 1: 集群总览
  ├─ 集群整体健康状态
  ├─ 节点资源使用
  └─ 关键指标汇总

Level 2: 命名空间视图
  ├─ Namespace 资源配额
  ├─ Pod 数量和状态
  └─ 服务健康状况

Level 3: 服务详情
  ├─ RED 指标
  ├─ 资源使用
  └─ 依赖服务状态

Level 4: Pod 详情
  ├─ 容器资源
  ├─ 日志和事件
  └─ 网络指标

Panel 设计

{
  "title": "Request Rate",
  "targets": [{
    "expr": "sum(rate(http_requests_total[5m])) by (pod)"
  }],
  "yaxes": [{
    "label": "req/sec",
    "format": "short",
    "decimals": 2
  }],
  "thresholds": [
    {
      "value": 100,
      "colorMode": "critical",
      "op": "gt",
      "fill": true,
      "line": true
    }
  ]
}

日志规范

结构化日志

// ✅ 推荐
logger.info('User login', {
  user_id: 'user123',
  ip: '192.168.1.1',
  duration_ms: 150,
  success: true
});

// ❌ 不推荐
console.log('User user123 logged in from 192.168.1.1 in 150ms');

日志级别

ERROR: 错误,需要处理
WARN:  警告,需要关注
INFO:  重要信息
DEBUG: 调试信息(生产环境关闭)

关键字段

{
  "timestamp": "2024-01-08T12:00:00Z",
  "level": "error",
  "message": "Database query failed",
  "service": "user-service",
  "version": "1.2.3",
  "environment": "production",
  "trace_id": "abc123",
  "span_id": "def456",
  "user_id": "user123",
  "error": {
    "type": "DatabaseError",
    "message": "Connection timeout",
    "stack": "..."
  }
}

数据保留策略

Prometheus

prometheus:
  prometheusSpec:
    # 短期:详细数据
    retention: 15d
    
    # 长期:降采样数据
    # 使用 Thanos 或 Cortex

Elasticsearch

PUT _ilm/policy/logs-policy
{
  "policy": {
    "phases": {
      "hot": {
        "actions": {
          "rollover": {
            "max_age": "1d",
            "max_size": "50gb"
          }
        }
      },
      "warm": {
        "min_age": "7d",
        "actions": {
          "shrink": {
            "number_of_shards": 1
          }
        }
      },
      "cold": {
        "min_age": "30d",
        "actions": {
          "freeze": {}
        }
      },
      "delete": {
        "min_age": "90d",
        "actions": {
          "delete": {}
        }
      }
    }
  }
}

性能优化

1. 减少时序基数

# ❌ 避免高基数标签
http_requests_total{user_id="..."}  # 百万级用户

# ✅ 使用聚合标签
http_requests_total{user_type="premium"}  # 几种类型

2. 合理设置抓取间隔

# 默认间隔
scrape_interval: 15s

# 慢变化的指标可以更长
scrape_interval: 60s

3. 使用 Recording Rules

groups:
- name: recording_rules
  interval: 30s
  rules:
  # 预计算复杂查询
  - record: job:http_requests:rate5m
    expr: sum(rate(http_requests_total[5m])) by (job)
  
  - record: job:http_errors:rate5m
    expr: sum(rate(http_requests_total{status_code=~"5.."}[5m])) by (job)

常用命令

# Prometheus
kubectl port-forward -n monitoring svc/prometheus 9090:9090

# Grafana
kubectl port-forward -n monitoring svc/grafana 3000:80

# Alertmanager
kubectl port-forward -n monitoring svc/alertmanager 9093:9093

# 查看 Prometheus 配置
curl http://localhost:9090/api/v1/status/config

# 查看目标状态
curl http://localhost:9090/api/v1/targets

# 查看告警规则
curl http://localhost:9090/api/v1/rules

# 测试 PromQL
curl -g 'http://localhost:9090/api/v1/query?query=up'

# 重载 Prometheus 配置
curl -X POST http://localhost:9090/-/reload

小结

监控最佳实践总结:

方法论: RED(服务)、USE(资源)、四个黄金信号
告警设计: 分级、降噪、症状优先
指标规范: 命名约定、标签最佳实践
PromQL: 常用查询模式和技巧
Dashboard: 层级设计、Panel 配置
日志规范: 结构化、关键字段、日志级别
数据保留: Prometheus + ILM 策略
性能优化: 降低基数、Recording Rules

至此,监控与日志章节全部完成!🎉

下一章:故障排查。