10 KiB
10 KiB
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 (服务发现)
失败原因推测:
- 镜像拉取失败 (最可能) - 国内网络无法访问 Docker Hub/quay.io
- 资源配额不足
- 配置错误
证据:
# 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 + 手动配置)
-
每次添加新服务都要手动编辑 ConfigMap
# 添加新服务时 kubectl edit configmap prometheus-config -n monitoring # 手动添加 scrape_configs # 手动重启 Prometheus -
告警规则管理混乱
- 需要手动创建多个 ConfigMap
- 修改后需要手动 reload
- 不支持版本控制
-
无法使用 ServiceMonitor 自动发现
- 新部署的服务(如 MinIO、Gitea Exporter)创建了 ServiceMonitor
- 但 monitoring 命名空间的 Prometheus 不支持 ServiceMonitor
- 导致这些服务的指标无法被抓取
-
扩展性差
- 无法动态添加 Prometheus 实例
- 无法实现 Prometheus 联邦集群
- 无法使用 Thanos 长期存储
Prometheus Operator 的优势
-
声明式配置 - 一切皆 CRD
# 添加新服务只需创建 ServiceMonitor apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: my-app spec: selector: matchLabels: app: my-app endpoints: - port: metrics -
自动服务发现
- Prometheus Operator 自动监听 ServiceMonitor 创建事件
- 自动更新 Prometheus 配置并 reload
- 无需手动干预
-
告警规则即代码
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 -
多租户支持
- 可以为不同命名空间部署独立的 Prometheus 实例
- 每个实例只抓取特定命名空间的服务
-
GitOps 友好
- 所有配置都是 Kubernetes 资源
- 可以用 ArgoCD/Flux 管理
- 支持版本控制和回滚
🎯 问题总结
为什么有两套系统?
不是因为需要两套,而是:
- ❌ 第一套 (observability) 部署失败了
- ✅ 第二套 (monitoring) 是应急临时方案
- ⏳ 一直没时间修复第一套或清理僵尸配置
为什么需要 Prometheus Operator?
不是"需要独立 NS 的 Prometheus Operator",而是:
- 应该用 Prometheus Operator 替代当前的手动部署方式
- 可以部署在任何命名空间(observability 或 monitoring 都行)
- 核心是使用 Operator 管理方式 vs 手动 Deployment 方式
💡 推荐方案
方案 1: 修复 observability 命名空间(推荐)
优点:
- ✅ 保留所有已配置的 ServiceMonitor 和 PrometheusRule
- ✅ 利用 Helm 管理,方便升级
- ✅ 15个 ServiceMonitor 立即生效
步骤:
- 查明为何 Pod 未创建(可能是镜像问题)
- 配置国内镜像仓库
- 重新部署 Helm release
- 迁移 Grafana 数据源
- 清理 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
优点:
- ✅ 不改变现有命名空间
- ✅ 平滑迁移
步骤:
- 在 monitoring 命名空间部署 Prometheus Operator
- 将 ServiceMonitor 从 observability 迁移到 monitoring
- 逐步替换手动 Deployment
- 清理 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 命名空间:简陋但能用的手动部署(临时方案)
根本问题:
- 不是"为什么需要两套",而是"第一套没部署成功"
解决方向:
- 修复 observability 的 Prometheus Operator 部署
- 迁移 Grafana 数据源
- 清理 monitoring 命名空间的临时方案
- 统一使用 Prometheus Operator 管理
预期收益:
- ✅ 自动服务发现(ServiceMonitor)
- ✅ 声明式告警规则(PrometheusRule)
- ✅ GitOps 友好
- ✅ 便于扩展和维护
需要我帮你执行诊断和修复吗?