Files
ljwx-k8s/OBSERVABILITY-ENHANCEMENT-GUIDE.md
2026-02-20 22:50:45 +08:00

13 KiB
Raw Permalink Blame History

K8s 可观测性增强完整指南

基于现有 LGTM Stack(Loki + Grafana + Tempo + Metrics),完成 Postgres/Redis 监控、业务应用三件套、以及 Loki↔Tempo 链路追踪联动。

📋 目标

本指南将帮助你完成以下 P0 任务:

  • ✅ T1: 新增 Prometheus scrape configs(Postgres/Redis/K3s)
  • ✅ T2: 部署 postgres-exporter 和 redis-exporter
  • ✅ T3: 导入 Grafana 运营级 Dashboard + 关键告警
  • ✅ T4: 配置 Grafana Loki ↔ Tempo 双向跳转
  • ✅ T5: 业务应用 Metrics 暴露和抓取
  • ✅ T6: 业务应用 Trace 包含 DB/Redis spans
  • ✅ T7: 启用 Postgres pg_stat_statements 慢 SQL 面板

🗂️ 目录结构

k8s/
├── infra/observability/              # 基础设施监控组件
│   ├── postgres-exporter.yaml        # Postgres Exporter 部署
│   ├── postgres-secret-example.yaml  # Postgres 连接配置示例
│   ├── redis-exporter.yaml           # Redis Exporter 部署
│   └── redis-secret-example.yaml     # Redis 连接配置示例
│
├── monitoring/
│   ├── prometheus/
│   │   ├── prometheus-configmap-enhanced.yaml  # 增强的 Prometheus 配置
│   │   └── rules/                              # 告警规则
│   │       ├── postgres-alerts.yml             # Postgres 告警
│   │       ├── redis-alerts.yml                # Redis 告警
│   │       └── k3s-operational-alerts.yml      # K3s 运营告警
│   │
│   └── grafana/
│       ├── datasources-loki-tempo-enhanced.yaml  # 增强的数据源配置
│       └── dashboards/
│           ├── README.md                         # Dashboard 导入指南
│           └── import-dashboards.sh              # 一键导入脚本
│
├── docs/observability/               # 文档
│   ├── business-instrumentation-spring-boot.md  # Spring Boot 集成
│   ├── business-instrumentation-python.md       # Python 集成
│   └── pg-stat-statements-setup.md              # pg_stat_statements 启用
│
└── verify-observability-enhanced.sh  # 验收脚本

🚀 快速开始(5 分钟部署)

前置条件

确保你已经部署了:

  • ✅ Prometheus (monitoring namespace)
  • ✅ Grafana (monitoring namespace)
  • ✅ Loki (logging namespace)
  • ✅ Tempo (tracing namespace)

一键部署

cd /Users/brunogao/work/codes/tools/macos/k8s

# 1. 部署 Postgres Exporter(如果有 Postgres)
# 先修改连接串
vi infra/observability/postgres-secret-example.yaml
kubectl apply -f infra/observability/postgres-secret-example.yaml
kubectl apply -f infra/observability/postgres-exporter.yaml

# 2. 部署 Redis Exporter(如果有 Redis)
# 先修改连接串
vi infra/observability/redis-secret-example.yaml
kubectl apply -f infra/observability/redis-secret-example.yaml
kubectl apply -f infra/observability/redis-exporter.yaml

# 3. 更新 Prometheus 配置
kubectl apply -f monitoring/prometheus/prometheus-configmap-enhanced.yaml

# 4. 部署告警规则(创建 ConfigMap)
kubectl create configmap prometheus-postgres-rules \
  --from-file=monitoring/prometheus/rules/postgres-alerts.yml \
  -n monitoring --dry-run=client -o yaml | kubectl apply -f -

kubectl create configmap prometheus-redis-rules \
  --from-file=monitoring/prometheus/rules/redis-alerts.yml \
  -n monitoring --dry-run=client -o yaml | kubectl apply -f -

kubectl create configmap prometheus-k3s-rules \
  --from-file=monitoring/prometheus/rules/k3s-operational-alerts.yml \
  -n monitoring --dry-run=client -o yaml | kubectl apply -f -

# 5. 重启 Prometheus(加载新配置和规则)
kubectl rollout restart deployment/prometheus -n monitoring

# 6. 更新 Grafana 数据源
kubectl apply -f monitoring/grafana/datasources-loki-tempo-enhanced.yaml
kubectl rollout restart deployment/grafana -n monitoring

# 7. 导入 Grafana Dashboards
cd monitoring/grafana/dashboards
./import-dashboards.sh

# 8. 验收所有组件
cd /Users/brunogao/work/codes/tools/macos/k8s
./verify-observability-enhanced.sh

📊 验收步骤

1. 验证 Exporter 运行

# 检查 Pod 状态
kubectl get pods -n monitoring | grep exporter

# 应该看到:
# postgres-exporter-xxx   1/1     Running
# redis-exporter-xxx      1/1     Running

# 检查 Metrics
kubectl port-forward -n monitoring svc/postgres-exporter 9187:9187 &
curl http://localhost:9187/metrics | grep pg_up

kubectl port-forward -n monitoring svc/redis-exporter 9121:9121 &
curl http://localhost:9121/metrics | grep redis_up

2. 验证 Prometheus Targets

# 端口转发到 Prometheus
kubectl port-forward -n monitoring svc/prometheus 9090:9090

# 浏览器打开: http://localhost:9090/targets
# 搜索:postgres-exporter、redis-exporter
# 状态应为:UP (1/1 up)

3. 验证 Grafana Dashboards

# 端口转发到 Grafana
kubectl port-forward -n monitoring svc/grafana 3000:3000

# 浏览器打开: http://localhost:3000
# 用户名: admin / 密码: admin

# 检查 Dashboard:
# - PostgreSQL Database (ID: 9628)
# - Redis (ID: 11835)
# - Kubernetes Cluster Monitoring (ID: 15760)

4. 验证 Loki → Tempo 跳转

# 在 Grafana Explore 中:
# 1. 选择数据源: Loki
# 2. 查询: {namespace="default"} | json | trace_id != ""
# 3. 点击日志中的 "View Trace" 链接
# 4. 应该跳转到 Tempo 并显示对应的 trace

5. 验证 Tempo → Loki 跳转

# 在 Grafana Explore 中:
# 1. 选择数据源: Tempo
# 2. 查询任意 trace
# 3. 点击 span 上的 "Logs for this span" 按钮
# 4. 应该跳转到 Loki 并显示相关日志

6. 验证告警规则

# 在 Prometheus 中检查告警规则
# 浏览器打开: http://localhost:9090/alerts

# 应该能看到:
# - postgres-alerts (Postgres 连接数、慢查询、锁等待等)
# - redis-alerts (Redis 内存、缓存命中、键淘汰等)
# - k3s-operational-alerts (Pod 重启、OOM、磁盘等)

🔧 业务应用集成

Spring Boot 应用

参考文档:docs/observability/business-instrumentation-spring-boot.md

核心步骤:

  1. 添加依赖(Micrometer + OpenTelemetry)
  2. 配置 application.yml(暴露 /actuator/prometheus)
  3. 配置 Logback(日志包含 trace_id)
  4. Deployment 附加 OpenTelemetry Java Agent
  5. 验证 metrics、traces、logs

Python 应用

参考文档:docs/observability/business-instrumentation-python.md

核心步骤:

  1. 安装依赖(prometheus-client + opentelemetry)
  2. 配置 JSON 日志(包含 trace_id)
  3. 初始化 OpenTelemetry(OTLP Exporter)
  4. 自动 instrumentation(Flask/FastAPI + psycopg2 + redis)
  5. 验证 metrics、traces、logs

🗄️ 启用 pg_stat_statements

参考文档:docs/observability/pg-stat-statements-setup.md

核心步骤:

  1. 修改 postgresql.conf(shared_preload_libraries = 'pg_stat_statements')
  2. 重启 PostgreSQL
  3. 创建扩展(CREATE EXTENSION pg_stat_statements)
  4. 配置监控用户权限(GRANT pg_monitor TO exporter)
  5. 更新 postgres-exporter Secret
  6. 验证 Grafana Dashboard 中的慢查询面板

📈 关键指标和查询

Postgres

# 连接数占比
(pg_stat_database_numbackends / on(instance) pg_settings_max_connections) * 100

# 缓存命中率
(pg_stat_database_blks_hit / (pg_stat_database_blks_hit + pg_stat_database_blks_read)) * 100

# Top 10 慢查询
topk(10, pg_stat_statements_mean_exec_time)

# 主从复制延迟
pg_replication_lag_bytes

Redis

# 内存使用率
(redis_memory_used_bytes / redis_memory_max_bytes) * 100

# 缓存命中率
(redis_keyspace_hits_total / (redis_keyspace_hits_total + redis_keyspace_misses_total)) * 100

# 键淘汰速率
rate(redis_evicted_keys_total[5m])

# 连接数
redis_connected_clients

K3s

# Pod 重启统计
rate(kube_pod_container_status_restarts_total[15m]) > 0

# Node CPU 使用率
100 - (avg by (instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)

# PVC 使用率
(kubelet_volume_stats_used_bytes / kubelet_volume_stats_capacity_bytes) * 100

🚨 告警规则说明

Postgres 告警

  • Critical: 连接数 > 90%、复制中断、慢查询 > 10 分钟
  • Warning: 连接数 > 80%、锁等待、缓存命中率 < 90%、表膨胀

Redis 告警

  • Critical: 内存 > 90%、连接被拒绝、复制中断、缓存命中率 < 50%
  • Warning: 内存 > 80%、键淘汰、慢查询、内存碎片

K3s 告警

  • Critical: Pod CrashLoopBackOff、Node NotReady、磁盘 < 10%
  • Warning: Pod OOMKilled、磁盘 < 20%、HPA 达到上限

🔍 故障排查

Exporter 无数据

# 1. 检查 Pod 日志
kubectl logs -n monitoring deployment/postgres-exporter
kubectl logs -n monitoring deployment/redis-exporter

# 2. 检查 Secret 配置
kubectl get secret postgres-exporter-secret -n monitoring -o yaml

# 3. 手动测试连接
kubectl run -it --rm debug --image=postgres:15 --restart=Never -- \
  psql -h postgres.infra.svc.cluster.local -U postgres -c "SELECT 1"

kubectl run -it --rm debug --image=redis:7 --restart=Never -- \
  redis-cli -h redis.infra.svc.cluster.local ping

Prometheus 抓取失败

# 检查 Service Annotations
kubectl get svc -n monitoring postgres-exporter -o yaml | grep prometheus.io

# 检查 Prometheus ConfigMap
kubectl get cm prometheus-config -n monitoring -o yaml | grep postgres-exporter

# 重启 Prometheus
kubectl rollout restart deployment/prometheus -n monitoring

Loki ↔ Tempo 跳转失败

# 1. 检查日志是否包含 trace_id
kubectl logs -n default <your-pod> | grep trace_id

# 2. 检查 Grafana datasource 配置
kubectl get cm grafana-datasources -n monitoring -o yaml

# 3. 重启 Grafana
kubectl rollout restart deployment/grafana -n monitoring

# 4. 在 Grafana UI 中测试数据源连接
# Configuration → Data Sources → Loki/Tempo → Save & Test

📚 参考资源

官方文档

Exporter

Dashboards

🎯 最佳实践

1. 监控数据保留

  • Prometheus: 15 天(通过 --storage.tsdb.retention.time=15d)
  • Loki: 30 天
  • Tempo: 7 天(traces)

2. 采样率

  • 开发环境: 100%(便于调试)
  • 生产环境: 10-20%(降低成本)

3. 告警降噪

  • 设置合理的 for 时长(避免瞬时抖动)
  • 使用 severity: warning/critical 分级
  • 配置 Alertmanager 分组和抑制规则

4. 安全

  • Exporter 使用专用只读账号
  • 定期轮换密码
  • 限制 Grafana 公网访问
  • 启用 RBAC 控制

❓ 常见问题

Q: 为什么选择这些 Dashboard?

A: 这些都是社区广泛使用、维护活跃的 Dashboard,覆盖了运营所需的核心指标,可以直接使用或作为模板定制。

Q: 如何降低监控成本?

A:

  1. 调整 Prometheus scrape_interval(默认 15s 可以改为 30s 或 60s)
  2. 降低 trace 采样率(生产环境 10%)
  3. 减少 metrics 高基数标签
  4. 设置合理的数据保留期

Q: 业务应用必须用 OpenTelemetry 吗?

A: 不是必须,但强烈推荐:

  • Metrics: 可以用任何 Prometheus 兼容的 exporter(如 Spring Boot Actuator)
  • Trace: OpenTelemetry 是标准,自动 instrumentation 非常方便
  • Logs: 只要日志包含 trace_id 字段即可

Q: 如何添加自定义告警?

A: 在 monitoring/prometheus/rules/ 下创建新的 .yml 文件,参考现有规则格式,然后:

kubectl create configmap prometheus-custom-rules \
  --from-file=monitoring/prometheus/rules/custom-alerts.yml \
  -n monitoring
kubectl rollout restart deployment/prometheus -n monitoring

🤝 贡献

如果你发现问题或有改进建议,请:

  1. 更新对应的配置文件
  2. 测试验证
  3. 更新文档
  4. 提交 PR

📄 License

本配置基于开源社区最佳实践,供内部使用。