Workloads gesund halten: Namespaces, Ressourcen, Quotas und Probes
Teile einen Cluster fair mit Requests, Limits und Quotas und lass Kubernetes ungesunde Container erkennen.
Ein Cluster ist ein gemeinsamer Pool aus CPU und Speicher. Ohne Leitplanken kann ein gieriger Workload seine Nachbarn aushungern, und eine hängende Anwendung kann weiter Traffic erhalten. Diese Anleitung behandelt die Werkzeuge für beides: Namespaces und Quotas, um den Pool aufzuteilen, Requests und Limits, um zu beschreiben, was jeder Container braucht, und Probes, damit Kubernetes erkennen kann, wann ein Container ungesund ist.
Einen Cluster mit Namespaces aufteilen
Namespaces teilen einen Cluster in getrennte Bereiche für Teams, Anwendungen oder Umgebungen:
kubectl create namespace demo
kubectl get pods -n demo
kubectl config set-context --current --namespace=demo
kubectl get pods -A
Deine Objekte landen in default, sofern du nichts anderes sagst, mit -n NAME bei einem Befehl oder metadata.namespace in einem Manifest. Die eigenen Komponenten des Clusters leben in kube-system. Die meisten Objekte sind namespace-bezogen (Pods, Services, ConfigMaps, Secrets), einige wie Knoten und PersistentVolumes sind clusterweit. Namespaces sind die Einheit, an der Quotas und Zugriffsregeln hängen, aber für sich genommen sind sie eine organisatorische Grenze, keine starke Sicherheitsgrenze. Eine häufige Überraschung ist ein Pod, der verschwunden scheint, obwohl du ihn in Wahrheit in einem anderen Namespace erstellt hast. Prüfe mit kubectl get pods -A.
Requests und Limits setzen
Jeder Container kann deklarieren, was er braucht und wie viel er höchstens nutzen darf:
spec:
containers:
- name: web
image: nginx:1.25
resources:
requests:
cpu: 250m
memory: 64Mi
limits:
cpu: 500m
memory: 128Mi
- Requests sind das, was der Scheduler reserviert. Ein Pod wird nur auf einem Knoten mit so viel nicht beanspruchter Kapazität platziert, und dem Container ist mindestens so viel garantiert.
- Limits sind eine harte Obergrenze. Ein Container, der versucht, mehr CPU zu nutzen, wird gedrosselt. Einer, der sein Speicherlimit überschreitet, wird beendet (
OOMKilled) und neu gestartet.
CPU wird in Kernen gemessen, wobei 1000m (Millicores) ein ganzer Kern ist, 250m also ein Viertel davon. Ein Limit darf nicht niedriger als sein Request sein. Beide werden pro Container gesetzt, nicht pro Pod.
Die Nutzung mit dem Metrics Server beobachten
kubectl top meldet die Live-Nutzung, braucht aber den Metrics Server, der vielen frischen Clustern fehlt. Ohne ihn siehst du „Metrics API not available“. Auf minikube:
minikube addons enable metrics-server
kubectl top nodes
kubectl top pods -A
Auf anderen Clustern installiere metrics-server von seiner Projektseite. Es ist ein schneller Weg zu erkennen, welche Pods die meisten Ressourcen nutzen.
Ein Budget durchsetzen mit ResourceQuota und LimitRange
Eine ResourceQuota begrenzt die Gesamtmenge, die ein Namespace anfordern oder nutzen darf:
apiVersion: v1
kind: ResourceQuota
metadata:
name: demo-quota
namespace: demo
spec:
hard:
requests.cpu: "1"
requests.memory: 1Gi
limits.cpu: "2"
limits.memory: 2Gi
pods: "10"
kubectl describe resourcequota -n demo zeigt, was gegen jedes Limit verbraucht ist. Sobald die Gesamtsumme überschritten würde, werden neue Pods bei der Erstellung mit einem Fehler „exceeded quota“ abgelehnt. Deckt eine Quota CPU oder Speicher ab, muss auch jeder Pod in diesem Namespace diese Requests und Limits deklarieren, sonst wird er abgelehnt. Eine LimitRange vermeidet das, indem sie Standardwerte für Container liefert, die keine eigenen setzen:
apiVersion: v1
kind: LimitRange
metadata:
name: container-defaults
namespace: demo
spec:
limits:
- type: Container
defaultRequest:
cpu: 100m
memory: 64Mi
default:
cpu: 250m
memory: 128Mi
Readiness- und Liveness-Probes hinzufügen
Ein laufender Container ist nicht zwingend ein funktionierender. Mit Probes kann Kubernetes prüfen:
- Eine Readiness-Probe entscheidet, ob der Container Traffic erhalten soll. Schlägt sie fehl, wird der Pod aus den Endpoints seiner Services entfernt, aber nicht neu gestartet. Nutze sie für langsame Starts oder vorübergehende Überlast.
- Eine Liveness-Probe entscheidet, ob der Container noch lebt. Nach genügend aufeinanderfolgenden Fehlschlägen startet der kubelet den Container neu.
- Eine Startup-Probe hält die anderen beiden zurück, während eine langsame Anwendung bootet.
spec:
containers:
- name: web
image: nginx:1.25
readinessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 2
periodSeconds: 5
timeoutSeconds: 1
failureThreshold: 3
livenessProbe:
httpGet:
path: /
port: 80
initialDelaySeconds: 10
periodSeconds: 10
failureThreshold: 3
Die Timing-Felder funktionieren bei jeder Probe gleich. initialDelaySeconds ist, wie lange nach dem Start des Containers bis zur ersten Prüfung gewartet wird, periodSeconds ist, wie oft geprüft wird, timeoutSeconds ist, wie lange auf eine Antwort gewartet wird, und failureThreshold ist, wie viele aufeinanderfolgende Fehlschläge als fehlgeschlagen zählen. Neben HTTP-Anfragen können Probes eine TCP-Verbindung öffnen (tcpSocket), einen Befehl im Container ausführen (exec) oder gRPC nutzen.
Halte Liveness-Prüfungen einfach und auf den Prozess selbst bezogen. Schlägt eine Liveness-Probe fehl, weil eine Datenbank ausgefallen ist, startet Kubernetes gesunde Anwendungs-Container umsonst neu und kann einen Ausfall verschlimmern. Eine Readiness-Probe ist der richtige Ort, um Abhängigkeiten abzubilden. Readiness steuert auch Rolling Updates: Neue Pods zählen erst als verfügbar, wenn sie bereit sind.
Die Probe-Ergebnisse siehst du in kubectl describe pod, wo Fehlschläge in den Events erscheinen, und in kubectl get pods, wo eine fehlschlagende Readiness-Probe in der Spalte READY als 0/1 erscheint.
Beliebte Anleitungen
-
Was Kubernetes ist und welche Probleme es löst Warum Container allein nicht mehr skalieren und wie Kubernetes eine Gruppe von Maschinen zu einer Plattform macht. -
Wie ein Kubernetes-Cluster funktioniert: Control Plane und Knoten Die Komponenten, die einen Cluster am Laufen halten, und was zwischen kubectl apply und einem laufenden Container passiert. -
Deployments: Skalieren, Selbstheilung und Rolling Updates Betreibe Replikas eines Pods, aktualisiere sie ohne Ausfallzeit und rolle zurück, wenn ein Release schiefgeht. -
Services: Stabiles Networking für kurzlebige Pods Gib Pods eine stabile Adresse, stelle sie innerhalb und außerhalb des Clusters bereit und beschränke, wer mit wem sprechen darf. -
Einen fehlschlagenden Pod debuggen: describe, logs, exec und port-forward Eine wiederholbare Checkliste, um herauszufinden, warum ein Pod Pending ist, abstürzt oder nicht antwortet.