Ein praktischer Leitfaden zur Optimierung des Kubernetes Horizontal Pod Autoscalers (HPA)

Erschließen Sie optimale Anwendungsleistung und Kosteneffizienz mit diesem praktischen Leitfaden zur Optimierung des Kubernetes Horizontal Pod Autoscalers (HPA). Lernen Sie, HPA mithilfe von CPU-, benutzerdefinierten und externen Metriken zu konfigurieren und fortgeschrittene Skalierungsverhalten mit `stabilizationWindowSeconds` und `policies` zu beherrschen. Dieser Artikel liefert umsetzbare Schritte, Codebeispiele und Best Practices, um sicherzustellen, dass Ihre Kubernetes-Deployments sich dynamisch an schwankende Lasten anpassen, Ressourcen-Überprovisionierung verhindern und eine hohe Verfügbarkeit gewährleisten.

27 Aufrufe

Ein praktischer Leitfaden zur Abstimmung des Kubernetes Horizontal Pod Autoscaler (HPA)

Kubernetes hat die Bereitstellung, Verwaltung und Skalierung von Anwendungen revolutioniert. Das Herzstück der Skalierungsfunktionen ist der Horizontal Pod Autoscaler (HPA), ein leistungsstarkes Werkzeug, das die Anzahl der Pod-Replikate in einer Bereitstellung, einem Replikationscontroller, einem ReplicaSet oder einem StatefulSet basierend auf der beobachteten CPU-Auslastung oder anderen ausgewählten Metriken automatisch anpasst. Obwohl HPA immense Vorteile für die Bewältigung schwankender Lasten bietet, wird sein wahres Potenzial durch sorgfältige Konfiguration und Abstimmung erschlossen.

Dieser Leitfaden beleuchtet die praktischen Aspekte der Konfiguration und Optimierung des Kubernetes Horizontal Pod Autoscalers. Wir behandeln grundlegende Konzepte, Kernparameter, fortgeschrittene Abstimmungsstrategien und Best Practices, um sicherzustellen, dass sich Ihre Anwendungen effizient an die Nachfrage anpassen, die Leistung bei unterschiedlichen Lasten aufrechterhalten und die Infrastrukturkosten optimieren können. Am Ende dieses Artikels werden Sie ein solides Verständnis davon haben, wie Sie den HPA optimal nutzen können.

Den Horizontal Pod Autoscaler (HPA) verstehen

Der HPA skaliert die Anzahl der Pods Ihrer Anwendung automatisch nach oben oder unten, um der aktuellen Nachfrage gerecht zu werden. Er überwacht kontinuierlich festgelegte Metriken und vergleicht diese mit Zielwerten. Wenn die beobachtete Metrik das Ziel überschreitet, leitet der HPA ein Scale-up-Ereignis ein; wenn sie darunter fällt, löst er ein Scale-down aus. Diese dynamische Anpassung stellt sicher, dass Ihre Anwendung genügend Ressourcen für eine optimale Leistung hat, ohne überdimensioniert zu sein.

HPA kann basierend auf folgenden Metriken skalieren:

  • Ressourcenmetriken: Hauptsächlich CPU-Auslastung und Speicherauslastung (verfügbar über die metrics.k8s.io-API, die normalerweise vom Kubernetes Metrics Server bereitgestellt wird).
  • Benutzerdefinierte Metriken: Anwendungsspezifische Metriken, die über die custom.metrics.k8s.io-API verfügbar gemacht werden (z. B. Anfragen pro Sekunde, Warteschlangentiefe, aktive Verbindungen). Diese erfordern typischerweise einen Adapter wie prometheus-adapter.
  • Externe Metriken: Metriken von Quellen außerhalb des Clusters, die über die external.metrics.k8s.io-API verfügbar gemacht werden (z. B. Google Cloud Pub/Sub-Warteschlangengröße, AWS SQS-Warteschlangenlänge). Diese erfordern ebenfalls einen benutzerdefinierten Metriken-API-Server, der externe Metriken abrufen kann.

Voraussetzungen für eine effektive HPA-Abstimmung

Bevor wir uns mit den HPA-Konfigurationen befassen, stellen Sie sicher, dass diese grundlegenden Elemente vorhanden sind:

1. Präzise Ressourcenanforderungen und -limits definieren

Dies ist wohl die wichtigste Voraussetzung. Der HPA ist stark auf korrekt definierte CPU- und Speicher-Anforderungen (requests) angewiesen, um Nutzungsprozentsätze zu berechnen. Wenn ein Pod keine CPU-Anforderungen definiert hat, kann der HPA seine CPU-Auslastung nicht berechnen, was eine CPU-basierte Skalierung unmöglich macht.

  • Anforderungen (Requests): Definieren Sie die minimal garantierten Ressourcen für Ihre Container. Der HPA verwendet diese Werte, um die Zielauslastung pro Pod zu bestimmen.
  • Limits: Definieren Sie die maximalen Ressourcen, die ein Container verbrauchen kann. Limits verhindern, dass ein einzelner Pod übermäßige Ressourcen verbraucht und andere Pods auf demselben Knoten beeinträchtigt.
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-container
        image: my-image:latest
        resources:
          requests:
            cpu: "200m"  # 20% eines CPU-Kerns
            memory: "256Mi"
          limits:
            cpu: "500m"
            memory: "512Mi"

2. Kubernetes Metrics Server installieren

Damit der HPA CPU- und Speicherauslastungsmetriken verwenden kann, muss der Kubernetes Metrics Server in Ihrem Cluster installiert sein. Er sammelt Ressourcenmetriken von Kubelets und stellt sie über die metrics.k8s.io-API bereit.

3. Anwendungsobservability

Für benutzerdefinierte oder externe Metriken muss Ihre Anwendung die relevanten Metriken exponieren (z. B. über einen Prometheus-Endpunkt). Außerdem benötigen Sie eine Möglichkeit, diese Metriken zu sammeln und der Kubernetes-API zur Verfügung zu stellen, typischerweise unter Verwendung eines Prometheus-Adapters oder eines benutzerdefinierten Metriken-API-Servers.

HPA konfigurieren: Kernparameter

Schauen wir uns die grundlegende Struktur eines HPA-Manifests an:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: my-app-hpa
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

Schlüsselparameter:

  • scaleTargetRef: Definiert die Zielressource (z. B. Deployment), die der HPA skalieren soll. Geben Sie deren apiVersion, kind und name an.
  • minReplicas: Die minimale Anzahl von Pods, auf die der HPA herunterskaliert. Es ist gute Praxis, diesen Wert selbst bei Null-Last mindestens auf 1 oder 2 für hohe Verfügbarkeit festzulegen.
  • maxReplicas: Die maximale Anzahl von Pods, auf die der HPA hochskaliert. Dies dient als Schutz vor außer Kontrolle geratener Skalierung und begrenzt die Kosten.
  • metrics: Ein Array, das die Metriken definiert, die der HPA überwachen soll.
    • type: Kann Resource, Pods, Object oder External sein.
    • resource.name: Gibt bei Typ Resource cpu oder memory an.
    • target.type: Bei Typ Resource entweder Utilization (Prozentsatz der angeforderten Ressource) oder AverageValue (absoluter Wert).
    • averageUtilization: Bei Typ Utilization der Zielprozentsatz. Der HPA berechnet die gewünschte Anzahl von Pods basierend auf current_utilization / target_utilization * current_pods_count.

HPA für Reaktionsfähigkeit und Stabilität abstimmen

Über die grundlegende Konfiguration hinaus bietet der HPA erweiterte Abstimmungsoptionen, insbesondere mit autoscaling/v2 (oder v2beta2 in älteren Versionen), um das Skalierungsverhalten granularer zu steuern.

1. CPU- und Speicherkennzahlen (averageUtilization / averageValue)

Die Festlegung der richtigen Zielauslastung ist entscheidend. Ein niedrigerer Zielwert bedeutet eine frühere Skalierung (reaktionsschneller, potenziell kostspieliger), während ein höherer Zielwert eine spätere Skalierung bedeutet (weniger reaktionsschnell, potenziell günstiger, birgt aber das Risiko einer Leistungsverschlechterung).

  • Ermittlung optimaler Ziele: Lasttests und Profiling sind Ihre besten Freunde. Erhöhen Sie schrittweise die Last auf Ihre Anwendung und überwachen Sie dabei die Ressourcennutzung und Leistungsmetriken (Latenz, Fehlerraten). Ermitteln Sie die CPU-/Speicherauslastung, bei der Ihre Anwendung beginnt, Leistungseinbußen zu zeigen. Setzen Sie Ihr HPA-Ziel unterhalb dieser Schwelle an, typischerweise im Bereich von 60–80 % für die CPU.
  • Abwägung: Streben Sie ein Ziel an, das genügend Puffer für unerwartete Spitzen lässt, aber nicht so niedrig ist, dass Sie ständig überdimensioniert sind.

2. Skalierungsverhalten (Feld behavior)

Das Feld behavior, eingeführt in HPA autoscaling/v2, bietet eine detaillierte Steuerung über Scale-up- und Scale-down-Ereignisse und verhindert "Thrashing" (schnelle Skalierungszyklen nach oben und unten).

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: my-app-hpa
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  minReplicas: 2
  maxReplicas: 10
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  behavior:
    scaleUp:
      stabilizationWindowSeconds: 60 # 60s warten, bevor erneut hochskaliert wird
      policies:
      - type: Pods
        value: 4
        periodSeconds: 15 # Max. 4 Pods alle 15 Sekunden hinzufügen
      - type: Percent
        value: 100
        periodSeconds: 15 # Oder die aktuelle Pod-Anzahl verdoppeln alle 15 Sekunden (je nachdem, was weniger restriktiv ist)
    scaleDown:
      stabilizationWindowSeconds: 300 # 5 Minuten warten, bevor herunterskaliert wird
      policies:
      - type: Percent
        value: 50
        periodSeconds: 60 # Max. 50% der Pods alle 60 Sekunden entfernen
      selectPolicy: Max # Die Richtlinie auswählen, die das 'aggressivste' (geringste Anzahl von) Pods zulässt

scaleUp-Konfiguration:

  • stabilizationWindowSeconds: Verhindert schnelle Skalierungszyklen (Flapping). Der HPA berücksichtigt Metriken aus diesem Fenster beim Hochskalieren, um sicherzustellen, dass nur dann hochskaliert wird, wenn die höhere Metrik bestehen bleibt. Ein typischer Wert liegt bei 30–60 Sekunden.
  • policies: Definiert, wie Pods während eines Scale-up-Ereignisses hinzugefügt werden. Sie können mehrere Richtlinien definieren, und der HPA verwendet diejenige, die die höchste Anzahl von Pods zulässt (aggressivstes Scale-up).
    • type: Pods: Skaliert um eine feste Anzahl von Pods hoch. value gibt die hinzuzufügende Anzahl von Pods an. periodSeconds definiert das Zeitfenster, über das diese Richtlinie gilt.
    • type: Percent: Skaliert um einen Prozentsatz der aktuellen Pod-Anzahl hoch. value ist der Prozentsatz.

scaleDown-Konfiguration:

  • stabilizationWindowSeconds: Dies ist für scaleDown noch wichtiger. Es gibt an, wie lange der HPA Metriken unterhalb des Ziels beobachten muss, bevor er ein Herunterskalieren in Betracht zieht. Ein längeres Fenster (z. B. 300–600 Sekunden) verhindert ein vorzeitiges Herunterskalieren bei vorübergehenden Tiefpunkten und vermeidet "Kaltstarts" und Leistungsabfälle. Dies ist eine entscheidende Einstellung für stabile Umgebungen.
  • policies: Ähnlich wie bei scaleUp definiert dies, wie Pods entfernt werden. Der HPA verwendet die Richtlinie, die zur niedrigsten Anzahl von Pods führt (aggressivstes Scale-down), wenn selectPolicy auf Min gesetzt ist, oder die Richtlinie, die zur höchsten Anzahl von Pods führt, wenn selectPolicy auf Max gesetzt ist.
    • type: Pods: Entfernt eine feste Anzahl von Pods.
    • type: Percent: Entfernt einen Prozentsatz der aktuellen Pods.
  • selectPolicy: Bestimmt, welche Richtlinie angewendet wird, wenn mehrere scaleDown-Richtlinien definiert sind. Min ist der Standard und wird im Allgemeinen für ein konservativeres Herunterskalieren empfohlen; Max würde die Richtlinie auswählen, die zur größten Anzahl von Pods führt (am wenigsten aggressives Herunterskalieren).

  • Warnung: Seien Sie vorsichtig bei aggressiven scaleDown-Richtlinien oder kurzen stabilizationWindowSeconds für scaleDown. Wenn Ihre Anwendung lange Initialisierungszeiten hat oder zustandsbehaftete Verbindungen verarbeitet, kann eine schnelle Herunterskalierung zu Dienstunterbrechungen oder erhöhter Latenz für Benutzer führen.

Erweiterte HPA-Metriken und Strategien

Obwohl CPU und Speicher üblich sind, skalieren viele Anwendungen besser anhand benutzerdefinierter oder externer Metriken, die ihre tatsächliche Arbeitslast widerspiegeln.

1. Benutzerdefinierte Metriken

Verwenden Sie benutzerdefinierte Metriken, wenn CPU/Speicher kein direkter Indikator für die Last oder den Leistungsengpass Ihrer Anwendung ist. Beispiele: HTTP-Anfragen pro Sekunde (QPS), aktive Verbindungen, Länge der Nachrichtenwarteschlange, Stapelverarbeitungs-Backlog.

Verwendung benutzerdefinierter Metriken:
1. Ihre Anwendung muss diese Metriken verfügbar machen (z. B. über einen Prometheus-Exporter).
2. Stellen Sie einen benutzerdefinierten Metriken-Adapter (z. B. prometheus-adapter) bereit, der diese Metriken abrufen und über die custom.metrics.k8s.io-API verfügbar machen kann.

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: my-app-hpa-qps
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-app
  minReplicas: 2
  maxReplicas: 15
  metrics:
  - type: Pods # Oder Object, wenn die Metrik für die Bereitstellung als Ganzes gilt
    pods:
      metric:
        name: http_requests_per_second # Der Name der von Ihrer Anwendung/Ihrem Adapter exponierten Metrik
      target:
        type: AverageValue
        averageValue: "10k" # Ziel: 10.000 Anfragen pro Sekunde pro Pod

2. Externe Metriken

Externe Metriken sind nützlich, wenn die Arbeitslast Ihrer Anwendung von einem externen System gesteuert wird, das nicht direkt auf Kubernetes läuft. Beispiele: AWS SQS-Warteschlangentiefe, Kafka-Topic-Lag, Pub/Sub-Abonnement-Backlog.

Verwendung externer Metriken:
1. Sie benötigen einen benutzerdefinierten Metriken-API-Server, der Metriken aus Ihrem externen System abrufen kann (z. B. einen speziellen Adapter für AWS CloudWatch oder GCP Monitoring).

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: my-worker-hpa-sqs
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: my-worker
  minReplicas: 1
  maxReplicas: 20
  metrics:
  - type: External
    external:
      metric:
        name: aws_sqs_queue_messages_visible # Metrikname aus Ihrer externen Quelle
        selector:
          matchLabels:
            queue: my-queue-name
      target:
        type: AverageValue
        averageValue: "100" # Ziel: 100 sichtbare Nachrichten in der Warteschlange pro Pod

3. Mehrere Metriken

HPA kann so konfiguriert werden, dass er mehrere Metriken gleichzeitig überwacht. Wenn mehrere Metriken angegeben sind, berechnet der HPA die gewünschte Replikatanzahl für jede Metrik unabhängig voneinander und wählt dann die höchste dieser gewünschten Replikatanzahlen. Dies stellt sicher, dass die Anwendung für alle beobachteten Lastdimensionen ausreichend skaliert wird.

# ... (HPA-Basisstruktur)
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70
  - type: Pods
    pods:
      metric:
        name: http_requests_per_second
      target:
        type: AverageValue
        averageValue: "10k"

Überwachung und Validierung

Die effektive HPA-Abstimmung ist ein iterativer Prozess, der kontinuierliche Überwachung und Validierung erfordert:

  • HPA-Ereignisse beobachten: Verwenden Sie kubectl describe hpa <hpa-name>, um den Status, die Ereignisse und die Skalierungsentscheidungen des HPA anzuzeigen. Dies liefert wertvolle Einblicke, warum der HPA hoch- oder herunterskaliert hat.
  • Metriken und Replikate überwachen: Verwenden Sie Ihren Observability-Stack (z. B. Prometheus, Grafana), um die Ressourcennutzung Ihrer Anwendung (CPU, Speicher), benutzerdefinierte/externe Metriken und die tatsächliche Anzahl der Pod-Replikate im Zeitverlauf zu visualisieren. Korrelieren Sie diese mit Änderungen der eingehenden Last.
  • Lasttests: Simulieren Sie erwartete und Spitzenlasten, um die Reaktionsfähigkeit des HPA zu validieren und sicherzustellen, dass Ihre Anwendung unter Belastung wie erwartet funktioniert. Passen Sie die HPA-Parameter basierend auf diesen Tests an.

Best Practices für die HPA-Abstimmung

  • Beginnen Sie mit klar definierten Ressourcenanforderungen/Grenzwerten: Sie sind die Grundlage für eine genaue, ressourcenbasierte HPA-Steuerung. Ohne sie kann der HPA für CPU/Speicher nicht effektiv funktionieren.
  • Realistische minReplicas und maxReplicas festlegen: minReplicas bietet eine Basislinie für die Verfügbarkeit, während maxReplicas als Sicherheitsnetz gegen außer Kontrolle geratene Kosten und Ressourcenerschöpfung dient.
  • Zielauslastung schrittweise anpassen: Beginnen Sie mit einem etwas konservativeren CPU-Ziel (z. B. 60–70 %) und iterieren Sie. Zielen Sie nicht auf 100 % Auslastung, da dies keinen Puffer für Latenz oder Verarbeitungssprünge lässt.
  • stabilizationWindowSeconds nutzen: Wesentlich, um schnelle Skalierungsschwankungen zu verhindern. Verwenden Sie für scaleDown ein längeres Fenster (z. B. 5–10 Minuten) als für scaleUp (z. B. 1–2 Minuten), um die Stabilität zu gewährleisten.
  • Anwendungsspezifische Metriken priorisieren: Wenn CPU oder Speicher nicht direkt mit den Leistungshindernissen Ihrer Anwendung korrelieren, verwenden Sie benutzerdefinierte oder externe Metriken für eine genauere und effizientere Skalierung.
  • Überwachen, Testen, Iterieren: Die HPA-Abstimmung ist keine einmalige Einrichtung. Das Verhalten der Anwendung, Verkehrsmuster und die zugrunde liegende Infrastruktur können sich ändern. Überprüfen Sie regelmäßig die HPA-Leistung und passen Sie die Einstellungen bei Bedarf an.
  • Die Skalierungseigenschaften Ihrer Anwendung verstehen: Skaliert sie linear mit Anfragen? Hat sie lange Startzeiten? Ist sie zustandsbehaftet? Diese Eigenschaften beeinflussen Ihre HPA-Strategie.

Fazit

Der Kubernetes Horizontal Pod Autoscaler ist eine entscheidende Komponente für die Erstellung widerstandsfähiger, kosteneffizienter und leistungsstarker Anwendungen in einer Kubernetes-Umgebung. Indem Sie seine Kernmechanismen verstehen, genaue Ressourcenanforderungen definieren und seine Parameter zur Verhaltenssteuerung sorgfältig abstimmen, können Sie sicherstellen, dass sich Ihre Anwendungen präzise automatisch an unterschiedliche Lasten anpassen.

Die effektive HPA-Abstimmung ist eine fortlaufende Reise aus Messung, Beobachtung und Anpassung. Nehmen Sie den iterativen Prozess an, nutzen Sie bei Bedarf erweiterte Metriken und überwachen Sie kontinuierlich die Leistung Ihrer Anwendung, um das volle Potenzial der dynamischen Skalierung innerhalb von Kubernetes auszuschöpfen.