Deployments: Skalieren, Selbstheilung und Rolling Updates
Betreibe Replikas eines Pods, aktualisiere sie ohne Ausfallzeit und rolle zurück, wenn ein Release schiefgeht.
Pods sind Wegwerfware, und ein einzelner Pod, der stirbt, bleibt tot. Ein Deployment behebt das: Du deklarierst, wie viele Kopien du willst und welches Image laufen soll, und Kubernetes hält so viele am Laufen und übernimmt die Updates für dich. Diese Anleitung behandelt das Erstellen eines Deployments, das Skalieren, das Aktualisieren ohne Ausfallzeit und das Zurückrollen.
Warum du selten einzelne Pods erstellst
Fällt ein Knoten aus oder wird ein Pod gelöscht, erstellt nichts einen eigenständigen Pod neu. In der Praxis erstellst du Pods fast nie direkt. Du erstellst ein Deployment, das ein ReplicaSet erstellt, das wiederum die Pods erstellt und pflegt. Das Deployment ergänzt, was dem ReplicaSet fehlt: kontrollierte Updates und Versionshistorie.
Ein Deployment schreiben
apiVersion: apps/v1
kind: Deployment
metadata:
name: web
labels:
app: web
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: nginx
image: nginx:1.25
ports:
- containerPort: 80
Es gibt zwei metadata-Abschnitte, und es hilft, sie auseinanderzuhalten. Der obere beschreibt das Deployment. Der unter template beschreibt die Pods, die es erstellt, und das template ist schlicht ein Pod-Manifest ohne Namen. Der selector sagt dem Deployment, welche Pods zu ihm gehören, er muss also zu den Labels im Template passen, sonst lehnt Kubernetes das Manifest ab.
kubectl apply -f deployment.yaml
kubectl get deployment,replicaset,pods
Du siehst ein Deployment, ein ReplicaSet, benannt nach ihm plus einem Hash, und drei nach dem ReplicaSet benannte Pods.
Labels und Selector: wie Objekte einander finden
Labels sind Schlüssel-Wert-Paare, die du an jedes Objekt hängen kannst. Selector fragen sie ab, und so verbindet Kubernetes Dinge: Ein Deployment findet seine Pods, ein Service findet seine Backends, und eine Network Policy findet die Pods, die sie regelt.
kubectl get pods --show-labels
kubectl get pods -l app=web
Um zu sehen, wie sehr ein Selector zählt, entferne das Label von einem Pod:
kubectl label pod POD_NAME app-
kubectl get pods --show-labels
Das ReplicaSet zählt diesen Pod nicht mehr als seinen eigenen und startet einen Ersatz, um wieder auf drei zu kommen. Der umgelabelte Pod läuft weiter, aber nichts verwaltet ihn. Lösche ihn mit kubectl delete pod POD_NAME, damit er nicht herumliegt.
Skalieren und die Selbstheilung beobachten
kubectl scale deployment web --replicas=5
kubectl get pods -w
Lösche in einem anderen Terminal einen Pod und sieh zu, wie innerhalb von Momenten ein Ersatz erscheint. Um die Replikazahl dauerhaft zu ändern, bearbeite replicas im Manifest und wende es erneut an, da kubectl scale allein deine Datei veraltet zurücklässt. Die Pods eines Deployments wirst du nicht los, indem du sie löschst, da sie immer wiederkommen. Lösche das Deployment selbst oder skaliere es auf null.
Eine neue Version ausrollen
Eine Änderung an irgendetwas im Pod-Template, etwa dem Image, löst ein Rolling Update aus:
kubectl set image deployment/web nginx=nginx:1.26
kubectl rollout status deployment/web
Das Deployment erstellt ein zweites ReplicaSet für die neue Version und skaliert es dann schrittweise hoch, während es das alte herunterskaliert, sodass stets einige Pods Traffic bedienen. Standardmäßig erlaubt es bis zu 25 % zusätzliche Pods (maxSurge) und bis zu 25 % nicht verfügbare (maxUnavailable) während der Änderung. Du kannst das in der Spec anpassen:
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
Mit maxUnavailable: 0 wird ein alter Pod erst entfernt, wenn ein neuer bereit ist. Was „bereit“ heißt, entscheiden Readiness-Probes, die eine spätere Anleitung behandelt. Das Ändern der Replikazahl ist kein Rollout, da das Pod-Template unberührt bleibt.
Zurückrollen
Kubernetes behält die alten ReplicaSets, was das Zurückrollen schnell macht:
kubectl rollout history deployment/web
kubectl rollout undo deployment/web
kubectl rollout undo deployment/web --to-revision=1
undo kehrt zur vorherigen Revision zurück, und --to-revision wählt eine bestimmte. Die Zahl der behaltenen alten Revisionen setzt revisionHistoryLimit, standardmäßig 10. Eine Warnung: Liegen deine Manifeste in Git und etwas wie Argo CD wendet sie an, bevorzuge das Zurücknehmen des Commits gegenüber rollout undo. Das Undo ändert den Cluster, aber nicht Git, sodass beide voneinander abweichen, bis jemand abgleicht.
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. -
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.