问题背景
单机Prometheus用着挺好,直到遇到这些问题:
- 存储空间有限:本地存储撑不了多久,15天的数据就把磁盘塞满了
- 单点故障:Prometheus挂了,监控数据就没了
- 多集群查询难:每个K8s集群一个Prometheus,想看全局数据得挨个登录
- 数据不能跨实例聚合:不同Prometheus的数据没法一起算
Prometheus官方的联邦方案解决不了长期存储,而且联邦本身也是单点。
Thanos的出现解决了这些问题:
- 无限期存储(用对象存储)
- 全局查询(跨Prometheus实例)
- 高可用(多副本去重)
- 向下采样(长期数据压缩)
Thanos架构
Thanos由几个组件构成:
┌─────────────────┐ ┌─────────────────┐ │ Prometheus 1 │ │ Prometheus 2 │ │ + Sidecar │ │ + Sidecar │ └────────┬────────┘ └────────┬────────┘ │ │ │ ┌──────────────────┤ │ │ │ ▼ ▼ ▼ ┌─────────────┐ ┌─────────┐ │ Querier │◄────────│ Store │ └──────┬──────┘ │ Gateway │ │ └────┬────┘ │ │ ▼ ▼ ┌─────────────┐ ┌─────────┐ │ Query │ │ Object │ │ Frontend │ │ Storage │ └─────────────┘ └─────────┘- Sidecar:挂在Prometheus旁边,上传数据到对象存储
- Store Gateway:从对象存储读取历史数据
- Querier:全局查询入口,聚合所有数据源
- Query Frontend:查询缓存和分片
- Compactor:数据压缩和向下采样
- Ruler:分布式告警规则评估
部署实战
用Helm部署最方便。假设对象存储用MinIO(生产环境用云厂商的OSS)。
准备对象存储
先创建存储配置:
# thanos-storage.yamltype:S3config:bucket:thanosendpoint:minio.monitoring.svc.cluster.local:9000access_key:thanossecret_key:thanos123456insecure:true创建Secret:
kubectl create secret generic thanos-objstore-config\--from-file=objstore.yml=thanos-storage.yaml\-n monitoring配置Prometheus + Sidecar
修改Prometheus配置,添加external_labels和Sidecar:
# prometheus-values.yaml (kube-prometheus-stack)prometheus:prometheusSpec:replicas:2retention:6hretentionSize:10GB# 外部标签,用于去重externalLabels:cluster:prod-cluster-1replica:$(POD_NAME)# 启用Thanos Sidecarthanos:image:quay.io/thanos/thanos:v0.32.5objectStorageConfig:existingSecret:name:thanos-objstore-configkey:objstore.yml# 禁用本地规则评估(用Thanos Ruler)ruleSelector:{}# Sidecar的grpc端口thanosService:enabled:truethanosServiceMonitor:enabled:true部署Thanos组件
# thanos-components.yaml---apiVersion:apps/v1kind:Deploymentmetadata:name:thanos-querynamespace:monitoringspec:replicas:2selector:matchLabels:app:thanos-querytemplate:metadata:labels:app:thanos-queryspec:containers:-name:thanos-queryimage:quay.io/thanos/thanos:v0.32.5args:-query---log.level=info---query.replica-label=replica---query.auto-downsampling# 连接所有Sidecar---endpoint=dnssrv+_grpc._tcp.prometheus-thanos.monitoring.svc.cluster.local# 连接Store Gateway---endpoint=dnssrv+_grpc._tcp.thanos-store.monitoring.svc.cluster.localports:-containerPort:10902name:http-containerPort