Files
ljwx-k8s/GRAFANA-PROMETHEUS-MIGRATION-GUIDE.md
2026-02-20 22:50:45 +08:00

10 KiB
Raw Permalink Blame History

Grafana Dashboard 与 Prometheus 切换影响分析

📊 当前 Grafana Dashboard 清单

已部署的 Dashboard ConfigMaps

  1. grafana-dashboard-cluster-monitoring - 集群监控仪表板
  2. grafana-dashboard-cluster-monitoring-updated - 集群监控(更新版)
  3. grafana-dashboard-corrected - 修正版仪表板
  4. grafana-dashboard-database-backups - 数据库备份监控
  5. grafana-dashboard-mysql - MySQL 性能监控
  6. grafana-dashboards - 默认仪表板集合

Dashboard 数据源配置特点

所有 Dashboard 的数据源引用方式:

  • 使用 "datasource": "Prometheus" (名称引用)
  • 或使用 "datasource": {"type": "prometheus", "uid": "prometheus"} (UID引用)

关键发现: ✅ Dashboard 使用的是数据源名称/UID,而不是硬编码的 URL ✅ 这意味着只要数据源名称保持为 "Prometheus",切换底层实例对 Dashboard 无影响


🔍 当前架构状态

Prometheus 实例现状

1. 当前使用中:Deployment 管理的 Prometheus (monitoring 命名空间)

  • Pod: prometheus-cc9cc6f7d-2mm88
  • Service: prometheus:9090 (ClusterIP: 192.168.194.201)
  • NodePort: 30900
  • 配置:
    • 保留时间: 7天
    • WAL 压缩: 启用
    • 配置文件: /etc/prometheus/prometheus.yml
  • Grafana 连接: ✅ http://prometheus:9090
  • 已抓取的指标:
    • ✅ MySQL (mysqld-exporter)
    • ✅ PostgreSQL
    • ✅ Redis
    • ✅ Grafana
    • ✅ Kube-state-metrics
    • ✅ Kubernetes API/Nodes/Pods
    • ✅ 业务服务

2. 已定义但未运行:Prometheus Operator (observability 命名空间)

  • CRD 状态: Available, Reconciled (41天前创建)
  • 版本: v3.7.3
  • 问题: ⚠️ CRD 存在但 没有实际的 Pod/Service 资源
  • ServiceMonitors: 存在 15+ 个 ServiceMonitor,但无 Prometheus 实例处理

结论: Prometheus Operator 的 CRD 是"僵尸配置",需要重新部署实际实例


📈 切换影响评估

✅ 无影响项

  1. Dashboard 展示 - 100% 兼容

    • Dashboard 使用数据源名称引用,切换后自动生效
    • 无需修改任何 Dashboard JSON
  2. 告警规则 (如果 PrometheusRule CRD 已存在)

    • Prometheus Operator 原生支持 PrometheusRule
    • 比手动编辑配置文件更方便
  3. 数据连续性 (如果同时运行两个实例)

    • 可以先启动新实例并行抓取
    • 确认稳定后再切换 Grafana 数据源

⚠️ 需要处理的问题

问题 1: Prometheus Operator 实例需要重新部署

当前问题:

kubectl get prometheus -n observability
# 显示: READY=1, AVAILABLE=True
# 但实际: 无 Pod, 无 Service

原因:可能是之前部署失败或手动删除了资源

解决方案:

# 删除旧 CRD
kubectl delete prometheus monitoring-kube-prometheus-prometheus -n observability

# 重新部署 (使用 Helm 或 Operator)
helm install prometheus-operator prometheus-community/kube-prometheus-stack \
  -n observability --create-namespace \
  --set prometheus.prometheusSpec.retention=7d

问题 2: 历史数据迁移

迁移需求 难度 推荐方案
不需要历史数据 ⭐ 直接切换,7天后旧实例数据过期
需要保留历史 ⭐⭐⭐ 使用 Thanos/Cortex 联邦查询
需要完整迁移 ⭐⭐⭐⭐⭐ 停机迁移 TSDB 数据目录

推荐: 不迁移历史数据,两实例并行运行7天

问题 3: 抓取配置迁移

当前配置方式 (Deployment):

# prometheus-config ConfigMap
scrape_configs:
  - job_name: 'mysql'
    static_configs:
      - targets: ['mysql-exporter:9104']

新配置方式 (Operator):

# ServiceMonitor CRD
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: mysql-exporter
spec:
  selector:
    matchLabels:
      app: mysql-exporter
  endpoints:
    - port: metrics

需要迁移的抓取目标:

  • MySQL Exporter
  • PostgreSQL Exporter
  • Redis Exporter
  • MinIO
  • Gitea Actions Exporter
  • 业务服务 exporters

好消息: observability 命名空间已存在这些 ServiceMonitor!

kubectl get servicemonitor -n observability
# gitea-actions-exporter, minio-metrics, monitoring-grafana...

🚀 迁移方案

方案 A: 推荐方案 - 平滑并行迁移 (零停机)

优点:

  • ✅ 零停机
  • ✅ 可以验证新实例正常后再切换
  • ✅ 保留7天回滚窗口
  • ✅ 历史数据逐步过期

步骤:

  1. 重新部署 Prometheus Operator 实例

    # 清理旧 CRD
    kubectl delete prometheus monitoring-kube-prometheus-prometheus -n observability
    
    # 部署新实例 (确保有 Service)
    helm upgrade --install prometheus-operator prometheus-community/kube-prometheus-stack \
      -n observability --create-namespace \
      --set prometheus.prometheusSpec.retention=7d \
      --set prometheus.prometheusSpec.walCompression=true \
      --set prometheus.service.type=NodePort \
      --set prometheus.service.nodePort=30901
    
  2. 迁移 ServiceMonitors 到 observability 命名空间

    # 检查已存在的 ServiceMonitors
    kubectl get servicemonitor -n observability
    
    # 如有缺失,从当前配置转换为 ServiceMonitor
    # 示例:MySQL
    cat <<EOF | kubectl apply -f -
    apiVersion: monitoring.coreos.com/v1
    kind: ServiceMonitor
    metadata:
      name: mysql-exporter
      namespace: observability
    spec:
      selector:
        matchLabels:
          app: mysql-exporter
      namespaceSelector:
        matchNames:
          - data
      endpoints:
        - port: metrics
          interval: 30s
    EOF
    
  3. 等待新 Prometheus 抓取数据(10-15分钟)

    # 访问新实例验证
    kubectl port-forward -n observability svc/prometheus-operator-kube-prometheus-prometheus 9091:9090
    # 浏览器: http://localhost:9091/targets
    
  4. 在 Grafana 添加第二个数据源(测试)

    # 修改 grafana-datasources ConfigMap
    apiVersion: 1
    datasources:
      - name: Prometheus
        type: prometheus
        url: http://prometheus.monitoring:9090  # 旧实例
        isDefault: true
    
      - name: Prometheus-Operator
        type: prometheus
        url: http://prometheus-operator-kube-prometheus-prometheus.observability:9090
        isDefault: false
    
  5. 测试 Dashboard 使用新数据源

    • 打开任意 Dashboard
    • 手动切换数据源到 "Prometheus-Operator"
    • 验证所有面板正常显示
  6. 切换默认数据源

    # 修改 grafana-datasources ConfigMap
    - name: Prometheus
      url: http://prometheus-operator-kube-prometheus-prometheus.observability:9090
      isDefault: true
    
    # 重启 Grafana
    kubectl rollout restart deployment/grafana -n monitoring
    
  7. 保留旧实例7天后清理

    # 7天后删除旧实例
    kubectl delete deployment prometheus -n monitoring
    kubectl delete svc prometheus prometheus-nodeport -n monitoring
    

时间线:

  • Day 0: 部署新实例 (30分钟)
  • Day 0-1: 并行运行,验证数据 (1天)
  • Day 1: 切换 Grafana 数据源 (5分钟)
  • Day 1-7: 监控新实例,确认稳定 (6天)
  • Day 7: 清理旧实例 (5分钟)

方案 B: 快速切换 (有风险)

仅当以下条件满足时使用:

  • ❌ 不需要历史数据
  • ❌ 可以接受短暂监控盲区
  • ❌ 紧急需要 ServiceMonitor 功能

步骤:

  1. 部署 Prometheus Operator
  2. 等待5分钟抓取数据
  3. 立即切换 Grafana 数据源
  4. 删除旧 Prometheus

风险:

  • ⚠️ 历史数据立即丢失
  • ⚠️ 告警规则可能短暂失效
  • ⚠️ Dashboard 可能显示数据断层

🎯 推荐行动

立即执行(今天)

  1. 检查 Prometheus Operator 状态

    kubectl get prometheus -n observability -o yaml
    # 确认为何有 CRD 但无 Pod
    
  2. 验证现有 ServiceMonitors

    kubectl get servicemonitor -n observability
    # 确认是否覆盖所有需要的服务
    

本周执行

  1. 重新部署 Prometheus Operator 实例

    • 使用方案 A 的步骤 1
    • 验证 Pod 和 Service 正常创建
  2. 迁移 ServiceMonitors

    • 对比当前 Prometheus 配置和 ServiceMonitors
    • 补齐缺失的 ServiceMonitors
  3. 并行验证

    • 同时运行两个 Prometheus 实例
    • 在 Grafana 中添加第二个数据源
    • 逐个验证 Dashboard

下周执行

  1. 切换生产环境

    • 修改 Grafana 默认数据源
    • 重启 Grafana
    • 验证所有 Dashboard 和告警
  2. 监控稳定性

    • 观察新实例性能
    • 检查是否有遗漏的抓取目标
  3. 清理旧资源

    • 7天后删除旧 Prometheus Deployment

📋 迁移检查清单

部署前

  • 备份当前 Prometheus 配置
    kubectl get configmap prometheus-config -n monitoring -o yaml > prometheus-config-backup.yaml
    
  • 记录当前所有抓取目标
    curl http://localhost:30900/api/v1/targets | jq > targets-backup.json
    
  • 确认磁盘空间 (两个实例需要 2x 存储)

部署中

  • Prometheus Operator Pod 状态: Running
  • Service 可以访问 (curl 测试)
  • ServiceMonitors 被正确识别
  • 所有目标状态: UP

部署后

  • Grafana 可以查询新 Prometheus
  • 所有 Dashboard 正常显示
  • 告警规则正常触发
  • 性能无明显下降

🔧 故障回滚

如果新实例有问题,立即回滚:

# 1. 修改 Grafana 数据源回到旧实例
kubectl edit configmap grafana-datasources -n monitoring
# 修改 url: http://prometheus:9090

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

# 3. 等待问题修复
# 旧实例继续运行,无数据丢失

💡 长期优化建议

  1. 统一使用 Prometheus Operator

    • 所有服务使用 ServiceMonitor
    • 告警规则使用 PrometheusRule CRD
    • 便于版本控制和 GitOps
  2. 添加长期存储

    • 部署 Thanos Sidecar
    • 存储到 MinIO/S3
    • 保留数月/年级别历史数据
  3. 高可用部署

    • Prometheus 副本数: 2
    • 使用 Thanos Query 前端
    • 避免单点故障

📞 需要支持?

如果在迁移过程中遇到问题,检查:

  1. Prometheus Operator 日志

    kubectl logs -n observability -l app.kubernetes.io/name=prometheus-operator
    
  2. Prometheus Pod 日志

    kubectl logs -n observability prometheus-<pod-name>
    
  3. ServiceMonitor 是否被识别

    kubectl get prometheus -n observability -o yaml | grep -A 20 serviceMonitorSelector