Kubernetes Kubernetes

Workloads gesund halten: Namespaces, Ressourcen, Quotas und Probes

Teile einen Cluster fair mit Requests, Limits und Quotas und lass Kubernetes ungesunde Container erkennen.

15 min Fortgeschritten

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