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:

  1. Single node — Geen native clustering of HA
  2. Lokale storage — Retentie beperkt door schijfgrootte
  3. Single cluster view — Kan niet queryen over clusters heen
  4. 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:

  1. Stelt Prometheus data beschikbaar aan Thanos Querier via gRPC
  2. Uploadt voltooide TSDB blocks naar object storage
  3. 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:

ResolutieData per dag1 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.