Kubernetes Performance Monitoring: Tools und Techniken zur Optimierung

Überwachen Sie die Kubernetes-Leistung mit nützlichen Metriken, Prometheus, Grafana, kubectl und praktischen Ressourcenoptimierungsgewohnheiten.

Kubernetes Performance Monitoring: Tools und Techniken zur Optimierung

Kubernetes Performance Monitoring bedeutet nicht nur das Beobachten von CPU-Diagrammen. Ein Cluster kann eine niedrige durchschnittliche CPU-Auslastung aufweisen, während Benutzer langsame Anfragen erleben. Ein Pod kann den größten Teil des Tages genug Speicher haben und trotzdem während eines Batch-Jobs getötet werden. Ein Node kann gesund aussehen, bis der Festplattendruck beginnt, Pods zu evakuieren. Gutes Monitoring verbindet Clustersignale mit der Erfahrung, die Menschen tatsächlich interessiert: Ist der Dienst schnell, verfügbar und vorhersagbar?

Der erste Fehler ist, mit Tools statt mit Fragen zu beginnen. Prometheus, Grafana, metrics-server, kube-state-metrics und Cloud-Überwachungsplattformen sind alle nützlich, aber sie entscheiden nicht, was wichtig ist. Das entscheiden Sie, indem Sie die Arbeitslast verstehen. Eine öffentliche API kümmert sich um Latenz und Fehler. Ein Queue-Worker kümmert sich um Rückstand und Verarbeitungsrate. Ein nächtlicher Job kümmert sich um die Fertigstellungszeit und fehlgeschlagene Pods. Eine datenbankähnliche Arbeitslast kümmert sich um Festplattenlatenz und Speicherdruck.

Für einen schnellen Blick ist kubectl top immer noch nützlich:

kubectl top nodes
kubectl top pods -A
kubectl top pod -n production api-7d9c8f7b9d-2x4mq --containers

Diese Befehle hängen von metrics-server ab. Sie geben aktuelle CPU- und Speichernutzung, aber keine vollständige Historie. Verwenden Sie sie während der Triage, nicht als Ihr einziges Überwachungssystem. Wenn ein Pod vor zehn Minuten neu gestartet wurde, weil ihm der Speicher ausgegangen ist, zeigt kubectl top möglicherweise nicht den Spike, der ihn verursacht hat.

Prometheus ist die gemeinsame Grundlage für Kubernetes-Metriken, weil es Zeitreihendaten abruft und gut mit der Kubernetes-Serviceerkennung funktioniert. In einem typischen Setup stammen Metriken aus mehreren Quellen. Der Kubelet stellt Container- und Pod-Ressourcenmetriken bereit. cAdvisor, integriert in Kubelet, liefert Container-CPU-, Speicher-, Dateisystem- und Netzwerkdaten. node-exporter meldet Host-Level-Metriken. kube-state-metrics wandelt den Kubernetes-Objektzustand in Metriken um: gewünschte Replikate, verfügbare Replikate, Pod-Phasen, Node-Bedingungen und mehr.

Grafana verwandelt diese Metriken dann in Dashboards. Ein gutes Dashboard ist keine Wand voller Messgeräte. Es sollte bestimmte Fragen schnell beantworten: Welcher Dienst ist langsam, welche Pods werden gedrosselt, welche Nodes stehen unter Druck, welches Deployment kann nicht ausgerollt werden und ob die automatische Skalierung mithält.

Beginnen Sie auf der Anwendungsebene. Für benutzerorientierte Dienste sind die wichtigsten Signale die Anforderungsrate, die Fehlerrate und die Latenz. Wenn Sie SLOs haben, stellen Sie sie grafisch dar. Ein Pod-CPU-Diagramm sagt Ihnen nicht, ob der Checkout fehlschlägt. Anwendungsmetriken tun das. Instrumentieren Sie Dienste mit Prometheus-Client-Bibliotheken, OpenTelemetry oder dem Überwachungssystem, das Ihre Plattform bereits verwendet. Kubernetes-Metriken erklären, warum der Dienst nicht gesund ist; Anwendungsmetriken sagen Ihnen, dass er nicht gesund ist.

Verbinden Sie dann Anwendungssymptome mit Pod-Ressourcen. Die CPU-Auslastung ist in Kubernetes leicht falsch zu interpretieren. Ein Container mit einem CPU-Limit kann gedrosselt werden, selbst wenn die durchschnittliche CPU-Auslastung nicht dramatisch aussieht. Die Drosselung tritt auf, wenn der Container versucht, mehr CPU-Zeit zu verwenden, als sein Limit im Planungszeitraum erlaubt. Bei latenzempfindlichen Apps kann dies zu langsamen Anfragen führen, die zufällig erscheinen.

Eine nützliche PromQL-Abfrage für die Drosselung ist:

rate(container_cpu_cfs_throttled_periods_total{namespace="production", container!=""}[5m])

Ein steigender Wert bedeutet, dass der Container gedrosselt wird. Kombinieren Sie ihn mit CPU-Auslastung und Anforderungslatenz. Wenn Latenzspitzen mit der Drosselung zusammenfallen, erwägen Sie, das CPU-Limit zu erhöhen oder zu entfernen, die Replikate zu erhöhen oder den Codepfad zu optimieren. Einige Teams setzen CPU-Anfragen, vermeiden aber CPU-Limits für latenzempfindliche Dienste und verlassen sich stattdessen auf Anfragen, automatische Skalierung und Node-Kapazitätskontrollen. Das kann sinnvoll sein, erfordert aber Disziplin auf Clusterebene, damit laute Arbeitslasten andere nicht aushungern.

Speicher verhält sich anders. CPU kann gedrosselt werden; Speicher kann nicht auf die gleiche Weise verlangsamt werden. Wenn ein Container sein Speicherlimit überschreitet, kann er OOMKilled werden. Suchen Sie nach Neustartgründen:

kubectl describe pod -n production api-7d9c8f7b9d-2x4mq
kubectl get pod -n production api-7d9c8f7b9d-2x4mq -o jsonpath='{.status.containerStatuses[*].lastState}'

In Prometheus überwachen Sie den Working-Set-Speicher und vergleichen ihn mit Limits:

container_memory_working_set_bytes{namespace="production", container!=""}

Stimmen Sie den Speicher nicht von einer einzigen ruhigen Stunde ab. Betrachten Sie Spitzenverkehr, Batch-Fenster, Bereitstellungen und Garbage-Collection-Verhalten. Java-, Go-, Node.js- und Python-Dienste haben unterschiedliche Speicherprofile. Ein Limit, das während des normalen Verkehrs großzügig aussieht, kann während des Starts, des Cache-Warmups oder einer großen Anfrage zu eng sein.

Ressourcenanfragen sind wichtig, weil der Scheduler sie verwendet, um Pods zu platzieren. Wenn die Anfragen zu niedrig sind, kann Kubernetes zu viele ausgelastete Pods auf denselben Node packen. Alles sieht effizient aus, bis diese Pods gleichzeitig ausgelastet werden. Wenn die Anfragen zu hoch sind, verschwendet der Cluster Kapazität und die automatische Skalierung kann Nodes früher als nötig hinzufügen. Die beste Anfrage basiert normalerweise auf der beobachteten Nutzung plus Spielraum, nicht auf einem kopierten Wert von einem anderen Dienst.

Der Vertical Pod Autoscaler kann helfen, indem er Anfragen aus der historischen Nutzung empfiehlt. Viele Teams führen VPA zuerst im Empfehlungsmodus aus, da automatische Aktualisierungen Pods je nach Konfiguration und Arbeitslasttyp neu starten können. Behandeln Sie Empfehlungen als Input, nicht als Gesetz. Ein Dienst mit seltenen, aber wichtigen Spitzen benötigt möglicherweise mehr Spielraum, als seine durchschnittliche Historie vermuten lässt.

Der Horizontal Pod Autoscaler ist nützlich, wenn mehr Replikate tatsächlich den Durchsatz verbessern. Er funktioniert gut für zustandslose Webdienste und Worker, die Last teilen können. Er behebt keinen Single-Thread-Engpass, eine Datenbanksperre oder eine nachgelagerte Abhängigkeit, die bereits gesättigt ist.

Ein grundlegender HPA könnte so aussehen:

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: api
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: api
  minReplicas: 3
  maxReplicas: 20
  metrics:
  - type: Resource
    resource:
      name: cpu
      target:
        type: Utilization
        averageUtilization: 70

Überwachen Sie das HPA-Verhalten, nicht nur die Replikatanzahl. Wenn es ständig hoch- und herunterskaliert, passen Sie Stabilisierungsfenster, Ziele oder die Metrik an. Wenn es maxReplicas erreicht und die Latenz immer noch schlecht ist, liegt das Problem möglicherweise an der Kapazität, am Code oder an einer Abhängigkeit. Wenn es nie skaliert, während Pods eindeutig überlastet sind, überprüfen Sie die Metrikverfügbarkeit und ob Anfragen gesetzt sind. CPU-Auslastungsziele hängen von CPU-Anfragen ab; fehlende oder unrealistische Anfragen können die automatische Skalierung irreführend machen.

Die Node-Gesundheit ist die nächste Ebene. Ein Pod-Problem, das auf vielen Diensten auf einem Node auftritt, ist normalerweise ein Node-Problem. Überwachen Sie CPU-Sättigung, Lastdurchschnitt, verfügbaren Speicher, Festplattendruck, Inode-Nutzung, Dateisystemlatenz, Netzwerkfehler und Kubelet-Gesundheit. Node-Bedingungen wie MemoryPressure, DiskPressure und PIDPressure sollten in Dashboards und Alarmen sichtbar sein.

Verwenden Sie kubectl describe node, wenn ein Node verdächtig aussieht:

kubectl describe node worker-12

Überprüfen Sie Bedingungen, zugewiesene Ressourcen, Ereignisse und auf dem Node geplante Pods. Ein Node kann durch Limits, Anfragen oder die tatsächliche Nutzung überbucht sein. Der Abschnitt "zugewiesene Ressourcen" hilft Ihnen zu sehen, ob die Planungsannahmen mit der Realität übereinstimmen.

Die Überwachung der Steuerungsebene ist wichtig, auch wenn Ihre Anwendungs-Pods in Ordnung aussehen. Die API-Server-Latenz kann Bereitstellungen, automatische Skalierung und Controller verlangsamen. etcd-Latenz oder Festplattenprobleme können den gesamten Cluster träge erscheinen lassen. Probleme mit dem Controller-Manager und Scheduler können die Pod-Platzierung oder -Abstimmung verzögern. In verwaltetem Kubernetes sehen Sie möglicherweise nicht jede Komponente der Steuerungsebene, aber Cloud-Anbieter legen normalerweise einige Gesundheits- und API-Latenzmetriken offen.

Ereignisse sind während Vorfällen nützlich, aber sie sind kein Langzeitspeicher für Metriken. Trotzdem erklären sie oft, was gerade passiert ist:

kubectl get events -A --sort-by=.lastTimestamp

Suchen Sie nach fehlgeschlagener Planung, Image-Pull-Fehlern, Probe-Fehlern, Evakuierungen und Back-Off-Nachrichten. Ereignisse können laut sein, filtern Sie daher nach Namespace oder betroffenem Objekt, wenn nötig.

Probes verdienen eine sorgfältige Überwachung. Zu aggressive Liveness-Probes können eine langsame, aber sich erholende App neu starten und einen Vorfall verschlimmern. Readiness-Probes, die korrekt fehlschlagen, können Benutzer schützen, indem sie schlechte Pods aus dem Dienst entfernen. Verfolgen Sie Probe-Fehler und korrelieren Sie sie mit CPU-Drosselung, GC-Pausen, nachgelagerten Timeouts und Bereitstellungen.

Bei speicherintensiven Arbeitslasten reichen Container-CPU und -Speicher nicht aus. Überwachen Sie die Latenz persistenter Volumes, den Festplattendurchsatz, die Warteschlangentiefe und die Dateisystemfüllung. Ein Pod, der auf langsamen Speicher wartet, kann eine niedrige CPU-Auslastung aufweisen, weil er blockiert ist. Wenn eine Datenbank oder Queue auf Kubernetes läuft, sind Speichermetriken Teil der Anwendungsleistung, nicht der Infrastruktur-Trivia.

Ein praktischer Troubleshooting-Pfad beginnt breit und verengt sich. Bestätigen Sie zuerst das benutzerseitige Symptom: Latenz, Fehler, fehlgeschlagene Jobs oder Rückstand. Identifizieren Sie zweitens den Umfang: ein Pod, ein Deployment, ein Node, ein Namespace oder der gesamte Cluster. Überprüfen Sie drittens aktuelle Änderungen: Bereitstellungen, Konfigurationsaktualisierungen, Aktivität des Autoscalers, Node-Rotationen oder Verkehrsspitzen. Untersuchen Sie viertens das Pod-Ressourcenverhalten: CPU-Drosselung, Speicherdruck, Neustarts und Probe-Fehler. Überprüfen Sie fünftens die Node- und Abhängigkeitsgesundheit.

Die Alarmierung sollte vermeiden, Menschen für harmlosen Lärm zu wecken. Alarmieren Sie zuerst über Benutzerauswirkungen: hohe Fehlerrate, hohe Latenz, verpasste Jobfrist, wachsendes Queue-Alter. Alarmieren Sie dann über starke Frühindikatoren: häufige OOMKills, anhaltende CPU-Drosselung bei latenzempfindlichen Diensten, Pods, die unter den gewünschten Replikaten nicht verfügbar sind, Node-Druck, anhaltende ausstehende Pods und HPA, das bei maximalen Replikaten feststeckt, während die Dienstmetriken schlecht sind.

Das Ziel ist nicht eine perfekte Auslastung. Ein Cluster, der den ganzen Tag bei 95 Prozent Ressourcennutzung läuft, mag effizient aussehen, bis ein Node ausfällt und kein Platz zum Neuplanen von Pods vorhanden ist. Lassen Sie Kapazität für Rollouts, Wiederholungen, Verkehrsspitzen und Fehler. Die Optimierung sollte Abfall reduzieren, ohne den Puffer zu entfernen, der Vorfälle klein hält.

Gutes Kubernetes Performance Monitoring fühlt sich praktisch an. Sie können ein Dashboard öffnen und die Dienstgesundheit, Pod-Gesundheit, Node-Gesundheit und das Skalierungsverhalten sehen, ohne durch zwanzig Tabs zu jagen. Sie können beantworten, ob eine Verlangsamung auf Code, Ressourcenlimits, Node-Druck, Speicher, Netzwerk oder die Steuerungsebene zurückzuführen ist. Und wenn Sie Anfragen, Limits oder die automatische Skalierung ändern, können Sie sehen, ob die Änderung geholfen hat, anstatt zu raten.

Namespace-Ebene-Ansichten sind nützlich, wenn viele Teams einen Cluster teilen. Ein einzelnes Team sieht möglicherweise keine Node-Ebene-Sättigung, wenn es nur seine eigenen Deployments überwacht. Plattformteams sollten Dashboards bereitstellen, die Namespace-CPU- und Speicheranfragen, die tatsächliche Nutzung, Pod-Anzahlen, Neustarts und Drosselung zeigen. Das macht Kapazitätsgespräche weniger emotional. Anstatt zu sagen, dass ein Team "zu viel" verwendet, können Sie Anforderungstrends, Spitzennutzung und Abfall zeigen.

Kostenoptimierung sollte nach Zuverlässigkeitssignalen kommen, nicht davor. Wenn ein Dienst noch nie Anfragen optimiert hatte, finden Sie möglicherweise einfache Einsparungen. Aber das aggressive Kürzen von Anfragen kann Planungsdruck und Probleme mit lauten Nachbarn erzeugen. Ein guter Prozess ändert eine Arbeitslastklasse nach der anderen, beobachtet Latenz und Neustarts und hinterlässt Rollback-Notizen. Behandeln Sie die Ressourcenoptimierung wie Produktionscode: kleine Änderungen, gemessene Ergebnisse.

Bereitstellungen selbst können Leistungsvorfälle erzeugen. Ein Rollout, das zu viele Pods auf einmal ersetzt, kann kalte Caches, Verbindungspools oder nachgelagerte Dienste überlasten. Überwachen Sie die Rollout-Dauer, nicht verfügbare Replikate und die Anwendungslatenz während Bereitstellungen. Passen Sie maxSurge und maxUnavailable basierend auf dem Verhalten des Dienstes während des Starts an. Ein Dienst mit langsamem Warmup benötigt möglicherweise ein konservatives Rollout, auch wenn die Leistung im stationären Zustand gut ist.

strategy:
  type: RollingUpdate
  rollingUpdate:
    maxSurge: 1
    maxUnavailable: 0

Diese Einstellung ist nicht universell am besten, aber sie zeigt den Kompromiss: langsameres Rollout, mehr Schutz vor Kapazitätseinbrüchen. Für einen zustandslosen Dienst, der sofort startet, können Sie ein schnelleres Rollout wählen. Für einen JVM-Dienst, der Caches aufwärmt und viele nachgelagerte Verbindungen öffnet, kann langsamer sicherer sein.

Behalten Sie die Kardinalität in Metriken im Auge. Kubernetes-Labels sind verlockend, aber Labels mit hoher Kardinalität wie Pod-UID, Anforderungs-ID oder Benutzer-ID können Prometheus teuer und langsam machen. Verwenden Sie Labels, die Ihnen bei der Aggregation helfen: Namespace, Arbeitslast, Pod, Container, Node, Statuscode, Routenmuster. Vermeiden Sie Labels, die für jeden Benutzer oder jede Anfrage eine neue Zeitreihe erstellen. Die Überwachung sollte nicht das werden, was die Clusterleistung beeinträchtigt.

Logs und Traces vervollständigen das Bild. Metriken sagen Ihnen, dass die Latenz gestiegen ist; Traces können zeigen, welcher nachgelagerte Aufruf langsam wurde; Logs können den genauen Fehler oder Timeout zeigen. OpenTelemetry wird häufig verwendet, um diese Signale zu verbinden, aber das Tool ist weniger wichtig als die Korrelation. Verwenden Sie konsistente Dienstnamen, Namespaces, Versionen und Trace-IDs, damit Sie von einem Alarm zu den relevanten Logs gelangen, ohne zu raten.

Für Batch- und Worker-Systeme überwachen Sie das Rückstandsalter anstatt nur die Pod-CPU. Ein Queue-Worker kann auf Pod-Ebene gesund sein, während er zurückfällt, weil die eingehende Arbeit die Verarbeitungskapazität übersteigt. Metriken wie das älteste Nachrichtenalter, abgeschlossene Jobs pro Minute, Wiederholungen und Dead-Letter-Anzahlen sind oft wichtiger als die Containerauslastung. HPA kann von benutzerdefinierten oder externen Metriken skalieren, wenn CPU das falsche Signal ist.

Überprüfen Sie Dashboards nach Vorfällen. Wenn Responder fünf manuelle Befehle ausführen mussten, um dieselbe Frage zu beantworten, gehört diese Frage in ein Dashboard oder ein Runbook. Die Überwachung wird durch die Nutzung besser. Das Ziel ist nicht, jeden Fehler vorherzusagen; es ist, die nächste Untersuchung kürzer und weniger abhängig vom Gedächtnis einer Person zu machen.