Files
ljwx-k8s/PROMETHEUS-ARCHITECTURE-ANALYSIS.md
2026-02-20 22:50:45 +08:00

10 KiB
Raw Permalink Blame History

Prometheus 双实例架构分析报告

🔍 问题根源

你的集群中确实存在两套 Prometheus 系统,但这不是设计上的需求,而是历史遗留问题。


📚 完整部署历史

阶段 1:最初部署 (41天前) - ❌ 失败

时间: 2025-11-23 操作: 通过 Helm 部署 kube-prometheus-stack 到 observability 命名空间

helm install monitoring prometheus-community/kube-prometheus-stack \
  -n observability --create-namespace

预期部署的组件:

  • ✅ Prometheus Operator (控制器)
  • ❌ Prometheus Pod (实际监控实例) - 失败
  • ❌ Grafana Pod - 失败
  • ❌ Alertmanager Pod - 失败
  • ✅ Node Exporter DaemonSet
  • ✅ Kube-State-Metrics
  • ✅ 34 个 PrometheusRule (告警规则)
  • ✅ 15 个 ServiceMonitor (服务发现)

失败原因推测:

  1. 镜像拉取失败 (最可能) - 国内网络无法访问 Docker Hub/quay.io
  2. 资源配额不足
  3. 配置错误

证据:

# Helm 显示部署成功
helm list -n observability
# STATUS: deployed

# 但实际没有 Pod
kubectl get pods -n observability
# No resources found

# CRD 存在但无实例
kubectl get prometheus -n observability
# READY=1, AVAILABLE=True (这是假的!只是 CRD 状态)

kubectl get pods -A -l app.kubernetes.io/instance=monitoring
# No resources found (真实情况)

阶段 2:应急部署 (21天前) - ✅ 成功

时间: 2025-12-13 操作: 手动部署独立的 Prometheus + Grafana 到 monitoring 命名空间

部署方式: 直接 apply YAML 文件(非 Helm)

成功部署的组件:

  • ✅ Prometheus Deployment (prometheus-cc9cc6f7d-2mm88)

    • 镜像:可能来自 harbor.eu.lingjingwanxiang.cn(国内镜像)
    • 配置:手动编辑 prometheus.yml
    • 保留时间:7天
    • NodePort:30900
  • ✅ Grafana Deployment (grafana-d794b8d5f-hbqkz)

    • 数据源:指向 http://prometheus:9090
    • Dashboard:手动导入 ConfigMaps
    • NodePort:30300

工作正常:

  • ✅ 抓取 MySQL、PostgreSQL、Redis、K8s 指标
  • ✅ Grafana 显示所有 Dashboard
  • ✅ 告警正常工作

阶段 3:增强部署 (最近几周) - ✅ 持续改进

操作: 基于 monitoring 命名空间持续添加功能

添加的组件:

  • PostgreSQL Exporter
  • MySQL Exporter
  • Redis Exporter
  • MinIO Metrics
  • Gitea Actions Exporter
  • Database Backup Dashboard
  • MySQL Performance Dashboard

问题: 这些新增的 ServiceMonitor 都部署到了 observability 命名空间,但那里没有 Prometheus 实例处理它们!

kubectl get servicemonitor -n observability
# gitea-actions-exporter, minio-metrics, monitoring-grafana...
# 这些 ServiceMonitor 都在等一个不存在的 Prometheus Operator

🏗️ 当前架构状态

observability 命名空间 (僵尸配置)

├── Helm Release: monitoring (kube-prometheus-stack)
│   ├── ✅ CRDs (已创建)
│   ├── ✅ ConfigMaps (34个 Dashboard 定义)
│   ├── ✅ Secrets (Grafana admin 密码等)
│   ├── ✅ ServiceMonitors (15个)
│   ├── ✅ PrometheusRules (34个告警规则)
│   └── ❌ Pods (0个 - 从未运行成功)

状态: 配置存在,但没有实际运行的组件


monitoring 命名空间 (实际在用)

├── Prometheus Deployment (手动部署)
│   ├── ✅ Pod: prometheus-cc9cc6f7d-2mm88
│   ├── ✅ Service: prometheus:9090
│   ├── ✅ NodePort: 30900
│   └── ✅ 手动配置的 prometheus.yml
│
├── Grafana Deployment (手动部署)
│   ├── ✅ Pod: grafana-d794b8d5f-hbqkz
│   ├── ✅ Service: grafana:3000
│   ├── ✅ NodePort: 30300
│   └── ✅ 手动导入的 6 个 Dashboard
│
└── 各种 Exporters
    ├── ✅ PostgreSQL Exporter
    ├── ✅ MySQL Exporter
    ├── ✅ Redis Exporter
    └── ✅ 通过 static_configs 配置抓取

状态: 正常工作,但配置方式原始


❓ 为什么需要 Prometheus Operator?

当前方式的痛点(Deployment + 手动配置)

  1. 每次添加新服务都要手动编辑 ConfigMap

    # 添加新服务时
    kubectl edit configmap prometheus-config -n monitoring
    # 手动添加 scrape_configs
    # 手动重启 Prometheus
    
  2. 告警规则管理混乱

    • 需要手动创建多个 ConfigMap
    • 修改后需要手动 reload
    • 不支持版本控制
  3. 无法使用 ServiceMonitor 自动发现

    • 新部署的服务(如 MinIO、Gitea Exporter)创建了 ServiceMonitor
    • 但 monitoring 命名空间的 Prometheus 不支持 ServiceMonitor
    • 导致这些服务的指标无法被抓取
  4. 扩展性差

    • 无法动态添加 Prometheus 实例
    • 无法实现 Prometheus 联邦集群
    • 无法使用 Thanos 长期存储

Prometheus Operator 的优势

  1. 声明式配置 - 一切皆 CRD

    # 添加新服务只需创建 ServiceMonitor
    apiVersion: monitoring.coreos.com/v1
    kind: ServiceMonitor
    metadata:
      name: my-app
    spec:
      selector:
        matchLabels:
          app: my-app
      endpoints:
        - port: metrics
    
  2. 自动服务发现

    • Prometheus Operator 自动监听 ServiceMonitor 创建事件
    • 自动更新 Prometheus 配置并 reload
    • 无需手动干预
  3. 告警规则即代码

    apiVersion: monitoring.coreos.com/v1
    kind: PrometheusRule
    metadata:
      name: my-alerts
    spec:
      groups:
        - name: my-app
          rules:
            - alert: HighErrorRate
              expr: rate(errors[5m]) > 0.1
    
  4. 多租户支持

    • 可以为不同命名空间部署独立的 Prometheus 实例
    • 每个实例只抓取特定命名空间的服务
  5. GitOps 友好

    • 所有配置都是 Kubernetes 资源
    • 可以用 ArgoCD/Flux 管理
    • 支持版本控制和回滚

🎯 问题总结

为什么有两套系统?

不是因为需要两套,而是:

  1. ❌ 第一套 (observability) 部署失败了
  2. ✅ 第二套 (monitoring) 是应急临时方案
  3. ⏳ 一直没时间修复第一套或清理僵尸配置

为什么需要 Prometheus Operator?

不是"需要独立 NS 的 Prometheus Operator",而是:

  • 应该用 Prometheus Operator 替代当前的手动部署方式
  • 可以部署在任何命名空间(observability 或 monitoring 都行)
  • 核心是使用 Operator 管理方式 vs 手动 Deployment 方式

💡 推荐方案

方案 1: 修复 observability 命名空间(推荐)

优点:

  • ✅ 保留所有已配置的 ServiceMonitor 和 PrometheusRule
  • ✅ 利用 Helm 管理,方便升级
  • ✅ 15个 ServiceMonitor 立即生效

步骤:

  1. 查明为何 Pod 未创建(可能是镜像问题)
  2. 配置国内镜像仓库
  3. 重新部署 Helm release
  4. 迁移 Grafana 数据源
  5. 清理 monitoring 命名空间的旧实例

命令示例:

# 1. 配置国内镜像
helm upgrade monitoring prometheus-community/kube-prometheus-stack \
  -n observability \
  --set prometheus.prometheusSpec.image.registry=harbor.eu.lingjingwanxiang.cn \
  --set prometheus.prometheusSpec.image.repository=library/prometheus \
  --set grafana.image.registry=harbor.eu.lingjingwanxiang.cn \
  --set grafana.image.repository=library/grafana
  # ... (其他组件镜像配置)

# 2. 验证 Pod 启动
kubectl get pods -n observability

# 3. 迁移数据源
kubectl edit configmap grafana-datasources -n monitoring
# 修改 url: http://prometheus-operated.observability:9090

# 4. 清理旧实例 (7天后)
kubectl delete deployment prometheus grafana -n monitoring

方案 2: 在 monitoring 命名空间部署 Operator

优点:

  • ✅ 不改变现有命名空间
  • ✅ 平滑迁移

步骤:

  1. 在 monitoring 命名空间部署 Prometheus Operator
  2. 将 ServiceMonitor 从 observability 迁移到 monitoring
  3. 逐步替换手动 Deployment
  4. 清理 observability 命名空间

方案 3: 统一到一个命名空间 (长期方案)

最佳实践:

observability 命名空间(统一所有可观测性组件)
├── Prometheus Operator
├── Prometheus (通过 CRD 管理)
├── Grafana
├── Alertmanager
├── Loki (日志)
├── Tempo (链路追踪)
└── 所有 ServiceMonitors/PrometheusRules

清理:

  • 删除 monitoring 命名空间的 Prometheus/Grafana
  • 所有可观测性资源统一到 observability

🔧 立即行动

第一步:诊断为何 observability 的 Pod 未创建

# 1. 查看 Prometheus Operator Deployment(如果存在)
kubectl get deployment -n observability

# 2. 查看 Prometheus StatefulSet 事件
kubectl describe prometheus monitoring-kube-prometheus-prometheus -n observability

# 3. 查看是否有 StatefulSet
kubectl get statefulset -n observability

# 4. 查看镜像配置
helm get values monitoring -n observability

第二步:修复镜像配置(如果是镜像问题)

# 创建镜像配置文件
cat > prometheus-operator-values.yaml <<EOF
global:
  imageRegistry: harbor.eu.lingjingwanxiang.cn

prometheus:
  prometheusSpec:
    image:
      registry: harbor.eu.lingjingwanxiang.cn
      repository: library/prometheus
      tag: v3.7.3

grafana:
  image:
    registry: harbor.eu.lingjingwanxiang.cn
    repository: library/grafana

alertmanager:
  alertmanagerSpec:
    image:
      registry: harbor.eu.lingjingwanxiang.cn
      repository: library/alertmanager
EOF

# 升级 Helm release
helm upgrade monitoring prometheus-community/kube-prometheus-stack \
  -n observability \
  -f prometheus-operator-values.yaml

第三步:验证修复

# 检查 Pod 是否创建
kubectl get pods -n observability -w

# 检查 Prometheus 服务
kubectl get svc -n observability | grep prometheus

# 测试访问
kubectl port-forward -n observability svc/prometheus-operated 9090:9090

📝 总结

当前状态:

  • ❌ observability 命名空间:配置完整但无运行实例(僵尸)
  • ✅ monitoring 命名空间:简陋但能用的手动部署(临时方案)

根本问题:

  • 不是"为什么需要两套",而是"第一套没部署成功"

解决方向:

  1. 修复 observability 的 Prometheus Operator 部署
  2. 迁移 Grafana 数据源
  3. 清理 monitoring 命名空间的临时方案
  4. 统一使用 Prometheus Operator 管理

预期收益:

  • ✅ 自动服务发现(ServiceMonitor)
  • ✅ 声明式告警规则(PrometheusRule)
  • ✅ GitOps 友好
  • ✅ 便于扩展和维护

需要我帮你执行诊断和修复吗?