Thanos 实战:Prometheus 长期存储与全局监控聚合

Prometheus 本地存储默认只有 15 天,多集群监控又各自为政——Thanos 用 Sidecar、Query、Store 与 Compact 把分散的 Prometheus 聚合成一套可长期保留、跨集群统一查询的全局监控体系。本文从痛点出发,带你把 Thanos 真正跑起来。

一、Prometheus 的三个老难题

Prometheus 几乎是云原生监控的事实标准,但它的本地 TSDB 设计从一开始就带着”短期、单机”的假设。规模一大,下面三个问题几乎必然撞上。

1.1 本地存储的天花板

默认 --storage.tsdb.retention.time=15d,超过就被清理。想看三个月前的容量趋势?只能提前把数据搬走,否则永远丢了。而把保留期拉到一年,单机磁盘和查询性能都扛不住。

1.2 多集群数据割裂

生产环境往往是”一地多集群”或”多地多集群”,每个集群一套 Prometheus。排障时要来回切换 Grafana 数据源,根本拼不出一张全局视图。Global View(联邦)方案配置繁琐,且中心节点容易成为瓶颈。

1.3 长期趋势分析乏力

容量规划、季度对账、同比环比,都需要”粗粒度但时间跨度极长”的数据。原始秒级采样存一年既贵又慢。我们需要的是:原始数据短期保留、长期只留降采样后的粗粒度——这正是 Thanos 的拿手好戏。

二、Thanos 架构总览

Thanos 的核心思路是:让每个 Prometheus 旁边挂一个 Sidecar,把落盘的 TSDB block 持续上传到对象存储(S3 兼容即可),再用一个无状态的 Query 组件把”本地 + 对象存储 + 其他集群”的多个数据源聚合成统一查询入口。各组件职责如下:

组件职责有状态?
Sidecar陪伴 Prometheus,上传 TSDB block 到对象存储,并暴露 StoreAPI无(随 Prometheus 扩缩)
Query实现 PromQL,聚合多个 StoreAPI 成全局视图无
Store Gateway从对象存储读取历史 block 对外提供查询无
Compactor压缩、降采样(5m/1h 分辨率)、执行保留策略无(建议单实例)
Receiver接收 Prometheus remote-write,适合”推”模型场景无
Ruler针对全局数据做 recording/alerting rule 评估无

最小可用只需要 Sidecar + Query + 对象存储 三件套;Store Gateway、Compactor 是”长期存储与降采样”的必选项;Receiver / Ruler 按需引入。

三、最小可用:Sidecar + Query

下面用一段 Kubernetes Deployment 片段演示:在同一个 Pod 里跑 Prometheus 和 Thanos Sidecar,Sidecar 通过 --prometheus.url 拉取本地数据,并把 block 上传到对象存储。

apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus
  namespace: monitoring
spec:
  replicas: 1
  template:
    spec:
      containers:
      - name: prometheus
        image: prom/prometheus:v2.53.0
        args:
        - --config.file=/etc/prometheus/prometheus.yml
        - --storage.tsdb.path=/prometheus
        - --storage.tsdb.retention.time=15d
        volumeMounts:
        - {name: data, mountPath: /prometheus}
      - name: thanos-sidecar
        image: quay.io/thanos/thanos:v0.36.0
        args:
        - sidecar
        - --prometheus.url=http://localhost:9090
        - --tsdb.path=/prometheus
        - --objstore.config-file=/etc/thanos/objstore.yaml
        ports:
        - {containerPort: 10901, name: grpc}   # StoreAPI
        - {containerPort: 10902, name: http}   # metrics
        volumeMounts:
        - {name: data, mountPath: /prometheus}
      volumes:
      - name: data
        emptyDir: {}

接着部署 Query,把各集群的 Sidecar 作为数据源通过 DNS SRV 自动发现聚合起来:

thanos query \
  --http-address=0.0.0.0:9090 \
  --grpc-address=0.0.0.0:10901 \
  --store=dnssrv+_grpc._tcp.thanos-sidecar.monitoring.svc:10901 \
  --store=dnssrv+_grpc._tcp.thanos-store.monitoring.svc:10901

打开 Query 的 :9090 UI,左侧 “Store” 下拉框可以勾选数据源,输入任意 PromQL 即可跨集群查询。如果你已经用 Kustomize 管理 K8s 声明式配置,把这段直接做成 overlay 即可多环境复用。

四、接入对象存储(以 MinIO 为例)

Thanos 支持 S3、GCS、Azure Blob、Swift 以及腾讯云 COS 等。本地验证最方便的是 MinIO(S3 协议兼容)。把下列配置挂进 Sidecar 和 Store Gateway 的 --objstore.config-file:

type: S3
config:
  bucket: thanos
  endpoint: minio.monitoring.svc:9000
  access_key: minioadmin
  secret_key: minioadmin
  insecure: true          # 自签证书时开启
  signature_version2: false

Sidecar 会每隔约 2 小时(block 上传周期)把本地 TSDB block 推到桶里;Store Gateway 启动时扫描桶内 block 索引,让 Query 能查到历史数据。对象存储是 Thanos 的”真相源”,Prometheus 本地磁盘只是缓存。

五、全局查询:跨集群统一 PromQL

Thanos 最爽的一点:Query 对上层完全兼容 Prometheus 的 HTTP API 和 PromQL。你只需把 Grafana 的数据源从各集群 Prometheus 改成这一个 Query 地址,所有面板立刻拥有全局视野。多个集群同名的指标会自动按 cluster / replica 等 external label 区分,配合 sum by (cluster) 就能做跨集群聚合。

多副本去重:生产环境常给 Prometheus 部署 HA 双副本,两份采样完全一致。Thanos Query 提供 --query.replica-label=replica,按该标签自动去重,避免跨集群求和时同一份数据被重复计算。再配合 --query.auto-downsampling,查询数月区间会自动优先选用 5m/1h 降采样块,查询速度与资源消耗都大幅下降。Query 本身也应多副本前置负载均衡,避免成为单点。

如果你的告警和弹性伸缩依赖监控数据,也可以让 K8s HPA 基于自定义指标 的链路统一走 Thanos Query,避免每个集群单独配置 Adapter。

六、降采样与压缩(Compactor)

长期存储如果只堆原始数据,查一年的曲线会非常慢且昂贵。Compactor 周期性地把旧 block 合并,并生成两种降采样块:5 分钟分辨率与 1 小时分辨率。查询长区间时,Query 自动选用粗粒度块,速度与成本都大幅下降。

分辨率典型用途建议保留
raw(原始)精确定位、短期排障30–90 天
5m 降采样周/月级趋势180 天
1h 降采样季度/年度同比长期(0d 表示永久)
thanos compact \
  --objstore.config-file=objstore.yaml \
  --data-dir=/tmp/thanos-compact \
  --retention.resolution-raw=30d \
  --retention.resolution-5m=180d \
  --retention.resolution-1h=0d \
  --wait

Compactor 建议全局只跑一个实例(可用 CronJob 串行执行并加锁),避免并发压缩同一 block。它与 Prometheus + Grafana 监控告警 体系天然互补:Prometheus 管实时,Thanos 管历史。

七、生产落地清单与排障

常见坑现象对策
external label 重复数据来源冲突、查询结果翻倍每个 Prometheus 设唯一 external_labels.cluster
对象存储权限不足Sidecar 上传 403/失败校验 bucket 策略与 endpoint 连通性(含 TLS)
Compactor 多实例并发block 损坏单实例 + 分布式锁,或串行 CronJob
Query 数据源过多查询变慢用 Store Gateway 收敛,按地域分 Query
Sidecar 与 Prometheus 版本错配API 不兼容对齐 TSDB 格式版本,保持 Thanos 较新

别忘了监控 Thanos 自身:Sidecar、Query、Store、Compactor 都暴露 /metrics,用 Prometheus + Grafana 监控面板 把它们也纳入采集。发布与配置变更建议接入 GitHub Actions 流水线,用 Docker Compose 或 K8s 统一交付,保证环境一致。

八、Thanos 还是 Mimir / Cortex?

到了 2026 年,长期存储方案主要有三派。Thanos 胜在”对已有 Prometheus 侵入最小”——加个 Sidecar 就能上;Cortex / Grafana Mimir 则是”把所有数据收口到独立后端”的集中式架构,扩展性更强但改造更重。

维度ThanosMimir / Cortex
部署形态Sidecar 贴近 Prometheus集中式后端,Prometheus 只 remote-write
上手成本低,增量接入中高,需独立运维后端
扩展性依赖对象存储,水平扩展好组件分片,超大规模更稳
适用场景多集群、存量 Prometheus 多单一超大数据中心、统一管控

结论:如果你已经有一堆 Prometheus、想用最小代价获得长期存储和全局视图,Thanos 是最平滑的选择;如果从头搭建且规模极大,再考虑 Mimir。无论选谁,先把基础监控(参见 K8s 监控告警实战)做扎实,再谈长期化。

上一篇 Docker buildx 多架构镜像实战:一次构建 arm64 与 amd64
下一篇 集群脑裂排查实战:Redis 与 MySQL 双主写冲突根治
最新评论
Docker 网络模式详解:bridge/host 生产选型 - FSData
Docker 网络模式详解:bridge/host 生产选型 - FSData
8月20日
[…] 注意最后那条:把端口绑定到 127.0.0.1,再由宿主机上的 Nginx 反代进来,比直接 -p 80:80 暴露安全得多,也方便统一做
Vue3 + TypeScript 工程化:类型安全的前端架构 - FSData
Vue3 + TypeScript 工程化:类型安全的前端架构 - FSData
8月20日
[…] Pinia 的工程化用法,可以参考我们之前的实战文章 《Vue3 组合式 API + Pinia:状态管理从入门到实战》,那里覆盖了 Sto
2026 年最值得装的 10 个 VS Code 插件(AI/前端/后端/效率全覆盖) - FSData
2026 年最值得装的 10 个 VS Code 插件(AI/前端/后端/效率全覆盖) - FSData
8月19日
[…] 状态,点一下就能起停容器,配合我们讲过的 Docker Compose 编排 […]
Redis 缓存设计:穿透、击穿、雪崩与最佳实践 - FSData
Redis 缓存设计:穿透、击穿、雪崩与最佳实践 - FSData
8月19日
[…] 缓存三大坑的本质都是”缓存失效导致请求穿透到数据库”。记住口诀:穿透用布隆、击穿用锁、雪崩用错峰。配合合理的过期策略
GitHub Actions 实战:从零搭建 CI/CD 流水线 - FSData
GitHub Actions 实战:从零搭建 CI/CD 流水线 - FSData
8月19日
[…] Docker 镜像部署。结合我们之前写的 Docker Compose 一键编排实战,可以在 CI […]