Fehlerbehebung bei häufigen Kubernetes-Leistungsengpässen
Lernen Sie, häufige Kubernetes-Leistungsengpässe systematisch zu diagnostizieren und zu beheben, einschließlich CPU-Drosselung, Speicher-OOMKills und Planungsverzögerungen. Dieser Leitfaden bietet umsetzbare Befehle und bewährte Methoden zur Optimierung von Ressourcenanforderungen, zur Optimierung der HPA-Skalierung und zur Identifizierung zugrunde liegender Cluster-Einschränkungen, um eine optimale Anwendungsleistung sicherzustellen.
Fehlerbehebung bei häufigen Kubernetes-Leistungsengpässen
Kubernetes-Leistungsprobleme kündigen sich selten mit der Aussage „Kubernetes ist langsam“ an. Sie sehen einen Rollout, der hängt, eine API, die plötzlich 5xx-Fehler zurückgibt, eine Warteschlange, die nicht mehr abgebaut wird, oder Pods, die gesund aussehen, während Benutzer sich über Latenz beschweren. Der Cluster ist nur ein Teil dieser Geschichte, aber der Teil, den Sie mit einem konsistenten Satz von Befehlen überprüfen können.
Der Trick besteht darin, nicht direkt zur Knotengröße oder Replikatanzahl zu springen. Entscheiden Sie zuerst, welche Art von Engpass Sie haben: CPU-Drosselung, Speicherdruck, Planungsverzögerung, langsames Skalieren, Netzwerklatenz, Speicherlatenz oder eine Anwendung, die einfach mehr Arbeit leistet als erwartet.
Phase 1: Identifizieren der Symptome
Bevor Sie sich mit spezifischen Komponenten befassen, definieren Sie klar die beobachtete Leistungsverschlechterung. Häufige Symptome fallen oft in eine dieser Kategorien:
- Langsame Bereitstellungen/Updates: Die Pod-Erstellung dauert übermäßig lange, oder Rolling-Updates bleiben stecken.
- Nicht reagierende Anwendungen: Pods laufen, reagieren aber nicht auf Anwendungsverkehr (z. B. hohe Latenz, 5xx-Fehler).
- Hohe Ressourcenspitzen: Unerklärliche CPU- oder Speicherauslastungsspitzen auf Knoten oder in bestimmten Bereitstellungen.
- Planungsverzögerungen: Neue Pods bleiben auf unbestimmte Zeit im Status
Pending.
Phase 2: Diagnose von Ressourcenbeschränkungen (CPU und Arbeitsspeicher)
Ressourcenfehlmanagement ist die häufigste Ursache für Kubernetes-Leistungsprobleme. Falsch gesetzte Requests und Limits führen zu Drosselung oder OOMKills.
1. Überprüfung der Ressourcennutzung und -limits
Überprüfen Sie zunächst die Ressourcenzuweisungen für die betroffene Anwendung mit kubectl describe und kubectl top.
Umsetzbare Prüfung: Vergleichen Sie die requests und limits mit der tatsächlichen Nutzung, die von den Metrikservern gemeldet wird.
# Ressourcennutzung für alle Pods in einem Namespace abrufen
kubectl top pods -n <namespace>
# Ressourcenanforderungen/-limits für einen bestimmten Pod überprüfen
kubectl describe pod <pod-name> -n <namespace>
Überprüfen Sie auch die zugehörige Workload, um zu verstehen, ob das Problem einen Pod oder die gesamte Bereitstellung betrifft:
kubectl get deploy <deployment-name> -n <namespace> -o yaml
kubectl get pods -n <namespace> -l app=<label> -o wide
Wenn nur ein Pod langsam ist und sich auf einem anderen Knoten als die anderen befindet, ist Knotendruck wahrscheinlicher. Wenn alle Replikate langsam sind, verdienen die Ressourceneinstellungen, nachgelagerten Abhängigkeiten oder das Anwendungsverhalten mehr Aufmerksamkeit.
2. CPU-Drosselung
Wenn die CPU-Auslastung eines Containers wiederholt sein definiertes Limit erreicht, wird der Kernel ihn drosseln, was zu schwerwiegenden Latenzspitzen führt, selbst wenn der Knoten selbst über ausreichende Kapazität verfügt. Dies wird oft mit allgemeinem CPU-Mangel verwechselt.
Diagnosetipp: Achten Sie auf hohe Latenzantworten, auch wenn kubectl top keine 100% CPU-Auslastung auf dem Knoten anzeigt. Die Drosselung erfolgt pro Container.
Für eine tiefere Bestätigung verwenden Sie Ihr Metriksystem, wenn es Metriken zur CPU-Drosselung von Containern bereitstellt. In Prometheus-basierten Setups beobachten Teams oft Metriken wie gedrosselte CPU-Perioden zusammen mit der Anforderungslatenz. Die reine CPU-Auslastung allein kann die Drosselung verbergen, da ein Container gedrosselt werden kann, bevor er überhaupt einen vollen Knotenkern zu nutzen scheint.
Lösung:
- Erhöhen Sie das CPU-
limit, wenn die Workload legitimerweise mehr Rechenleistung benötigt. - Wenn die Anwendung busy-waiting betreibt, optimieren Sie den Anwendungscode, anstatt einfach die Limits zu erhöhen.
- Erwägen Sie, CPU-Limits für einige latenzempfindliche Dienste zu entfernen, während Sie CPU-Requests beibehalten, wenn dies Ihrer Plattformrichtlinie entspricht. Dies vermeidet harte Drosselung, während der Scheduler dennoch nützliche Platzierungsinformationen erhält.
3. Speicherdruck und OOMKills
Wenn ein Container sein Speicher-limit überschreitet, initiiert Kubernetes einen Out-Of-Memory (OOM)-Kill und startet den Container wiederholt neu.
Diagnose: Überprüfen Sie den Pod-Status auf häufige Neustarts (überprüfen Sie die Spalte RESTARTS in kubectl get pods) und untersuchen Sie die Logs auf OOMKilled-Ereignisse.
# Überprüfen Sie aktuelle Ereignisse auf OOMKills
kubectl get events --field-selector involvedObject.name=<pod-name> -n <namespace>
Lösung:
- Wenn OOMKills häufig auftreten, erhöhen Sie sofort das Speicher-
limit. - Für langfristige Korrekturen profilieren Sie die Anwendung, um Speicherlecks zu finden und zu beheben oder die Heap-Größe zu reduzieren.
Speicher verhält sich anders als CPU. CPU kann gedrosselt werden und der Prozess läuft langsam weiter. Speicherlimitverstöße enden in der Regel damit, dass der Prozess getötet wird. Das macht Speicherprobleme wie Zuverlässigkeitsvorfälle: Neustarts, getrennte Verbindungen, kalte Caches und fehlgeschlagene laufende Anfragen.
Bewährte Methode: Requests mit Bedacht setzen. Stellen Sie sicher, dass Ressourcen-
requestsvernünftig nahe der erwarteten Mindestnutzung gesetzt werden. Wennrequestszu niedrig sind, könnte der Scheduler den Knoten überbuchen, was zu Konflikten führt, wenn alle Pods gleichzeitig ihre Anforderungen erreichen.
Phase 3: Untersuchung von Planungsengpässen
Wenn Pods im Status Pending bleiben, liegt das Problem in der Unfähigkeit des Schedulers, einen geeigneten Knoten zu finden.
1. Analyse ausstehender Pods
Verwenden Sie kubectl describe pod auf einem ausstehenden Pod, um den Abschnitt Events zu lesen. Dieser Abschnitt enthält normalerweise eine klare Erklärung für den Planungsfehler.
Häufige Scheduler-Meldungen:
0/3 nodes are available: 3 Insufficient cpu.(Knotenkapazitätsproblem)0/3 nodes are available: 3 node(s) had taint {dedicated: infra}, that the pod didn't tolerate.(Taints/Tolerations-Konflikt)0/3 nodes are available: 1 node(s) had taint {NoSchedule: true}, that the pod didn't tolerate.(Knotendruck oder Wartung)
2. Cluster-Ressourcensättigung
Wenn die Planung aufgrund von CPU-/Speichermangel verzögert wird, fehlt dem Cluster die ausreichende Gesamtkapazität.
Lösung:
- Fügen Sie dem Cluster weitere Knoten hinzu.
- Stellen Sie sicher, dass die Knotenauslastung nicht künstlich hoch ist aufgrund falsch konfigurierter Ressourcenanforderungen (siehe Phase 2).
- Verwenden Sie Cluster Autoscaler (CA), wenn Sie in Cloud-Umgebungen arbeiten, um dynamisch Knoten hinzuzufügen, wenn ausstehende Pods anfallen.
Wenn Cluster Autoscaler aktiviert ist, aber keine Knoten hinzugefügt werden, lesen Sie seine Logs, bevor Sie annehmen, dass der Cloud-Anbieter defekt ist. Der Autoscaler kann sich weigern, Knoten hinzuzufügen, weil Knotengruppen ihre maximale Größe erreicht haben, der ausstehende Pod Einschränkungen hat, die keine Knotengruppe erfüllen kann, oder Kontingente neue Instanzen verhindern.
Phase 4: Leistungsprobleme bei Skalierungsmechanismen
Automatische Skalierung sollte schnell reagieren, aber Fehlkonfigurationen in Horizontal Pod Autoscalern (HPA) oder Vertical Pod Autoscalern (VPA) können Probleme verursachen.
1. Horizontal Pod Autoscaler (HPA)-Verzögerung
HPA ist auf den Metrics Server angewiesen, um genaue CPU-/Speicherauslastung oder benutzerdefinierte Metriken zu melden.
Diagnoseschritte:
- Überprüfen Sie die Gesundheit des Metrics Servers: Stellen Sie sicher, dass der Metrics Server läuft und erreichbar ist.
kubectl get --raw "/apis/metrics.k8s.io/v1beta1/nodes" - Überprüfen Sie den HPA-Status: Untersuchen Sie die HPA-Konfiguration und aktuelle Ereignisse.
Achten Sie auf Meldungen, die darauf hinweisen, ob die Metrikquelle nicht verfügbar ist oder ob die Skalierungsentscheidungsschleife funktioniert.kubectl describe hpa <hpa-name> -n <namespace>
Engpässe: Wenn benutzerdefinierte Metriken verwendet werden, stellen Sie sicher, dass der externe Metrikanbieter korrekt funktioniert und Daten oft genug meldet, damit der HPA nützliche Entscheidungen treffen kann.
HPA ist reaktiv. Es weiß nicht, dass ein Verkehrsanstieg bevorsteht, es sei denn, Ihre Metrik spiegelt dies wider. Für Workloads mit plötzlichen Ausbrüchen benötigen Sie möglicherweise höhere Mindestreplikate, schnellere benutzerdefinierte Metriken, warteschlangenbasierte Skalierung oder Vorskalierung vor bekannten Ereignissen.
2. Vertical Pod Autoscaler (VPA)-Interaktionen
Während VPA automatisch Ressourcenanforderungen anpasst, kann es während seiner Anpassungsphase zu Leistungsinstabilität führen, wenn es Pods häufig neu startet oder deren Größe ändert, insbesondere bei zustandsbehafteten Anwendungen, die keine Neustarts tolerieren können.
Empfehlung: Verwenden Sie VPA zuerst im Recommender-Modus oder verwenden Sie updateMode: "Off", um nur Empfehlungen zu beobachten, ohne automatische Anwendung, wodurch unnötige Resizing-Unterbrechungen vermieden werden.
Phase 5: Netzwerk- und Speicherleistung
Wenn die Rechenressourcen in Ordnung aussehen, könnten Netzwerk oder persistenter Speicher der Engpass sein.
1. CNI (Container Network Interface)-Probleme
Wenn die Kommunikation zwischen Pods (insbesondere über Knoten hinweg) langsam ist oder zeitweise ausfällt, könnte das CNI-Plugin überlastet oder falsch konfiguriert sein.
Fehlerbehebung:
- Überprüfen Sie die Logs der CNI-Daemonset-Pods (z. B. Calico, Flannel).
- Testen Sie die grundlegende Konnektivität mit
pingodercurlzwischen Pods auf verschiedenen Knoten.
2. Persistent Volume (PV)-Latenz
Anwendungen, die stark von Festplatten-I/O abhängen (Datenbanken, Protokollierungssysteme), leiden, wenn die zugrunde liegende Persistent Volume-Latenz hoch ist.
Umsetzbare Prüfung: Bestätigen Sie den Provisioner-Typ (z. B. AWS EBS gp3 vs. io1) und stellen Sie sicher, dass das Volume die erforderlichen IOPS/Durchsatzspezifikationen erfüllt.
Warnung zum Speicher: Führen Sie niemals Hochdurchsatz-Datenbanken direkt auf Standard-
hostPath-Volumes aus, ohne die zugrunde liegenden Festplattenleistungsmerkmale zu verstehen. Verwenden Sie verwaltete Cloud-Speicherlösungen oder Hochleistungs-Lokalspeicher-Provisioner für anspruchsvolle Workloads.
Engpässe auf Knotenebene
Manchmal werden alle Pods auf einem Knoten gleichzeitig langsamer. Das ist Ihr Hinweis, nicht mehr auf eine einzelne Bereitstellung zu starren, sondern den Knoten zu überprüfen.
kubectl describe node <node-name>
kubectl top node <node-name>
kubectl get pods --all-namespaces -o wide | grep <node-name>
Achten Sie auf MemoryPressure, DiskPressure und PIDPressure-Bedingungen. Festplattendruck ist leicht zu übersehen, da das Anwendungssymptom ein langsamer Start, fehlgeschlagene Image-Pulls oder Vertreibungen sein kann, anstatt eines offensichtlichen Festplattenfehlers.
Überprüfen Sie auf dem Knoten selbst, wenn Sie Zugriff haben:
df -h
iostat -x 1
free -h
journalctl -u kubelet --since "30 minutes ago"
Verwaltete Kubernetes-Dienste können den direkten Knotenzugriff einschränken, aber die gleiche Idee gilt dennoch: Verwenden Sie Anbietermetriken, Kubelet-Ereignisse und Knotenbedingungen, um zu entscheiden, ob der Knoten der gemeinsame Engpass ist.
Steuerungsebene und API-Druck
Die meiste Anwendungslatenz wird nicht durch den Kubernetes-API-Server verursacht. Ihre Webanfrage ruft normalerweise nicht bei jeder Benutzeranfrage den API-Server auf. Aber der Druck auf die Steuerungsebene kann die Betriebsleistung beeinträchtigen: langsame Rollouts, verzögerte Planung, langsame Endpunktaktualisierungen oder Controller, die hinterherhinken.
Zu den Symptomen gehören:
kubectl-Befehle sind im gesamten Cluster langsam.- Bereitstellungen benötigen länger als üblich, um Pods zu erstellen.
- Controller hinken dem gewünschten Zustand hinterher.
- Ereignisse zeigen wiederholte API-Timeouts.
Überprüfen Sie, ob das Problem den normalen Anwendungsverkehr oder den Clusterbetrieb betrifft. Wenn nur Rollouts und Planung langsam sind, überprüfen Sie die API-Server-Gesundheit, das Controller-Manager-Verhalten, Admission-Webhooks und die etcd-Gesundheit in Clustern, in denen Sie die Steuerungsebene verwalten.
Admission-Webhooks verdienen besondere Aufmerksamkeit. Ein langsamer oder nicht verfügbarer Webhook kann die Pod-Erstellung verzögern, selbst wenn Knoten reichlich Kapazität haben. Wenn ein Rollout zum Zeitpunkt der Erstellung hängt und Ereignisse Webhook-Aufrufe erwähnen, untersuchen Sie den Webhook-Dienst, bevor Sie Knoten vergrößern.
Eine praktische Reihenfolge zur Fehlerbehebung
Beginnen Sie mit dem für den Benutzer sichtbaren Symptom:
- Langsame HTTP-Anfragen: Vergleichen Sie Anwendungslatenz, CPU-Drosselung, Speicherneustarts, nachgelagerte Latenz und Netzwerkpfad.
- Langsamer Pod-Start: Überprüfen Sie Image-Pull-Zeit, Planungsereignisse, Volume-Attach-Zeit und Init-Container.
- Ausstehende Pods: Überprüfen Sie Requests, Knotenkapazität, Taints, Affinitäten, Kontingente und Autoscaler-Limits.
- Periodische Latenzspitzen: Überprüfen Sie CPU-Drosselung, Garbage Collection, laute Nachbarn, Speicherlatenz und HPA-Skalierungszeitpunkt.
- Zufällige Neustarts: Überprüfen Sie OOMKilled, Liveness-Probes, Knotendruck und Anwendungslogs aus dem vorherigen Container.
Beweisen oder eliminieren Sie dann eine Schicht nach der anderen. Wenn beispielsweise Latenzspitzen genau mit CPU-Drosselung zusammenfallen, haben Sie eine starke Spur. Wenn Latenzspitzen auftreten, während CPU, Speicher, Netzwerk und Speicher alle ruhig aussehen, könnte der Engpass in der Anwendung oder einem nachgelagerten Dienst außerhalb von Kubernetes liegen.
Request- und Limit-Optimierung ohne Rätselraten
Schlechte Ressourceneinstellungen verursachen viele Leistungsprobleme:
- Requests zu niedrig: Der Scheduler packt zu viele ausgelastete Pods auf denselben Knoten.
- Requests zu hoch: Pods bleiben ausstehend, obwohl die tatsächliche Nutzung bescheiden ist.
- CPU-Limits zu niedrig: Latenzempfindliche Apps werden gedrosselt.
- Speicher-Limits zu niedrig: Container werden getötet, anstatt langsamer zu werden.
- Keine Requests: Die Planung wird weniger vorhersagbar, und kritische Workloads können mit lauten Nachbarn konkurrieren.
Verwenden Sie aktuelle Produktionsmetriken als Ausgangspunkt und lassen Sie dann Spielraum für normale Spitzen. Für Java-, Node.js-, Go-, Python- und datenbankähnliche Workloads kann das Speicherverhalten sehr unterschiedlich sein. Vermeiden Sie es daher, Limits von einem Dienst auf einen anderen zu kopieren, nur weil die Container-Image-Größe ähnlich aussieht.
Nächste Schritte
Die besten Kubernetes-Leistungsuntersuchungen sind im positiven Sinne langweilig: Definieren Sie das Symptom, überprüfen Sie den Pod, überprüfen Sie den Knoten, überprüfen Sie die Skalierung, dann überprüfen Sie Netzwerk und Speicher. kubectl describe und kubectl top sind nur der Anfang, aber sie sagen Ihnen normalerweise, welche Richtung es wert ist, verfolgt zu werden.
- Implementieren Sie robuste Ressourcenkontingente, um zu verhindern, dass laute Nachbarn kritische Anwendungen aushungern.
- Überprüfen Sie regelmäßig die Pod-Neustartanzahlen, um subtile OOM- oder fehlerhafte Anwendungsverhalten frühzeitig zu erkennen.
- Nutzen Sie Prometheus/Grafana-Dashboards, die speziell CPU-Drosselungsmetriken verfolgen, nicht nur die rohe Nutzung.