- Authors

- Name
- Phillip Pham
- @ddppham
TL;DR
Requests reservieren Ressourcen für den Scheduler, Limits begrenzen den tatsächlichen Verbrauch. CPU wird bei Überschreitung gedrosselt (Throttling), Memory führt zum OOMKill. Kubernetes ordnet Pods in drei QoS-Klassen ein: Guaranteed, Burstable und BestEffort. Setzen Sie immer Memory-Limits und nutzen Sie LimitRange als Namespace-Default.
Requests vs. Limits verstehen
Der Scheduler nutzt Requests um zu entscheiden, auf welchem Node ein Pod platziert wird. Limits begrenzen, was ein Container maximal nutzen darf.
apiVersion: v1
kind: Pod
metadata:
name: web-app
spec:
containers:
- name: app
image: nginx:1.27
resources:
requests:
cpu: 250m # 0.25 CPU-Cores reserviert
memory: 128Mi # 128 MiB reserviert
limits:
cpu: 500m # max 0.5 CPU-Cores
memory: 256Mi # max 256 MiB
CPU-Einheiten: 1000m = 1 vCPU/Core. 250m = ein Viertel Core.
Memory-Einheiten: Mi (Mebibyte), Gi (Gibibyte). Vermeiden Sie M und G (Dezimal) - die Differenz kann bei großen Werten relevant werden.
CPU vs. Memory: Unterschiedliches Verhalten
Das ist die wichtigste Unterscheidung bei Kubernetes-Ressourcen:
| Aspekt | CPU | Memory |
|---|---|---|
| Typ | Kompressibel | Inkompressibel |
| Bei Limit-Überschreitung | Throttling (gedrosselt) | OOMKill (Pod-Neustart) |
| Unter-Provisionierung | Langsamere Antwortzeiten | Crash |
| Über-Provisionierung | Verschwendung | Verschwendung |
CPU-Throttling erkennen
CPU-Throttling ist heimtückisch - der Container stürzt nicht ab, wird aber langsamer. So erkennen Sie es:
# Throttling-Statistiken aus cgroup lesen
kubectl exec web-app -- cat /sys/fs/cgroup/cpu.stat
# nr_throttled: Anzahl der Throttling-Perioden
# throttled_usec: Gesamte gedrosselte Zeit
# Aktuellen Verbrauch prüfen
kubectl top pod web-app
OOMKill erkennen
# Pod-Status prüfen
kubectl get pod web-app -o jsonpath='{.status.containerStatuses[0].lastState}'
# Events zeigen OOMKilled
kubectl describe pod web-app | grep -i oom
# Typische Ausgabe:
# Last State: Terminated
# Reason: OOMKilled
# Exit Code: 137
Exit Code 137 bedeutet immer OOMKill (128 + Signal 9).
QoS-Klassen im Detail
Kubernetes ordnet jedem Pod automatisch eine Quality-of-Service-Klasse zu. Bei Ressourcenknappheit werden Pods in dieser Reihenfolge evicted: BestEffort zuerst, dann Burstable, zuletzt Guaranteed.
Guaranteed: Höchste Priorität
Requests und Limits sind identisch für alle Container im Pod:
apiVersion: v1
kind: Pod
metadata:
name: database
spec:
containers:
- name: postgres
image: postgres:16
resources:
requests:
cpu: "1"
memory: 2Gi
limits:
cpu: "1"
memory: 2Gi
Einsatz: Datenbanken, Stateful Workloads, kritische Services. Der Pod bekommt exakt die angeforderten Ressourcen.
Burstable: Mittlere Priorität
Mindestens ein Container hat Requests, aber Limits und Requests unterscheiden sich:
apiVersion: v1
kind: Pod
metadata:
name: api-server
spec:
containers:
- name: api
image: my-api:v3
resources:
requests:
cpu: 200m
memory: 256Mi
limits:
cpu: "1"
memory: 1Gi
Einsatz: Die meisten Anwendungen. Der Pod kann bei Bedarf mehr Ressourcen nutzen als reserviert, riskiert aber Throttling und Eviction.
BestEffort: Niedrigste Priorität
Keine Requests und keine Limits definiert:
apiVersion: v1
kind: Pod
metadata:
name: batch-job
spec:
containers:
- name: worker
image: busybox
command: ["sh", "-c", "echo hello"]
# Keine resources-Sektion
Einsatz: Nur für unkritische Batch-Jobs oder Entwicklungsumgebungen. Diese Pods werden bei Ressourcenknappheit als Erstes beendet.
# QoS-Klasse eines Pods prüfen
kubectl get pod database -o jsonpath='{.status.qosClass}'
# Ausgabe: Guaranteed
LimitRange: Namespace-weite Defaults
Ohne LimitRange können Entwickler Pods ohne Limits deployen - ein Risiko für die Cluster-Stabilität. LimitRange setzt Defaults und erzwingt Grenzen pro Container.
apiVersion: v1
kind: LimitRange
metadata:
name: default-limits
namespace: production
spec:
limits:
- type: Container
default: # Standard-Limits wenn keine gesetzt
cpu: 500m
memory: 512Mi
defaultRequest: # Standard-Requests wenn keine gesetzt
cpu: 100m
memory: 128Mi
min: # Minimum pro Container
cpu: 50m
memory: 64Mi
max: # Maximum pro Container
cpu: "4"
memory: 8Gi
# LimitRange anwenden
kubectl apply -f limitrange.yaml
# Prüfen
kubectl describe limitrange default-limits -n production
Pods die nach dem Erstellen der LimitRange deployed werden, bekommen automatisch die Defaults. Bestehende Pods sind nicht betroffen.
ResourceQuota: Gesamtbudget pro Namespace
Während LimitRange einzelne Container begrenzt, limitiert ResourceQuota den gesamten Namespace:
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-quota
namespace: production
spec:
hard:
requests.cpu: "10"
requests.memory: 20Gi
limits.cpu: "20"
limits.memory: 40Gi
pods: "50"
Sizing-Empfehlungen
Richtig dimensionieren ist keine exakte Wissenschaft. Starten Sie konservativ und optimieren Sie basierend auf Monitoring-Daten.
| Workload-Typ | CPU Request | CPU Limit | Memory Request | Memory Limit |
|---|---|---|---|---|
| Web-API | 100-500m | 500m-1 | 128-512Mi | 256Mi-1Gi |
| Datenbank | 500m-2 | 2-4 | 1-4Gi | 2-8Gi |
| Batch-Job | 100m-1 | 1-4 | 256Mi-1Gi | 512Mi-2Gi |
| Cache (Redis) | 100-250m | 250-500m | 256Mi-2Gi | 512Mi-4Gi |
Praktische Regeln:
- Memory-Limit = 1.5-2x Memory-Request als Startpunkt
- CPU-Limit weglassen ist eine valide Strategie - viele Teams setzen bewusst kein CPU-Limit um Throttling zu vermeiden (nur Request für Scheduling)
- Memory-Limit immer setzen - ohne Limit kann ein Memory-Leak den gesamten Node destabilisieren
- Nutzen Sie
kubectl top podsund den Vertical Pod Autoscaler (VPA) im Recommend-Modus für datenbasiertes Sizing
# Aktuellen Verbrauch aller Pods im Namespace
kubectl top pods -n production --sort-by=memory
# Node-Auslastung prüfen
kubectl top nodes
# VPA-Empfehlungen abrufen (wenn installiert)
kubectl get vpa -n production -o yaml
FAQ
Soll ich CPU-Limits setzen oder weglassen?
Das ist umstritten. Ohne CPU-Limit vermeiden Sie Throttling und der Pod kann freie CPU-Kapazität nutzen. Das Risiko: Ein Pod kann temporär einen ganzen Node auslasten. Setzen Sie mindestens CPU-Requests und testen Sie beide Varianten.
Was passiert wenn Requests die Node-Kapazität übersteigen?
Der Scheduler platziert den Pod nicht auf dem Node - er bleibt Pending. Requests sind Garantien: Der Scheduler summiert alle Requests und vergleicht mit der Node-Kapazität (Allocatable).
Wie finde ich die richtigen Resource-Werte?
Starten Sie mit großzügigen Limits, beobachten Sie den tatsächlichen Verbrauch über 1-2 Wochen mit kubectl top oder Prometheus, und passen Sie dann an. Der VPA im Recommend-Modus schlägt automatisch passende Werte vor.
Warum wird mein Pod trotz freiem Memory OOMKilled?
Das Memory-Limit bezieht sich auf den einzelnen Container, nicht den Node. Auch Kernel-Memory und Cache zählen zum Verbrauch. Prüfen Sie mit kubectl describe pod den tatsächlichen Verbrauch aller Container im Pod, inklusive Sidecars.
Was ist der Unterschied zwischen LimitRange und ResourceQuota?
LimitRange setzt Grenzen pro einzelnem Container/Pod und definiert Defaults. ResourceQuota limitiert die Summe aller Ressourcen in einem Namespace. Beide ergänzen sich und sollten zusammen eingesetzt werden.
Kubernetes ohne DevOps-Overhead?
Wir betreiben Ihre Kubernetes-Cluster 24/7 – Sie fokussieren auf Ihr Kerngeschäft. Ab 4.000€/Monat, DSGVO-konform, mit deutschem Support.
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
Kubernetes Requests und Limits richtig setzen
CPU und Memory Requests und Limits korrekt konfigurieren: QoS-Klassen verstehen, typische Fehler vermeiden und die richtigen Werte finden.
Kubernetes Requests, Limits und QoS richtig setzen
Kubernetes Requests und Limits optimal konfigurieren, QoS-Klassen verstehen und durch Right-Sizing bis zu 25 Prozent Cloud-Kosten sparen.
ConfigMaps richtig nutzen: Kubernetes Best Practices
ConfigMaps in Kubernetes erstellen, mounten und aktualisieren: Praktische Best Practices für Volumes, Env-Vars und Hot-Reload mit Reloader.
RBAC Best Practices: Kubernetes-Zugriff sicher steuern
Kubernetes RBAC richtig konfigurieren: Role vs. ClusterRole, praxisnahe Beispiele für Developer- und CI/CD-Rollen und die häufigsten Fehler vermeiden.
kubectl apply vs create: Unterschied und Empfehlung
kubectl apply, create und replace im Vergleich: Wann Sie deklarativ oder imperativ arbeiten sollten und welche typischen Fehler es zu vermeiden gilt.