Veröffentlicht am

Custom Metrics: Kubernetes-Autoscaling mit Prometheus

Teilen:
Authors

TL;DR

Der Horizontal Pod Autoscaler skaliert standardmäßig nur nach CPU und Memory. Mit dem Prometheus Adapter kannst du beliebige Prometheus-Metriken — etwa Requests pro Sekunde oder Queue-Länge — als Custom Metrics im HPA nutzen. So skaliert dein Cluster nach echten Business-Metriken statt nach Ressourcenverbrauch.


HPA mit Custom Metrics aus Prometheus

CPU-basiertes Autoscaling reicht oft nicht aus. Eine Anwendung kann bei 20% CPU-Auslastung bereits überlastet sein, wenn die Request-Latenz steigt. Custom Metrics lösen dieses Problem: Du definierst selbst, welche Metrik die Skalierung steuert.

Architektur-Überblick

Der Weg von Prometheus zum HPA hat drei Stationen:

  1. Prometheus sammelt Metriken von deinen Pods
  2. Prometheus Adapter übersetzt diese in die Kubernetes Custom Metrics API
  3. HPA fragt die Custom Metrics API ab und skaliert
PodServiceMonitorPrometheusPrometheus AdapterCustom Metrics APIHPA

Voraussetzungen

  • Kubernetes-Cluster (ab v1.23)
  • Prometheus im Cluster (z.B. via kube-prometheus-stack)
  • kubectl und helm konfiguriert

Prüfe, ob Prometheus läuft:

kubectl get pods -n monitoring -l app.kubernetes.io/name=prometheus

Beispiel-Anwendung deployen

Für dieses Tutorial nutzen wir eine einfache Go-App, die einen /metrics-Endpunkt mit http_requests_total exponiert:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-app
  namespace: default
  labels:
    app: sample-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: sample-app
  template:
    metadata:
      labels:
        app: sample-app
      annotations:
        prometheus.io/scrape: "true"
        prometheus.io/port: "8080"
    spec:
      containers:
        - name: app
          image: registry.example.com/sample-app:v1
          ports:
            - containerPort: 8080
          resources:
            requests:
              cpu: 100m
              memory: 64Mi
---
apiVersion: v1
kind: Service
metadata:
  name: sample-app
  labels:
    app: sample-app
spec:
  selector:
    app: sample-app
  ports:
    - port: 80
      targetPort: 8080

ServiceMonitor einrichten

Damit Prometheus die Metriken scrapet, brauchen wir einen ServiceMonitor:

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: sample-app
  namespace: monitoring
  labels:
    release: kube-prometheus-stack
spec:
  namespaceSelector:
    matchNames:
      - default
  selector:
    matchLabels:
      app: sample-app
  endpoints:
    - port: "8080"
      interval: 15s
      path: /metrics

Verifiziere in der Prometheus-UI, dass die Metrik http_requests_total auftaucht.

Prometheus Adapter installieren

Der Adapter registriert sich als API-Server für custom.metrics.k8s.io und beantwortet Anfragen, indem er PromQL-Queries gegen Prometheus ausführt.

helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update

helm install prometheus-adapter prometheus-community/prometheus-adapter \
  --namespace monitoring \
  --set prometheus.url=http://kube-prometheus-stack-prometheus.monitoring.svc \
  --set prometheus.port=9090

Nach wenigen Sekunden sollte die Custom Metrics API verfügbar sein:

kubectl get apiservice v1beta1.custom.metrics.k8s.io
# STATUS sollte "True" sein

Custom Metrics konfigurieren

Die zentrale Konfiguration passiert in der ConfigMap des Adapters. Hier definierst du, welche Prometheus-Metriken als Custom Metrics exponiert werden.

Erstelle eine values.yaml für den Adapter:

rules:
  custom:
    - seriesQuery: 'http_requests_total{namespace!="",pod!=""}'
      resources:
        overrides:
          namespace:
            resource: namespace
          pod:
            resource: pod
      name:
        matches: "^(.*)_total$"
        as: "${1}_per_second"
      metricsQuery: 'rate(<<.Series>>{<<.LabelMatchers>>}[2m])'
FeldBedeutung
seriesQueryPrometheus-Serie, die als Quelle dient
resources.overridesMapping von Labels auf Kubernetes-Ressourcen
name.asName der Custom Metric in der API
metricsQueryPromQL-Query, die bei Abruf ausgeführt wird

Upgrade den Adapter mit der neuen Config:

helm upgrade prometheus-adapter prometheus-community/prometheus-adapter \
  --namespace monitoring \
  -f values.yaml

Teste, ob die Metrik registriert ist:

kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1/namespaces/default/pods/*/http_requests_per_second" | jq .

Die Ausgabe sollte die aktuelle Rate pro Pod zeigen.

HPA mit Custom Metric erstellen

Jetzt kommt der entscheidende Teil — der HPA, der nach http_requests_per_second skaliert:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: sample-app-hpa
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: sample-app
  minReplicas: 2
  maxReplicas: 10
  metrics:
    - type: Pods
      pods:
        metric:
          name: http_requests_per_second
        target:
          type: AverageValue
          averageValue: "50"
  behavior:
    scaleDown:
      stabilizationWindowSeconds: 300
      policies:
        - type: Percent
          value: 25
          periodSeconds: 60
    scaleUp:
      stabilizationWindowSeconds: 30
      policies:
        - type: Percent
          value: 100
          periodSeconds: 30

Dieses HPA skaliert hoch, wenn der Durchschnitt über 50 Requests/Sekunde pro Pod liegt. Das Scale-Down ist konservativ konfiguriert: maximal 25% der Pods pro Minute, mit 5 Minuten Stabilisierung.

kubectl apply -f hpa.yaml
kubectl get hpa sample-app-hpa -w

Lasttests durchführen

Generiere Last, um das Autoscaling zu testen:

# Mit kubectl run einen Load-Generator starten
kubectl run load-generator --image=busybox --restart=Never -- \
  /bin/sh -c "while true; do wget -q -O- http://sample-app.default.svc; done"

# HPA beobachten
kubectl get hpa sample-app-hpa -w

Nach 30-60 Sekunden sollte der HPA die Replica-Anzahl erhöhen. Stoppe den Load-Generator mit kubectl delete pod load-generator und beobachte das Scale-Down nach der Stabilisierungsphase.

Mehrere Metriken kombinieren

Ein HPA kann mehrere Metriken gleichzeitig verwenden. Der höchste errechnete Replica-Wert gewinnt:

spec:
  metrics:
    - type: Pods
      pods:
        metric:
          name: http_requests_per_second
        target:
          type: AverageValue
          averageValue: "50"
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 70

So hast du ein Sicherheitsnetz: Selbst wenn die Custom Metric keine Skalierung auslöst, greift CPU-basiertes Scaling als Fallback.

Troubleshooting

HPA zeigt <unknown> bei der Metrik:

# Prüfe ob der Adapter die Metrik kennt
kubectl get --raw "/apis/custom.metrics.k8s.io/v1beta1" | jq '.resources[].name'

# Adapter-Logs prüfen
kubectl logs -n monitoring deployment/prometheus-adapter

Metrik hat den Wert 0:

Stelle sicher, dass Prometheus tatsächlich Daten für die Serie hat. Öffne die Prometheus-UI und teste die PromQL-Query manuell.

FAQ

Welche Metriken eignen sich für Custom Metrics Autoscaling?

Am besten eignen sich Metriken, die direkt mit der Last korrelieren: Requests pro Sekunde, Queue-Länge, aktive Verbindungen oder Kafka-Consumer-Lag. CPU und Memory sind oft nachlaufende Indikatoren.

Kann ich External Metrics statt Custom Metrics verwenden?

Ja, External Metrics (external.metrics.k8s.io) sind für Metriken gedacht, die nicht an einen Pod gebunden sind — etwa eine SQS-Queue-Länge oder Cloud-Monitoring-Werte. Der Prometheus Adapter unterstützt auch External Metrics.

Wie schnell reagiert der HPA auf Metrikänderungen?

Der HPA prüft standardmäßig alle 15 Sekunden (konfigurierbar via --horizontal-pod-autoscaler-sync-period). Mit dem behavior-Block im HPA steuerst du zusätzlich Scale-Up- und Scale-Down-Geschwindigkeit.

Was passiert, wenn der Prometheus Adapter ausfällt?

Der HPA kann keine Metriken mehr abrufen und zeigt <unknown>. Die aktuelle Replica-Anzahl bleibt bestehen — der HPA skaliert weder hoch noch runter. Überwache den Adapter deshalb mit einem eigenen Alert.


Kubernetes-Expertise gesucht?

Managed Services, Beratung, Training oder Security – wir unterstützen deutsche Unternehmen bei allen Kubernetes-Themen.

Kubernetes-Beratung gesucht?

Wir helfen deutschen Unternehmen bei der Kubernetes-Implementierung, Migration und Optimierung. DSGVO-konform und praxiserprobt.

📖 Verwandte Artikel

Weitere interessante Beiträge zu ähnlichen Themen