Prometheus 多集群联邦与 Thanos 长期存储:从单集群到全局监控
Prometheus 多集群联邦与 Thanos 长期存储:从单集群到全局监控
一、监控数据的"孤岛困境":多集群环境下的全局视角缺失
企业级 Kubernetes 环境通常包含多个集群(开发、测试、生产、不同地域),每个集群部署独立的 Prometheus 实例采集指标。这种架构导致三个核心问题:一是全局视角缺失,无法在一个面板上查看所有集群的资源使用和告警状态;二是数据短期化,Prometheus 默认保留 15 天数据,历史数据查询需要逐个集群翻找;三是存储成本高,每个集群独立存储监控数据,无法集中管理和压缩。
Prometheus 联邦(Federation)和 Thanos 是解决多集群监控的两个互补方案:联邦实现跨集群数据聚合,Thanos 实现长期存储和全局查询。
二、多集群监控的架构设计
flowchart TD A[集群 A Prometheus] --> B[Thanos Sidecar] C[集群 B Prometheus] --> D[Thanos Sidecar] E[集群 C Prometheus] --> F[Thanos Sidecar] B --> G[对象存储 S3/OSS] D --> G F --> G B --> H[Thanos Query] D --> H F --> H H --> I[Grafana 全局面板] G --> H subgraph 联邦模式 J[中心 Prometheus] --> K[集群 A /federation] J --> L[集群 B /federation] end联邦模式适合轻量级场景:中心 Prometheus 从各集群的 /federation 端点拉取关键指标。Thanos 模式适合大规模场景:各集群的 Sidecar 将数据上传到对象存储,Thanos Query 提供全局查询接口,支持跨集群和跨时间范围的数据查询。
三、工程化实现
3.1 Prometheus 联邦配置
# 中心 Prometheus:从各集群拉取联邦数据 # central-prometheus.yaml global: scrape_interval: 15s scrape_configs: # 从集群 A 拉取联邦数据 - job_name: 'federation-cluster-a' scrape_interval: 30s honor_labels: true metrics_path: '/federate' params: 'match[]': # 只拉取关键指标,避免数据量过大 - '{job="kubernetes-nodes"}' - '{job="kubernetes-pods"}' - '{__name__=~"up$"}' - '{__name__=~"container_cpu_usage_seconds_total"}' - '{__name__=~"container_memory_working_set_bytes"}' static_configs: - targets: - 'prometheus-cluster-a:9090' labels: cluster: 'cluster-a' # 从集群 B 拉取联邦数据 - job_name: 'federation-cluster-b' scrape_interval: 30s honor_labels: true metrics_path: '/federate' params: 'match[]': - '{job="kubernetes-nodes"}' - '{job="kubernetes-pods"}' - '{__name__=~"up$"}' - '{__name__=~"container_cpu_usage_seconds_total"}' - '{__name__=~"container_memory_working_set_bytes"}' static_configs: - targets: - 'prometheus-cluster-b:9090' labels: cluster: 'cluster-b'3.2 Thanos 部署配置
# Thanos Sidecar:与 Prometheus 共存,上传数据到对象存储 apiVersion: apps/v1 kind: StatefulSet metadata: name: prometheus spec: template: spec: containers: - name: prometheus image: prom/prometheus:v2.50.0 args: - '--config.file=/etc/prometheus/prometheus.yml' - '--storage.tsdb.path=/prometheus' - '--storage.tsdb.retention.time=2d' # 本地只保留 2 天 - '--web.enable-remote-write-receiver' ports: - containerPort: 9090 - name: thanos-sidecar image: thanosio/thanos:v0.34.0 args: - 'sidecar' - '--tsdb.path=/prometheus' - '--prometheus.url=http://localhost:9090' - '--objstore.config-file=/etc/thanos/objstore.yml' - '--shipper.upload-compacted=true' # 上传已压缩数据 volumeMounts: - name: prometheus-data mountPath: /prometheus - name: thanos-config mountPath: /etc/thanos --- # 对象存储配置 apiVersion: v1 kind: Secret metadata: name: thanos-objstore-config type: Opaque stringData: objstore.yml: | type: s3 config: bucket: thanos-storage endpoint: s3.amazonaws.com access_key: ${AWS_ACCESS_KEY} secret_key: ${AWS_SECRET_KEY}3.3 Thanos Query 全局查询
# Thanos Query:全局查询入口 apiVersion: apps/v1 kind: Deployment metadata: name: thanos-query spec: template: spec: containers: - name: thanos-query image: thanosio/thanos:v0.34.0 args: - 'query' - '--http-address=0.0.0.0:19192' - '--query.replica-label=replica' # 连接各集群的 Sidecar(实时数据) - '--store=thanos-sidecar-cluster-a:10901' - '--store=thanos-sidecar-cluster-b:10901' # 连接对象存储(历史数据) - '--store=thanos-store-gateway:10901' ports: - containerPort: 19192 --- # Thanos Store Gateway:从对象存储读取历史数据 apiVersion: apps/v1 kind: Deployment metadata: name: thanos-store-gateway spec: template: spec: containers: - name: thanos-store image: thanosio/thanos:v0.34.0 args: - 'store' - '--data-dir=/data' - '--objstore.config-file=/etc/thanos/objstore.yml' - '--index-cache.config-file=/etc/thanos/index-cache.yml'3.4 全局告警规则
# 全局告警规则:跨集群统一管理 apiVersion: monitoring.coreos.com/v1 kind: PrometheusRule metadata: name: global-alerts spec: groups: - name: multi-cluster rules: # 集群节点不可用 - alert: ClusterNodeDown expr: up{job="kubernetes-nodes"} == 0 for: 5m labels: severity: critical annotations: summary: "集群 {{ $labels.cluster }} 节点 {{ $labels.instance }} 不可用" # 跨集群资源使用率告警 - alert: HighClusterCPUUsage expr: | avg by (cluster) ( rate(container_cpu_usage_seconds_total{container!=""}[5m]) ) > 0.8 for: 10m labels: severity: warning annotations: summary: "集群 {{ $labels.cluster }} 平均 CPU 使用率超过 80%"四、多集群监控的 Trade-offs
联邦 vs Thanos 的选择:联邦模式简单轻量,但只能拉取当前数据,无法查询历史;且拉取所有指标会导致中心 Prometheus 存储爆炸。Thanos 功能完整,支持长期存储和全局查询,但架构复杂,需要对象存储和多个 Thanos 组件。建议小规模(< 5 集群)用联邦,大规模用 Thanos。
对象存储的成本:Thanos 将监控数据上传到 S3/OSS,长期存储成本约 $0.023/GB/月。一个 50 集群、每集群 100 万 series 的环境,月存储成本约 $500-1000。建议配置数据降采样(Thanos Compactor):原始数据保留 30 天,5 分钟降采样保留 1 年,1 小时降采样永久保留。
查询性能:跨集群查询需要 Thanos Query 从多个 Store Gateway 获取数据并合并,查询延迟可能达到数秒。建议在 Grafana 中设置查询超时,并对大范围时间查询使用降采样数据。
网络连通性:联邦和 Thanos 都需要跨集群网络连通。如果集群在不同 VPC 或云厂商,需要配置 VPN 或专线。建议使用 Thanos Receive 模式,让各集群主动推送数据到中心,避免跨集群拉取的网络依赖。
五、总结
多集群监控从"单集群孤岛"走向"全局视角",联邦和 Thanos 是两种互补的方案。落地路线上,建议先用联邦实现跨集群关键指标聚合,再引入 Thanos 实现长期存储和全局查询。关键原则:联邦只拉取关键指标,Thanos 必须配置降采样,查询性能需要优化,网络连通性是基础设施前提。
