Kubernetes monitoring met Prometheus en kube-prometheus-stack

Een productiecluster zonder observability is een cluster waar je naar raadt. Deze tutorial loopt door de installatie van kube-prometheus-stack via Helm, legt uit wat elk component doet, laat zien hoe je je eigen applicatiemetrics scrapt met ServiceMonitor, hoe je alertingregels schrijft, alerts routeert en wanneer remote storage nodig wordt.

Inhoudsopgave

Wat je leert

Aan het eind van deze tutorial heb je een werkende Prometheus-, Alertmanager- en Grafana-stack draaien op je cluster. Je weet hoe je metrics van je eigen applicaties scrapt, alertingregels schrijft die afgaan als er iets misgaat, die alerts doorstuurt naar Slack of PagerDuty, en wanneer de lokale opslag van Prometheus niet meer genoeg is.

Vereisten

Zorg dat je het volgende bij de hand hebt:

  • Een draaiend Kubernetes-cluster, versie 1.25 of nieuwer. Van een lokaal kind/minikube-cluster tot managed GKE/EKS/AKS maakt niet uit. Deze tutorial is geschreven tegen chartversie 83.4.0, die Prometheus Operator v0.90.1 en Prometheus 3.x bundelt.
  • Helm 3 geinstalleerd en geconfigureerd voor je cluster.
  • kubectl met cluster-admin-rechten (de chart installeert CRDs en clusterwijde resources).
  • Basiskennis van Kubernetes Deployments, Services en namespaces. Wil je Services opfrissen, dan behandelt de Kubernetes Services-gids de relevante Service-typen voor metric-endpoints.

kube-prometheus-stack installeren met Helm

De kube-prometheus-stack Helm-chart is de meestgebruikte installatieroute voor Prometheus op Kubernetes. De chart bundelt Prometheus Operator, Prometheus-server, Alertmanager, Grafana, kube-state-metrics en node-exporter in een enkele release.

Even een belangrijk verschil: de naam kube-prometheus (zonder "stack") verwijst naar een apart jsonnet-gebaseerd project onder de Prometheus Operator GitHub-organisatie. De Helm-chart is een community-artifact onder prometheus-community. Deze tutorial behandelt de Helm-chart.

Minimale installatie

Twee commando's en je stack draait:

# Voeg de prometheus-community Helm-repository toe
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

# Installeer in een aparte monitoring-namespace
helm install kube-prom-stack prometheus-community/kube-prometheus-stack \
  --namespace monitoring --create-namespace

Dit installeert alles met standaardinstellingen: een enkele Prometheus-replica, een enkele Alertmanager-replica, Grafana met een tijdelijke SQLite-database en geen persistente opslag. Prima om te verkennen. Niet genoeg voor productie.

Productiewaarden

Voor een cluster waar je om geeft, maak je een values.yaml die de drie gaten van de defaults dicht: persistentie, high availability en resourcelimieten.

# values.yaml voor kube-prometheus-stack 83.4.0
prometheus:
  prometheusSpec:
    replicas: 2                    # HA: twee Prometheus-replica's
    podAntiAffinity: "hard"        # spreidt over nodes
    retention: "15d"               # standaard; expliciet is duidelijker
    externalLabels:
      cluster: prod-eu1            # identificeert dit cluster bij multi-cluster
    storageSpec:
      volumeClaimTemplate:
        spec:
          storageClassName: "standard"
          accessModes: ["ReadWriteOnce"]
          resources:
            requests:
              storage: 50Gi        # afmeting hangt af van aantal series; zie opslagsectie
    resources:
      requests:
        memory: 2Gi
        cpu: "1"
      limits:
        memory: 4Gi
        cpu: "2"

alertmanager:
  alertmanagerSpec:
    replicas: 3                    # HA: drie replica's voor quorum
    storage:
      volumeClaimTemplate:
        spec:
          storageClassName: "standard"
          accessModes: ["ReadWriteOnce"]
          resources:
            requests:
              storage: 10Gi

grafana:
  enabled: true
  persistence:
    enabled: true
    storageClassName: "standard"
    size: 10Gi
  # Commit geen wachtwoorden in plain text. Gebruik een bestaand Secret:
  # admin:
  #   existingSecret: grafana-admin-credentials
  #   userKey: admin-user
  #   passwordKey: admin-password

Installeer met het valuesbestand:

helm install kube-prom-stack prometheus-community/kube-prometheus-stack \
  --namespace monitoring --create-namespace \
  --values values.yaml

Checkpoint. Controleer na een paar minuten of de pods draaien:

kubectl get pods -n monitoring

Je zou pods moeten zien voor prometheus-kube-prom-stack-*, alertmanager-kube-prom-stack-*, kube-prom-stack-grafana-*, kube-prom-stack-kube-state-metrics-* en kube-prom-stack-prometheus-node-exporter-* in Running-staat. Staan er pods op Pending? Kijk dan of je cluster een StorageClass genaamd standard heeft en genoeg nodecapaciteit. De gids over resource requests en limits legt uit hoe requests de scheduling beinvloeden.

Wat de stack deployt

De chart installeert zes componenten. Begrijpen wat elk doet voorkomt veel verwarring later.

Prometheus Operator (v0.90.1). Een controller die Custom Resource Definitions (CRDs) als ServiceMonitor, PodMonitor en PrometheusRule in de gaten houdt. Als je een ServiceMonitor aanmaakt, genereert de Operator automatisch de bijbehorende Prometheus-scrapeconfiguratie. Je bewerkt nooit met de hand scrape_configs.

Prometheus (3.x). De timeseriesdatabase en scraper. Haalt metrics op van /metrics-endpoints met een standaardinterval van 15 seconden, slaat ze op in een lokale TSDB en evalueert alertingregels. Queries gebruik je met PromQL.

Alertmanager. Ontvangt alerts van Prometheus, dedupliceert ze, groepeert ze en routeert ze naar notificatiekanalen (Slack, PagerDuty, e-mail, webhooks). Draait een eigen gossipprotocol op poort 9094 voor statussynchronisatie tussen replica's.

Grafana (11.x). Dashboards en visualisatie. De chart wordt geleverd met kant-en-klare dashboards voor clusteroverzicht, nodegezondheid, podresources en namespaceworkloads.

kube-state-metrics (v2.18.0). Een enkele pod die de Kubernetes API-server bewaakt en de staat van Kubernetes-objecten als Prometheus-metrics beschikbaar maakt. Deployreplica-aantallen, podfasen, jobvoltooiingsstatus, nodecondities. Het meet geen resourcegebruik; het meet objectstaat.

node-exporter. Een DaemonSet (een pod per node) die host-level hardware- en OS-metrics beschikbaar maakt: CPU-gebruik, geheugengebruik, disk-I/O, filesystemcapaciteit, networkdoorvoer. Metrics gebruiken het node_-prefix en worden gescrapt op poort 9100.

En metrics-server dan?

Een veelvoorkomend misverstand: metrics-server en Prometheus doen hetzelfde. Dat klopt niet. metrics-server levert tijdelijke, in-memory CPU- en geheugensnapshots voor kubectl top, de Horizontal Pod Autoscaler (HPA) en de Vertical Pod Autoscaler (VPA). Het heeft geen querytaal, geen alerting en geen persistente opslag. Prometheus biedt de volledige observabilitystack. Een productiecluster heeft beide nodig.

Aspect metrics-server kube-state-metrics node-exporter
Databron kubelet Summary API Kubernetes API-server Linux-kernel / procfs
Wat het meet Live CPU + geheugengebruik Kubernetes-objectstaat Host-OS-hardwaremetrics
Opslag In-memory, tijdelijk In-memory (Prometheus slaat de gescrapete data op) Geen (Prometheus slaat de gescrapete data op)
Primaire consument HPA, VPA, kubectl top Prometheus Prometheus

De dashboards openen

Met de stack draaiend, gebruik je kubectl port-forward om de UI's te bereiken vanaf je werkstation.

Grafana

kubectl port-forward -n monitoring svc/kube-prom-stack-grafana 3000:80

Open http://localhost:3000. De standaardcredentials zijn admin / prom-operator. Wijzig het wachtwoord direct op elk cluster dat niet wegwerpbaar is, of beter nog, mount credentials vanuit een Kubernetes Secret.

De chart levert tientallen kant-en-klare dashboards mee. Begin met "Kubernetes / Compute Resources / Cluster" voor een overzicht op het hoogste niveau.

Prometheus UI

kubectl port-forward -n monitoring svc/kube-prom-stack-kube-prom-prometheus 9090:9090

Open http://localhost:9090. De pagina Status > Targets toont elk scrapetarget en zijn gezondheid. Dit is de eerste plek om te kijken als een metric lijkt te ontbreken.

Alertmanager

kubectl port-forward -n monitoring svc/kube-prom-stack-kube-prom-alertmanager 9093:9093

Open http://localhost:9093. Toont actieve alerts, silences en de routeringsboom.

Checkpoint. Ga in de Prometheus UI naar Status > Targets. Je zou targets moeten zien voor serviceMonitor/monitoring/kube-prom-stack-*-entries, allemaal met status "UP". Staat een target op "DOWN", noteer dan de fout. De meestvoorkomende oorzaak is een network policy of firewall die scrapeverkeer blokkeert.

Je eigen applicaties monitoren met ServiceMonitor

Prometheus scrapt je applicatieworkloads niet automatisch. Elke applicatie heeft een ServiceMonitor (of PodMonitor) CRD nodig om de Operator te vertellen wat er gescrapt moet worden.

Stap 1: maak een metricsendpoint beschikbaar

Je applicatie moet Prometheus-format metrics serveren op een HTTP-pad (standaard /metrics). De meeste talen hebben clientbibliotheken: prometheus/client_golang, prometheus/client_python, prometheus/client_java.

Stap 2: maak een Service met een benoemde poort

De ServiceMonitor verwijst naar een benoemde poort op een Kubernetes Service. Zorg dat je Service de metricspoort beschikbaar maakt:

apiVersion: v1
kind: Service
metadata:
  name: order-api
  namespace: production
  labels:
    app: order-api
spec:
  selector:
    app: order-api
  ports:
    - name: metrics         # ServiceMonitor verwijst naar deze naam
      port: 9090
      targetPort: 9090
    - name: http
      port: 8080
      targetPort: 8080

Stap 3: maak de ServiceMonitor aan

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: order-api
  namespace: production
  labels:
    release: kube-prom-stack    # moet matchen met Prometheus serviceMonitorSelector
spec:
  selector:
    matchLabels:
      app: order-api
  endpoints:
    - port: metrics             # matcht de benoemde poort op de Service
      interval: 30s
      path: /metrics

Apply het:

kubectl apply -f servicemonitor-order-api.yaml

Stap 4: controleer of het target verschijnt

In de Prometheus UI (Status > Targets) zou binnen twee minuten een nieuwe targetgroep moeten verschijnen. Gebeurt dat niet, controleer dan de labelselector (zie "Veelvoorkomende valkuilen" hieronder).

Wanneer PodMonitor gebruiken

PodMonitor scrapt pods rechtstreeks, zonder de Service-laag. Gebruik het voor workloads zonder Kubernetes Service: CronJobs, batch Jobs, DaemonSet-sidecars of eenmalige pods. Voor alles met een Service is ServiceMonitor de standaardkeuze.

Alertingregels aanmaken met PrometheusRule

De PrometheusRule CRD definieert alerting- en recordingregels als Kubernetes-resources. De Operator laadt ze automatisch in Prometheus.

apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
  name: order-api-alerts
  namespace: monitoring
  labels:
    release: kube-prom-stack     # moet matchen met Prometheus ruleSelector
spec:
  groups:
    - name: order-api.rules
      rules:
        - alert: OrderApiDown
          expr: up{job="order-api"} == 0
          for: 2m
          labels:
            severity: critical
          annotations:
            summary: "order-api instance  is onbereikbaar"

        - alert: OrderApiHighErrorRate
          expr: |
            (
              rate(http_requests_total{job="order-api", status=~"5.."}[5m])
              / rate(http_requests_total{job="order-api"}[5m])
            ) > 0.05
          for: 5m
          labels:
            severity: warning
          annotations:
            summary: "order-api 5xx-foutpercentage boven 5% gedurende 5 minuten"

        - alert: OrderApiHighMemory
          expr: |
            (container_memory_usage_bytes{container="order-api"}
            / container_spec_memory_limit_bytes{container="order-api"}) > 0.9
          for: 5m
          labels:
            severity: critical
          annotations:
            summary: "order-api pod  geheugen boven 90% van limiet"

Apply het en controleer de Prometheus UI onder Status > Rules. De regels zouden binnen een minuut moeten verschijnen.

Het for-veld is belangrijk. Het bepaalt hoe lang de conditie waar moet zijn voordat de alert afgaat. Zonder for triggert een enkele mislukte scrape al een alert. Met for: 5m moet de conditie vijf opeenvolgende minuten aanhouden.

Alerts routeren met Alertmanager

Alertmanager ontvangt afgevuurde alerts van Prometheus en routeert ze naar notificatiekanalen. Je kunt routing configureren met een Kubernetes Secret dat een raw Alertmanager-config bevat, of met de AlertmanagerConfig CRD.

De Secret-aanpak is eenvoudiger voor een enkel team. Maak een alertmanager.yaml:

global:
  resolve_timeout: 5m

route:
  receiver: "slack-default"
  group_by: ["alertname", "namespace"]
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  routes:
    - match:
        severity: critical
      receiver: "pagerduty-critical"
    - match:
        severity: warning
      receiver: "slack-warnings"

receivers:
  - name: "slack-default"
    slack_configs:
      - api_url: "https://hooks.slack.com/services/T00/B00/XXXX"
        channel: "#alerts"

  - name: "slack-warnings"
    slack_configs:
      - api_url: "https://hooks.slack.com/services/T00/B00/XXXX"
        channel: "#alerts-warnings"

  - name: "pagerduty-critical"
    pagerduty_configs:
      - service_key: "your-pagerduty-integration-key"

Sla het op als Kubernetes Secret (Alertmanager verwacht de key alertmanager.yaml):

kubectl create secret generic alertmanager-config \
  --namespace monitoring \
  --from-file=alertmanager.yaml=alertmanager.yaml

Verwijs er dan naar in je Helm-values:

alertmanager:
  alertmanagerSpec:
    alertmanagerConfiguration:
      name: alertmanager-config

Upgrade de release:

helm upgrade kube-prom-stack prometheus-community/kube-prometheus-stack \
  --namespace monitoring --values values.yaml

Checkpoint. Open de Alertmanager UI op http://localhost:9093. Ga naar Status > Config. Je routeringsboom zou zichtbaar moeten zijn. Trigger een testalert door tijdelijk een drempel in je PrometheusRule te verlagen en verifieer dat de notificatie aankomt.

Wanneer lokale Prometheus niet meer voldoet

Prometheus slaat data op in een lokale TSDB met een standaardretentie van 15 dagen. De TSDB verwerkt tot grofweg 10 miljoen actieve tijdseries voordat geheugen en querylatency verslechteren. Voor een cluster met 100 pods dat zo'n 10.000 series genereert, past 15 dagen retentie prima op 50 Gi disk. De formule: retentie_seconden x ingested_samples_per_seconde x bytes_per_sample (Prometheus comprimeert gemiddeld naar 1 tot 2 bytes per sample).

Voorbij grofweg twee weken retentie of 100 GB aan data stijgt de operationele last snel. Dat is het moment om remote storage toe te voegen.

Oplossing Architectuur Geschikt voor
Thanos Sidecar uploadt 2-uurs TSDB-blokken naar objectstorage; Store Gateway serveert historische queries Soepelste migratie vanuit bestaande Prometheus; multi-clusterfederatie
Grafana Mimir Gecentraliseerde remote-write; Grafana's opvolger van Cortex Enterprise-multitenancy, hoge cardinaliteit op schaal
VictoriaMetrics Drop-in Prometheus-compatibel remote-write-target Beste verhouding prestaties/eenvoud voor de meeste organisaties

Thanos is de meestgebruikte eerste stap omdat het als sidecar aan je bestaande Prometheus-pods hangt met grofweg 10% CPU-overhead. De sidecar uploadt voltooide TSDB-blokken elke twee uur naar een S3-compatibele bucket. Eenmaal geupload kun je de lokale retentie verkorten.

Een breaking change in Prometheus 3.x om te weten: enable_http2 in remote_write staat nu standaard op false. Als je in Prometheus 2.x HTTP/2 voor remote write gebruikte, moet je na de upgrade enable_http2: true expliciet instellen.

Veelvoorkomende valkuilen

ServiceMonitor-labelmismatch. Standaard vindt de Prometheus-instance van kube-prometheus-stack alleen ServiceMonitors met een release: <release-naam>-label. Ontbreekt dat label of heeft het de verkeerde waarde, dan negeert Prometheus het stilletjes. Controleer Status > Targets in de Prometheus UI. Om discovery ongeacht labels toe te staan, voeg dit toe aan je values.yaml:

prometheus:
  prometheusSpec:
    serviceMonitorSelectorNilUsesHelmValues: false
    podMonitorSelectorNilUsesHelmValues: false

CRDs worden niet mee-geupgraded door Helm. helm upgrade werkt Custom Resource Definitions niet bij. Voor grote chartversie-upgrades moet je handmatig de nieuwe CRD-manifests applyen uit de chartrepository.

Geen persistente opslag. Zonder PersistentVolumeClaim gaat Prometheus-data verloren bij elke podherstart. Stel storageSpec.volumeClaimTemplate altijd in voor productie.

GKE private cluster-firewall. Bij private GKE-clusters blokkeert de control-plane-firewall de Prometheus Operator-admissionwebhook op poort 8443. Open de firewallregel of zet prometheusOperator.admissionWebhooks.enabled: false in values.

kube-proxy-metrics onbereikbaar. Het standaard bind-adres van kube-proxy is 127.0.0.1:10249, onbereikbaar vanuit Prometheus. Om kube-proxy-metrics te verzamelen, wijzig het bind-adres naar 0.0.0.0:10249 in de kube-system ConfigMap.

Metrics met hoge cardinaliteit. Unieke labelcombinaties (hoge cardinaliteit) vergroten het geheugengebruik en vertragen PromQL-queries. Monitor de prometheus_tsdb_head_series-metric. Kruipt die richting 10 miljoen, bekijk dan je metrics op onbegrensde labels als user-IDs of requestpaden.

Wat je hebt geleerd

Deze tutorial behandelde het volledige pad van een leeg cluster naar een werkende observabilitystack:

  • kube-prometheus-stack installeert Prometheus, Alertmanager, Grafana, kube-state-metrics en node-exporter in een enkele Helm-release. De Prometheus Operator gebruikt CRDs om configuratie als Kubernetes-resources te beheren.
  • Applicatiemetrics worden niet automatisch gescrapt. Elke applicatie heeft een ServiceMonitor (of PodMonitor) nodig met matchende labels.
  • Alertingregels definieer je als PrometheusRule-resources. Alertmanager verzorgt routing, deduplicatie en notificatie.
  • De lokale Prometheus TSDB is ontworpen voor kortetermijnretentie (standaard 15 dagen). Voor langere historie of multi-clusteroverzichten voeg je Thanos, Mimir of VictoriaMetrics toe als remote-storage-backend.

Verder lezen

  • De gids over resource requests en limits legt uit hoe je je Prometheus-pods dimensioneert en hoe de metrics van node-exporter en kube-state-metrics verband houden met scheduling en eviction.
  • De gids over health probes behandelt het configureren van liveness- en readinessprobes, een natuurlijke aanvulling op metric-gebaseerde alerting.

Terugkerende server- of deploymentproblemen?

Ik help teams productie betrouwbaar maken met CI/CD, Kubernetes en cloud—zodat fixes blijven en deploys geen stress meer zijn.

Bekijk DevOps consultancy

Doorzoek deze site

Begin met typen om te zoeken, of blader door de kennisbank en blog.