Je kunt niet fixen wat je niet kunt zien. Je kunt niet optimaliseren wat je niet kunt meten.
Prometheus is de standaard voor Kubernetes metrics. Het werkt prachtig — totdat je lange-termijn opslag nodig hebt, of meerdere clusters, of hoge beschikbaarheid. Dan loop je tegen de limieten aan.
Thanos breidt Prometheus uit zonder het te vervangen. Behoud je bestaande setup, voeg Thanos componenten toe, krijg onbeperkte retentie en globale queries.
Het Probleem met Standalone Prometheus
Prometheus heeft ingebouwde beperkingen:
- Single node — Geen native clustering of HA
- Lokale storage — Retentie beperkt door schijfgrootte
- Single cluster view — Kan niet queryen over clusters heen
- Geen downsampling — Oude data neemt evenveel ruimte als nieuwe
Voor een enkel klein cluster met 2 weken retentie zijn dit geen problemen. Voor productie multi-cluster omgevingen met compliance eisen zijn het blokkers.
Thanos Architectuur
Thanos voegt componenten toe rond Prometheus:
flowchart TD
subgraph clusterA["Cluster A"]
PA["Prometheus + Sidecar"]
end
subgraph clusterB["Cluster B"]
PB["Prometheus + Sidecar"]
end
PA --> OS["Object Storage<br/>(S3/MinIO/GCS)"]
PB --> OS
OS --> Q["Querier"]
OS --> SG["Store Gateway"]
OS --> C["Compactor"]
SG --> Q
Q --> G["Grafana"]
Sidecar — Draait naast Prometheus, uploadt blocks naar object storage Store Gateway — Serveert historische data van object storage Querier — Aggregeert data van sidecars en store gateway Compactor — Downsampled en dedupliceert data in object storage
Thanos Installeren
Met de Bitnami Helm chart:
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update
helm install thanos bitnami/thanos \
--namespace monitoring \
--create-namespace \
--set objstoreConfig="$(cat thanos-objstore.yaml)"
Object store configuratie (thanos-objstore.yaml):
type: s3
config:
bucket: thanos-metrics
endpoint: minio.storage:9000
access_key: ${MINIO_ACCESS_KEY}
secret_key: ${MINIO_SECRET_KEY}
insecure: true # Voor MinIO zonder TLS
Prometheus met Thanos Sidecar
Pas je Prometheus deployment aan om de sidecar te bevatten:
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
metadata:
name: prometheus
namespace: monitoring
spec:
replicas: 2 # HA paar
retention: 2h # Korte lokale retentie, Thanos handelt lange-termijn
# Thanos sidecar configuratie
thanos:
baseImage: quay.io/thanos/thanos
version: v0.34.0
objectStorageConfig:
key: thanos.yaml
name: thanos-objstore-secret
# Externe labels voor deduplicatie
externalLabels:
cluster: production
replica: $(POD_NAME)
# Laat Thanos sidecar Prometheus data benaderen
storage:
volumeClaimTemplate:
spec:
storageClassName: longhorn
resources:
requests:
storage: 50Gi
De sidecar:
- Stelt Prometheus data beschikbaar aan Thanos Querier via gRPC
- Uploadt voltooide TSDB blocks naar object storage
- Beantwoordt Store API queries voor recente data
Thanos Componenten Configuratie
Querier
apiVersion: apps/v1
kind: Deployment
metadata:
name: thanos-querier
namespace: monitoring
spec:
replicas: 2
template:
spec:
containers:
- name: thanos-query
image: quay.io/thanos/thanos:v0.34.0
args:
- query
- --http-address=0.0.0.0:9090
- --grpc-address=0.0.0.0:10901
# Verbind met sidecars
- --store=dnssrv+_grpc._tcp.prometheus-operated.monitoring.svc
# Verbind met store gateway
- --store=dnssrv+_grpc._tcp.thanos-store.monitoring.svc
# Deduplicatie
- --query.replica-label=replica
ports:
- name: http
containerPort: 9090
- name: grpc
containerPort: 10901
Store Gateway
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: thanos-store
namespace: monitoring
spec:
replicas: 2
template:
spec:
containers:
- name: thanos-store
image: quay.io/thanos/thanos:v0.34.0
args:
- store
- --http-address=0.0.0.0:10902
- --grpc-address=0.0.0.0:10901
- --data-dir=/var/thanos/store
- --objstore.config-file=/etc/thanos/objstore.yaml
volumeMounts:
- name: objstore-config
mountPath: /etc/thanos
- name: data
mountPath: /var/thanos/store
volumes:
- name: objstore-config
secret:
secretName: thanos-objstore-secret
volumeClaimTemplates:
- metadata:
name: data
spec:
storageClassName: longhorn
resources:
requests:
storage: 10Gi
Compactor
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: thanos-compactor
namespace: monitoring
spec:
replicas: 1 # Slechts één compactor!
template:
spec:
containers:
- name: thanos-compact
image: quay.io/thanos/thanos:v0.34.0
args:
- compact
- --http-address=0.0.0.0:10902
- --data-dir=/var/thanos/compact
- --objstore.config-file=/etc/thanos/objstore.yaml
- --retention.resolution-raw=30d
- --retention.resolution-5m=90d
- --retention.resolution-1h=1y
- --wait
volumeMounts:
- name: objstore-config
mountPath: /etc/thanos
- name: data
mountPath: /var/thanos/compact
Retentie configuratie:
- Raw data: 30 dagen op volledige resolutie
- 5m gedownsampled: 90 dagen
- 1h gedownsampled: 1 jaar
Oudere data neemt minder ruimte omdat het gedownsampled is.
GitOps Deployment
Voor ArgoCD:
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: thanos
namespace: argocd
spec:
project: default
source:
repoURL: https://charts.bitnami.com/bitnami
chart: thanos
targetRevision: 12.20.0
helm:
values: |
objstoreConfig: |-
type: s3
config:
bucket: thanos-metrics
endpoint: minio.storage:9000
insecure: true
query:
enabled: true
replicaCount: 2
stores:
- dnssrv+_grpc._tcp.prometheus-operated.monitoring.svc
storegateway:
enabled: true
replicaCount: 2
persistence:
size: 20Gi
compactor:
enabled: true
retentionResolutionRaw: 30d
retentionResolution5m: 90d
retentionResolution1h: 1y
persistence:
size: 50Gi
ruler:
enabled: false # Gebruik Prometheus rules in plaats daarvan
receive:
enabled: false # Gebruiken sidecar mode
destination:
server: https://kubernetes.default.svc
namespace: monitoring
Hoge Beschikbaarheid
Thanos maakt Prometheus HA mogelijk:
# Draai twee Prometheus instances
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
spec:
replicas: 2
externalLabels:
replica: $(POD_NAME) # Verschillend voor elke replica
Beide Prometheus instances scrapen dezelfde targets. Thanos Querier dedupliceert:
# Querier configuratie
args:
- --query.replica-label=replica
- --query.replica-label=prometheus_replica
Queries retourneren automatisch gededupliceerde resultaten.
Globaal Overzicht Over Clusters
Voeg meerdere clusters toe aan dezelfde Thanos deployment:
Cluster A Prometheus:
externalLabels:
cluster: production-eu
replica: $(POD_NAME)
Cluster B Prometheus:
externalLabels:
cluster: production-us
replica: $(POD_NAME)
Querier aggregeert beide:
# Totaal requests over alle clusters
sum(rate(http_requests_total[5m]))
# Requests per cluster
sum by (cluster) (rate(http_requests_total[5m]))
Grafana Integratie
Wijs Grafana naar Thanos Querier:
apiVersion: v1
kind: ConfigMap
metadata:
name: grafana-datasources
data:
thanos.yaml: |
apiVersion: 1
datasources:
- name: Thanos
type: prometheus
url: http://thanos-query.monitoring:9090
access: proxy
isDefault: true
jsonData:
timeInterval: "15s"
Al je bestaande Prometheus dashboards werken — wijs gewoon naar Thanos in plaats daarvan.
Recording Rules voor Performance
Pre-compute dure queries:
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: recording-rules
spec:
groups:
- name: aggregations
interval: 1m
rules:
# Pre-aggregeer request rate per service
- record: service:http_requests:rate5m
expr: sum by (service) (rate(http_requests_total[5m]))
# Pre-aggregeer error rate
- record: service:http_errors:rate5m
expr: sum by (service) (rate(http_requests_total{status=~"5.."}[5m]))
# Pre-compute availability
- record: service:availability:ratio
expr: |
1 - (
service:http_errors:rate5m /
service:http_requests:rate5m
)
Dashboards queryen de pre-computed service:* metrics in plaats van raw data.
Alerting Architectuur
Houd alerting dicht bij data — draai Alertmanager met Prometheus, niet Thanos:
apiVersion: monitoring.coreos.com/v1
kind: Prometheus
spec:
alerting:
alertmanagers:
- namespace: monitoring
name: alertmanager
port: web
ruleSelector:
matchLabels:
role: alert-rules
Thanos Ruler bestaat maar voegt complexiteit toe. Voor de meeste setups is Prometheus alerting voldoende.
Thanos Zelf Monitoren
Thanos stelt Prometheus metrics beschikbaar. Monitor:
# Sidecar upload succes
thanos_shipper_uploads_total
thanos_shipper_upload_failures_total
# Store gateway performance
thanos_bucket_store_series_fetch_duration_seconds
thanos_bucket_store_block_loads_total
# Compactor health
thanos_compact_group_compactions_total
thanos_compact_group_compaction_failures_total
# Querier performance
thanos_query_gate_duration_seconds
Alert op failures:
- alert: ThanosSidecarUploadFailing
expr: increase(thanos_shipper_upload_failures_total[1h]) > 0
for: 15m
labels:
severity: warning
annotations:
summary: "Thanos sidecar faalt bij uploaden van blocks"
Storage Overwegingen
Object storage kosten voor metrics:
| Resolutie | Data per dag | 1 jaar kosten (S3) |
|---|---|---|
| Raw (15s) | ~100MB/target | ~$4/target |
| 5m downsample | ~3MB/target | ~$0.12/target |
| 1h downsample | ~0.5MB/target | ~$0.02/target |
Downsampling is cruciaal voor kostenbeheersing. Bewaar raw data niet voor altijd.
Voor self-hosted object storage werkt MinIO goed:
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: minio
spec:
template:
spec:
containers:
- name: minio
image: minio/minio:latest
args:
- server
- /data
- --console-address
- ":9001"
env:
- name: MINIO_ROOT_USER
valueFrom:
secretKeyRef:
name: minio-credentials
key: root-user
- name: MINIO_ROOT_PASSWORD
valueFrom:
secretKeyRef:
name: minio-credentials
key: root-password
Mijn Productie Setup
# Prometheus met sidecar
prometheus:
replicas: 2
retention: 6h # Zeer kort, Thanos handelt lange-termijn
thanos:
objectStorageConfig:
name: thanos-objstore
externalLabels:
cluster: production
environment: prod
# Thanos componenten
thanos:
query:
replicaCount: 2
stores:
- dnssrv+_grpc._tcp.prometheus-operated.monitoring.svc
- dnssrv+_grpc._tcp.thanos-store.monitoring.svc
storegateway:
replicaCount: 2
persistence:
size: 50Gi
compactor:
retentionResolutionRaw: 14d
retentionResolution5m: 60d
retentionResolution1h: 365d
persistence:
size: 100Gi
# Object storage
minio:
replicas: 4
persistence:
size: 500Gi
Belangrijke beslissingen:
- 6h lokale retentie — Sidecar uploadt frequent, geen lange lokale opslag nodig
- 14d raw retentie — Volledige resolutie voor recente debugging
- 1 jaar 1h retentie — Capacity planning en trends
- Self-hosted MinIO — Data soevereiniteit, geen cloud afhankelijkheid
Waarom Dit Ertoe Doet
Metrics zijn hoe je je systemen begrijpt. Ze beantwoorden:
- Is deze service gezond?
- Wat veranderde er voor het incident?
- Halen we onze SLOs?
- Waar moeten we investeren in optimalisatie?
Zonder lange-termijn metrics verlies je het vermogen om “vergeleken met wanneer?” te beantwoorden. Zonder cross-cluster queries kun je het volledige plaatje niet zien.
Prometheus + Thanos geeft je onbeperkte retentie, globaal overzicht en hoge beschikbaarheid terwijl je de vertrouwde Prometheus interface behoudt.
Dit is begrip op schaal.
Je kunt niet verbeteren wat je niet kunt zien over tijd. Thanos breidt Prometheus uit van “wat gebeurt er nu” naar “wat is er gebeurd” — het verschil tussen reactief brandjes blussen en proactieve optimalisatie.
