Kubernetes-Ressourcenanforderungen und -Limits für Spitzenleistung meistern
Kubernetes bietet leistungsstarke Funktionen für die Automatisierung der Bereitstellung, Skalierung und Verwaltung containerisierter Anwendungen. Doch das Erreichen von Spitzenleistung und die Aufrechterhaltung der Stabilität in Ihrem Cluster hängt entscheidend davon ab, wie Sie die Ressourcenanforderungen für Ihre Workloads definieren. Falsch konfigurierte Ressourceneinstellungen sind eine Hauptursache für Leistungsengpässe, unvorhersehbare Zeitplanung und ineffiziente Clusterauslastung.
Dieser Leitfaden befasst sich eingehend mit Kubernetes-Ressourcenanforderungen (Resource Requests) und -Limits (Limits). Das Verständnis des Unterschieds und deren korrekte Anwendung sind grundlegend, um die Dienstqualität (Quality of Service, QoS) für Ihre Anwendungen sicherzustellen, „laute Nachbarn“ zu vermeiden und Ihre Infrastrukturkosten zu optimieren. Wir werden untersuchen, wie diese Einstellungen mit dem Kubernetes-Scheduler und dem zugrunde liegenden Betriebssystem interagieren.
Die Kernkonzepte verstehen: Requests vs. Limits
In Kubernetes muss jede Containerspezifikation innerhalb eines Pods ihren erwarteten Ressourcenverbrauch mithilfe von resources.requests und resources.limits definieren. Diese Einstellungen steuern CPU und Arbeitsspeicher, die beiden wichtigsten Ressourcen für die Anwendungsstabilität.
1. Ressourcenanforderungen (requests)
Requests stellen die Menge an Ressourcen dar, die einem Container bei der Zeitplanung garantiert zugewiesen wird. Dies ist die Mindestmenge an Ressourcen, die der Kube-Scheduler verwendet, um zu entscheiden, auf welchem Knoten ein Pod platziert werden soll.
- Zeitplanung: Ein Knoten muss über ausreichend verfügbare zuweisbare Ressourcen verfügen, die die Summe aller Pod-Requests erfüllen, bevor ein neuer Pod dort geplant werden kann.
- Garantien: Wenn der Knoten später knapper an Ressourcen wird, erhält der Container immer noch mindestens die angeforderte Menge (es sei denn, er unterliegt der Eviction).
2. Ressourcen-Limits (limits)
Limits definieren die maximale Menge an Ressourcen, die ein Container verbrauchen darf. Das Überschreiten dieser Limits führt zu spezifischen, definierten Verhaltensweisen für CPU und Arbeitsspeicher.
- CPU-Limits: Versucht ein Container, mehr CPU zu nutzen, als sein Limit zulässt, drosseln die cgroups des Linux-Kernels seine Nutzung und verhindern, dass er weitere Zyklen verbraucht.
- Arbeitsspeicher-Limits: Überschreitet ein Container sein Arbeitsspeicher-Limit, beendet das Betriebssystem den Prozess sofort (OOMKill: Out Of Memory Kill).
Verhalten von CPU vs. Arbeitsspeicher
Es ist entscheidend, den qualitativen Unterschied im Verhalten von Kubernetes bei der Durchsetzung von CPU- und Arbeitsspeicher-Grenzen zu verstehen:
| Ressource | Verhalten bei Überschreitung des Limits | Erzwingungsmechanismus |
|---|---|---|
| CPU | Gedrosselt (verlangsamt) | cgroups (CPU-Bandbreitenkontrolle) |
| Arbeitsspeicher | Beendet (OOMKill) | Kernel OOM Killer |
Tipp: Da die CPU-Drosselung im Allgemeinen weniger störend ist als ein OOMKill, ist es oft am besten, ein CPU-Limit festzulegen, das etwas höher ist als Ihre typische Spitzenlast, während ein striktes Arbeitsspeicher-Limit gesetzt wird, um Knoteninstabilität zu verhindern.
Ressourcen in Pod-Spezifikationen definieren
Ressourcen werden innerhalb des spec.containers[*].resources-Blocks definiert. Mengen werden mit standardmäßigen Kubernetes-Suffixen angegeben (z. B. m für Milli-CPU, Mi für Mebibyte).
CPU-Einheitsdefinitionen
1CPU-Einheit entspricht 1 vollem Kern (oder vCPU bei Cloud-Anbietern).1000m(Millicores) entspricht 1 CPU-Einheit.
Arbeitsspeicher-Einheitsdefinitionen
Mi(Mebibytes) oderGi(Gibibytes) sind gängig.1024Mi=1Gi.
Beispiel-YAML-Konfiguration
Betrachten Sie einen Container, der ein garantiertes Minimum von 500m CPU und 256Mi Arbeitsspeicher benötigt, aber niemals 1 CPU und 512Mi überschreiten sollte:
resources:
requests:
memory: "256Mi"
cpu: "500m"
limits:
memory: "512Mi"
cpu: "1"
Quality of Service (QoS) Klassen
Das Verhältnis zwischen Requests und Limits bestimmt die dem Pod zugewiesene Quality of Service (QoS)-Klasse. Diese Klasse bestimmt die Priorität des Pods, wenn Ressourcen knapp werden und der Knoten Arbeitsspeicher freigeben muss (Eviction).
Kubernetes definiert drei QoS-Klassen:
1. Guaranteed
Definition: Alle Container im Pod müssen identische, ungleich Null-Requests und Limits für sowohl CPU als auch Arbeitsspeicher haben.
- Vorteil: Diese Pods werden bei Ressourcendruck als Letzte entfernt (evicted), was maximale Stabilität gewährleistet.
- Anwendungsfall: Kritische Systemkomponenten oder Datenbanken, die eine strikte Leistungsisolation erfordern.
2. Burstable
Definition: Mindestens ein Container im Pod hat definierte Requests, aber entweder Requests und Limits sind nicht für alle Container gleich, oder einige Ressourcen sind nicht begrenzt (obwohl das Setzen von Limits dringend empfohlen wird).
- Vorteil: Ermöglicht es Containern, über ihre Requests hinaus zu „bursten“ und ungenutzte Kapazität auf dem Knoten bis zu ihren definierten Limits zu nutzen.
- Eviction-Priorität: Wird vor BestEffort-Pods, aber nach Guaranteed-Pods entfernt.
- Anwendungsfall: Die meisten standardmäßigen zustandslosen Anwendungen, bei denen geringfügige Latenzschwankungen akzeptabel sind.
3. BestEffort
Definition: Der Pod hat keine Requests oder Limits für irgendeinen Container definiert.
- Vorteil: Keiner, außer Einfachheit.
- Risiko: Diese Pods sind die ersten Kandidaten für die Entfernung (Eviction), wenn der Knoten Ressourcendruck erfährt. Sie unterliegen auch sofortiger Drosselung oder OOMKills, wenn die Knotenkapazität überschritten wird.
- Anwendungsfall: Nicht-kritische Batch-Jobs oder Logging-Agenten, die leicht neu gestartet werden können.
Praktische Optimierungsstrategien
Effektives Ressourcenmanagement erfordert Messung, Iteration und sorgfältige Planung.
Strategie 1: Requests genau messen und setzen
Requests sollten die typische oder minimal nachhaltige Last widerspiegeln, die Ihre Anwendung benötigt. Wenn Sie Requests zu hoch ansetzen, verschwenden Sie Clusterkapazität, da der Scheduler diese Ressource reserviert, auch wenn der Container sie nicht nutzt.
Best Practice: Verwenden Sie Überwachungstools (wie Prometheus/Grafana), um historische Nutzungsdaten zu analysieren. Legen Sie Requests nahe dem 90. Perzentil der beobachteten Nutzung während des normalen Betriebs fest.
Strategie 2: Konservative Limits definieren
Limits dienen als Sicherheitsnetz. Für den Arbeitsspeicher sollten Sie Limits immer etwas über Ihrem gemessenen Spitzenwert festlegen, um Abstürze zu vermeiden. Für die CPU verhindert das Setzen von Limits, dass ein außer Kontrolle geratener Prozess kritische Geschwisterprozesse auf demselben Knoten „aushungert“.
Warnung zu CPU-Limits: Zu aggressives Setzen von CPU-Limits (z. B. 50 % des tatsächlichen Bedarfs) führt zu einer starken Leistungsminderung aufgrund ständiger Drosselung. Bevorzugen Sie immer die Burstable-QoS, es sei denn, Sie haben einen spezifischen Bedarf an Guaranteed-Isolation.
Strategie 3: Nutzung des Vertical Pod Autoscaler (VPA)
Das manuelle Anpassen von Ressourcen ist schwierig und zeitaufwändig. Der Vertical Pod Autoscaler (VPA) überwacht die Laufzeitnutzung und passt die in Ihren Pod-Spezifikationen definierten Requests und Limits im Laufe der Zeit automatisch an. VPA hilft dabei, Workloads von schlecht konfigurierten Zuständen (oder BestEffort) in optimale Burstable- oder Guaranteed-Konfigurationen zu überführen.
Strategie 4: Ressourcen-Quotas für Namespaces
Um die Ressourcenverschwendung über Teams oder Umgebungen hinweg zu verhindern, sollten Administratoren Ressourcen-Quotas (Resource Quotas) auf Namespace-Ebene verwenden. Eine ResourceQuota legt aggregierte Limits für die Gesamtmenge an CPU-/Arbeitsspeicher-Requests und -Limits fest, die in diesem Namespace existieren dürfen, und gewährleistet so Fairness.
Beispiel Namespace-Quota
apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: development
spec:
hard:
requests.cpu: "10"
limits.memory: "20Gi"
Dies stellt sicher, dass die insgesamt angeforderte CPU über alle Pods im development-Namespace 10 Kerne nicht überschreiten kann und die gesamten Arbeitsspeicher-Limits 20Gi nicht überschreiten können.
Fazit
Das Meistern von Kubernetes-Ressourcenanforderungen und -Limits geht über die bloße Vermeidung von Abstürzen hinaus; es geht darum, vorhersehbare Leistung zu erzielen und den Return on Investment Ihrer Infrastruktur zu maximieren. Durch das korrekte Setzen von Requests für die Zeitplanungssicherung und Limits als Schutz vor unkontrolliertem Verbrauch heben Sie Ihre Pods auf die gewünschte QoS-Klasse (vorzugsweise Burstable oder Guaranteed). Überprüfen Sie regelmäßig Leistungsmetriken und ziehen Sie die Nutzung von Tools wie VPA in Betracht, um eine optimale Ressourcenausrichtung zu gewährleisten, während sich Ihre Anwendungen weiterentwickeln.