生产环境 Thanos 必须分层部署、组件解耦、存储分离,单实例 Prometheus + Sidecar 会导致上传失败、查询卡顿、Compactor 崩溃;Sidecar、Store Gateway、Query、Compactor 各有严格生产约束,对象存储配置需精确到 bucket 命名、TLS、region 等细节,历史数据查不到多因时间窗口未对齐或组件启动顺序错误。

生产环境不能只装一个 Prometheus 再加个 Thanos 就算“全套”——必须分层部署、组件解耦、存储分离,否则 1000+ 节点或 300+ 集群下,查询卡顿、上传失败、Compactor 崩溃是常态。
为什么不能直接用单实例 Prometheus + Thanos Sidecar?
这是最常踩的坑:把 Thanos 当成“Prometheus 插件”来用,结果在压测阶段就暴露问题。
-
Prometheus本地storage.tsdb.max-block-duration默认是 2h,但若设置过大(如 24h),Sidecar上传 block 时会卡住,因为 block 太大、压缩慢、网络超时;设太小(如 30m)又导致对象存储里碎片 block 过多,Store Gateway启动慢、索引压力大。 -
Sidecar和Prometheus共享同一进程内存,Prometheus OOM 时 Sidecar 也挂,上传中断,对象存储出现“半块”(half-written block),Compactor后续会反复报invalid block: meta.json missing错误。 - 所有集群共用一个
Query实例?一旦该节点 CPU 或网络抖动,跨区域查询全挂,且无法按租户/集群做查询限流。
必须拆开部署的四个核心组件及其生产约束
Thanos 不是“一装就灵”,每个组件在生产中都有明确职责边界和资源契约:
-
Sidecar:仅与单个Prometheus实例绑定,启动参数必须含--tsdb.path=/prometheus(路径需与 Prometheus 的--storage.tsdb.path严格一致),且--prometheus.url必须用http://localhost:9090(不可用 Pod IP 或 DNS,避免 DNS 缓存失效导致探针失败)。 -
Store Gateway:每个实例最多对接 1 个对象存储 bucket,不支持多 bucket 聚合;建议按集群维度部署独立实例(如store-gw-cluster-a),避免单点故障影响全局历史数据访问。 -
Query:必须通过--store显式列出所有后端(如--store=dnssrv+_grpc._tcp.thanos-store-gw-a.default.svc.cluster.local),不能依赖自动服务发现——DNS SRV 记录变更延迟会导致部分 store 瞬间不可达。 -
Compactor:必须单实例运行(并发 compact 会破坏对象存储中 block 的一致性),且需配置--wait参数防止在 block 正在上传时提前触发降采样;日志中若频繁出现skipping block: not healthy,说明上游Sidecar上传未完成或Store Gateway尚未加载该 block。
对象存储配置的关键细节(MinIO/S3/OSS)
别只填 endpoint 和 key——生产环境对象存储配置错一个字段,就会让整个 Thanos 长期存储失效:
-
objstore.yml中的bucket名必须全小写(MinIO 严格校验,Thanos上传时若遇到大写 bucket 名会静默失败); - 使用 MinIO 时,
insecure: true仅限内网,但必须同步关闭tls_config.insecure_skip_verify: true,否则Sidecar启动时报failed to create client: unable to load TLS config; - S3 兼容存储(如阿里云 OSS、腾讯云 COS)需显式指定
region字段,即使 endpoint 已含地域信息(如oss-cn-hangzhou.aliyuncs.com),否则Store Gateway列表 bucket 时返回空; - 所有组件(
Sidecar/Store Gateway/Compactor)必须使用同一份objstore.yml,且文件权限为600,否则thanos进程启动时拒绝读取密钥。
查不到历史数据?先确认这三件事
90% 的“查不到 7 天前数据”问题,不是配置错,而是没理解 Thanos 数据流的三个时间窗口:
-
Prometheus本地保留策略:--storage.tsdb.retention.time=7d—— 只控制本地磁盘留多久,不影响对象存储; -
Sidecar上传时机:默认每 2 小时上传一次已封存 block(由max-block-duration控制),但首次上传要等第一个 block 完整生成(即至少 2h 后才见首块); -
Store Gateway加载延迟:启动后需主动扫描对象存储,首次加载可能耗时数分钟(取决于 block 数量),期间/status页面显示0 blocks loaded是正常现象,不是故障。
真正容易被忽略的是:如果 Query 组件启动早于 Store Gateway,它不会自动重试连接,必须手动重启 Query 或等待其内部健康检查周期(默认 30s)后才恢复聚合能力。











