Prometheus 联邦集群架构部署与运维实战
一、背景与概述
1.1 为什么需要联邦集群
随着监控规模扩大,单实例 Prometheus 面临以下挑战:
- 数据量爆炸:百万级时间序列导致内存和存储压力
- 查询性能下降:PromQL 查询延迟增加
- 单点故障风险:单实例故障导致监控盲区
- 多地域部署:跨地域网络延迟影响采集效率
Prometheus 联邦集群(Federation)通过分层架构解决上述问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| ┌─────────────────────────────────────────────────────────┐ │ Global Prometheus │ │ (联邦层 - 聚合全局指标) │ └─────────────────────────────────────────────────────────┘ │ ┌─────────────────┼─────────────────┐ ▼ ▼ ▼ ┌───────────────┐ ┌───────────────┐ ┌───────────────┐ │ Cluster A │ │ Cluster B │ │ Cluster C │ │ Prometheus │ │ Prometheus │ │ Prometheus │ │ (采集层) │ │ (采集层) │ │ (采集层) │ └───────────────┘ └───────────────┘ └───────────────┘ │ │ │ ┌───┴───┐ ┌───┴───┐ ┌───┴───┐ ▼ ▼ ▼ ▼ ▼ ▼ Node Pod Node Pod Node Pod
|
1.2 联邦架构类型
| 类型 |
适用场景 |
特点 |
| 层级联邦 |
多集群/多地域 |
下层采集,上层聚合 |
| 去中心化联邦 |
对等集群 |
各集群独立,互相备份 |
| Thanos/Cortex |
超大规模 |
全局视图 + 长期存储 |
二、环境规划
2.1 架构设计
本次部署采用三层架构:
1
| 采集层(多个) → 聚合层(1-2 个) → 展示层(Grafana)
|
规模规划:
| 层级 |
实例数 |
配置 |
职责 |
| 采集层 |
3-5 |
4C8G |
采集原始指标,保留 7 天 |
| 聚合层 |
2 |
8C16G |
联邦聚合,保留 30 天 |
| 存储层 |
可选 |
- |
Thanos/S3 长期存储 |
2.2 网络规划
| 组件 |
端口 |
访问范围 |
| Prometheus |
9090 |
内网 |
| Alertmanager |
9093 |
内网 |
| Grafana |
3000 |
内网/外网 |
| Node Exporter |
9100 |
内网 |
三、采集层 Prometheus 部署
3.1 Helm Chart 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
| replicaCount: 1
prometheus: prometheusSpec: retention: 7d resources: requests: memory: 4Gi cpu: 2 limits: memory: 8Gi cpu: 4 storageSpec: volumeClaimTemplate: spec: storageClassName: local-storage accessModes: ["ReadWriteOnce"] resources: requests: storage: 100Gi serviceMonitorSelectorNilUsesHelmValues: false podMonitorSelectorNilUsesHelmValues: false ruleSelectorNilUsesHelmValues: false additionalScrapeConfigs: - job_name: 'federate' scrape_interval: 15s honor_labels: true metrics_path: '/federate' params: 'match[]': - '{job="kubernetes-pods"}' - '{__name__=~"job:.*"}' static_configs: - targets: - 'prometheus-aggregator:9090'
alertmanager: enabled: true config: global: smtp_smarthost: 'smtp.163.com:465' smtp_from: 'weijiantu@163.com' route: receiver: 'email' receivers: - name: 'email' email_configs: - to: 'tuwj@pcl.ac.cn'
grafana: enabled: false
serverFiles: prometheus.yml: scrape_configs: - job_name: 'kubernetes-pods' kubernetes_sd_configs: - role: pod relabel_configs: - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape] action: keep regex: true - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path] action: replace target_label: __metrics_path__ regex: (.+) - source_labels: [__address__] action: replace target_label: __address__ regex: (.+?)(\:\d+)? replacement: $1:9090
|
3.2 部署命令
1 2 3 4 5 6 7 8
| helm install prometheus-collector prometheus-community/kube-prometheus-stack \ --namespace monitoring \ --version 55.0.0 \ -f values-collector.yaml
kubectl get pods -n monitoring -l app.kubernetes.io/name=prometheus
|
3.3 联邦端点配置
采集层需要暴露 /federate 端点供聚合层抓取:
1 2 3 4 5 6 7
| global: external_labels: cluster: 'cluster-a' region: 'beijing'
|
四、聚合层 Prometheus 部署
4.1 Helm Chart 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102
| replicaCount: 2
prometheus: prometheusSpec: retention: 30d resources: requests: memory: 8Gi cpu: 4 limits: memory: 16Gi cpu: 8 storageSpec: volumeClaimTemplate: spec: storageClassName: nfs-storage accessModes: ["ReadWriteOnce"] resources: requests: storage: 500Gi additionalScrapeConfigs: - job_name: 'federate-collector-a' scrape_interval: 30s honor_labels: true metrics_path: '/federate' params: 'match[]': - '{__name__=~".+"}' static_configs: - targets: - 'prometheus-collector-a.monitoring.svc:9090' - job_name: 'federate-collector-b' scrape_interval: 30s honor_labels: true metrics_path: '/federate' params: 'match[]': - '{__name__=~".+"}' static_configs: - targets: - 'prometheus-collector-b.monitoring.svc:9090' - job_name: 'federate-collector-c' scrape_interval: 30s honor_labels: true metrics_path: '/federate' params: 'match[]': - '{__name__=~".+"}' static_configs: - targets: - 'prometheus-collector-c.monitoring.svc:9090'
ruleSelectorNilUsesHelmValues: false ruleNamespaceSelector: {}
alertmanager: enabled: true config: global: resolve_timeout: 5m smtp_smarthost: 'smtp.163.com:465' smtp_from: 'weijiantu@163.com' route: group_by: ['alertname', 'cluster'] group_wait: 30s group_interval: 5m repeat_interval: 4h receiver: 'email' routes: - match: severity: critical receiver: 'critical-email' receivers: - name: 'email' email_configs: - to: 'tuwj@pcl.ac.cn' - name: 'critical-email' email_configs: - to: 'tuwj@pcl.ac.cn' html: '{{ template "email.default.html" . }}'
grafana: enabled: true adminPassword: 'admin123' service: type: NodePort nodePort: 30080 datasources: datasources.yaml: apiVersion: 1 datasources: - name: 'Prometheus-Aggregator' type: prometheus url: http://prometheus-aggregator:9090 access: proxy isDefault: true
|
4.2 部署命令
1 2 3 4 5
| helm install prometheus-aggregator prometheus-community/kube-prometheus-stack \ --namespace monitoring \ --version 55.0.0 \ -f values-aggregator.yaml
|
五、联邦查询配置
5.1 全局视图配置
聚合层 Prometheus 提供全局指标视图,Grafana 只需配置一个数据源:
1 2 3 4 5 6 7 8 9 10 11 12
| apiVersion: 1 datasources: - name: 'Global-Prometheus' type: prometheus url: http://prometheus-aggregator:9090 access: proxy isDefault: true jsonData: timeInterval: "30s" queryTimeout: "2m" httpMethod: "POST"
|
5.2 跨集群查询示例
1 2 3 4 5 6 7 8
| # 查询所有集群的 CPU 使用率 sum(rate(container_cpu_usage_seconds_total{image!=""}[5m])) by (cluster, namespace, pod)
# 查询特定集群的指标 sum(rate(container_cpu_usage_seconds_total{cluster="cluster-a"}[5m])) by (namespace)
# 查询跨集群聚合 sum(rate(http_requests_total{job="api-server"}[5m])) by (cluster, status_code)
|
5.3 标签管理
使用 external_labels 区分数据来源:
1 2 3 4 5 6 7 8
| global: external_labels: cluster: 'cluster-a' region: 'beijing' environment: 'production'
|
六、高可用配置
6.1 Prometheus 高可用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| prometheusSpec: replicas: 2 shards: 2 affinity: podAntiAffinity: requiredDuringSchedulingIgnoredDuringExecution: - labelSelector: matchLabels: app.kubernetes.io/name: prometheus topologyKey: kubernetes.io/hostname
|
6.2 Alertmanager 集群
1 2 3 4 5 6 7 8 9 10 11 12 13
| alertmanager: replicaCount: 3 config: global: cluster_advertise_address: true alertmanagerSpec: cluster: peers: - alertmanager-0.alertmanager-operated:9094 - alertmanager-1.alertmanager-operated:9094 - alertmanager-2.alertmanager-operated:9094
|
6.3 数据冗余
1 2 3 4 5 6 7
| prometheusSpec: remoteWrite: - url: "http://thanos-receive:19291/api/v1/receive" queueConfig: capacity: 10000 maxSamplesPerSend: 5000
|
七、性能优化
7.1 采集优化
1 2 3 4 5 6 7 8 9 10 11 12
| prometheusSpec: scrapeTimeout: 10s scrapeInterval: 30s sampleLimit: 10000 targetLimit: 5000
|
7.2 查询优化
1 2 3 4 5 6 7 8 9 10
| prometheusSpec: query: timeout: "2m" maxConcurrency: 20 additionalArgs: - name: log.level value: info
|
7.3 存储优化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| prometheusSpec: additionalArgs: - name: storage.tsdb.min-block-duration value: 2h - name: storage.tsdb.max-block-duration value: 2h - name: storage.tsdb.retention.time value: 30d resources: requests: memory: 8Gi limits: memory: 16Gi
|
八、监控与告警
8.1 Prometheus 自监控
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
| apiVersion: monitoring.coreos.com/v1 kind: PrometheusRule metadata: name: prometheus-rules namespace: monitoring spec: groups: - name: prometheus.rules rules: - alert: PrometheusTargetScrapeFail expr: rate(prometheus_target_scrapes_exceeded_sample_limit_total[5m]) > 0 for: 5m labels: severity: warning annotations: summary: "Prometheus 抓取超限" description: "实例 {{ $labels.instance }} 抓取样本数超限" - alert: PrometheusStorageFull expr: predict_linear(prometheus_tsdb_storage_blocks_bytes[6h], 3600 * 24) > 0.9 for: 1h labels: severity: critical annotations: summary: "Prometheus 存储即将耗尽" description: "预计 24 小时内存储空间将耗尽" - alert: PrometheusDown expr: absent(up{job="prometheus"} == 1) for: 5m labels: severity: critical annotations: summary: "Prometheus 实例宕机" description: "Prometheus 实例 {{ $labels.instance }} 已宕机 5 分钟"
|
8.2 联邦层监控
1 2 3 4 5 6 7 8
| - alert: FederationLag expr: time() - prometheus_remote_storage_highest_timestamp_in_seconds > 300 for: 5m labels: severity: warning annotations: summary: "联邦抓取延迟过高" description: "联邦抓取延迟超过 5 分钟"
|
九、故障排查
9.1 常见问题诊断
1 2 3 4 5 6 7 8 9 10 11 12
| curl -s 'http://prometheus-aggregator:9090/api/v1/targets' | jq '.data.activeTargets[] | select(.labels.job | contains("federate"))'
prometheus_target_scrapes_exceeded_sample_limit_total prometheus_target_scrapes_sample_duplicate_timestamp_total
curl -s 'http://prometheus-collector:9090/federate?match[]={__name__=~".+"}' | head -50
kubectl exec -it prometheus-aggregator-0 -- ls -lh /prometheus/
|
9.2 性能问题排查
1 2 3 4 5 6 7 8 9 10 11
| kubectl port-forward prometheus-aggregator-0 9090
prometheus_http_request_duration_seconds_bucket{handler="/api/v1/query"}
prometheus_target_scrape_pool_sync_duration_seconds
|
9.3 数据一致性检查
1 2 3 4 5 6 7 8 9
| # 对比采集层和聚合层数据 # 在采集层查询 up{job="kubernetes-pods"}
# 在聚合层查询相同指标 up{job="kubernetes-pods", cluster="cluster-a"}
# 检查数据完整性 count({__name__=~".+"}) # 对比各层指标数量
|
十、最佳实践
10.1 架构设计
- 分层明确:采集层专注采集,聚合层专注查询
- 标签规范:统一使用 external_labels 标识来源
- 保留策略:采集层短保留,聚合层长保留
- 容量规划:按 10 万时间序列/实例规划
10.2 运维建议
- 定期备份:备份 Prometheus 配置和告警规则
- 版本管理:使用 GitOps 管理 Helm values
- 容量监控:监控存储和内存使用率
- 演练测试:定期进行故障切换演练
10.3 扩展方案
当联邦架构无法满足需求时,考虑:
- Thanos:全局视图 + 对象存储长期保存
- Cortex:多租户 + 水平扩展
- Mimir:Grafana Labs 的 Cortex 发行版
十一、总结
Prometheus 联邦集群是中等规模监控场景的理想选择:
- 适用规模:10-100 万时间序列
- 部署复杂度:中等
- 运维成本:可控
通过本指南,您可以:
- 完成多层联邦架构部署
- 配置跨集群聚合查询
- 实现高可用和故障恢复
- 进行性能优化和故障排查
对于超大规模场景,建议评估 Thanos 或 Mimir 方案。
参考资源: