监控最佳实践
监控最佳实践
本节总结 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 提出的监控指标:
- 延迟(Latency): 请求响应时间
- 流量(Traffic): 请求量
- 错误(Errors): 失败请求率
- 饱和度(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
至此,监控与日志章节全部完成!🎉
下一章:故障排查。