Kubernetes Deployments
07.06.2026
DevOps, Kubernetes, Kubernetes Deployments
Lerne in diesem Tutorial wie du Kubernetes Deployments verwenden kannst. Du lernst, wie du Deployments skalierst, was Rolling Updates sind, wie du mit den Parameter maxUnavailable und maxSurge die Update-Strategie feinjustierst und wie du die Anzahl der Replicasets bestimmst.
Inhaltsverzeichnis
Voraussetzungen
- laufender Kubernetes Cluster
kubectlist installiert und mit dem Cluster verbunden
Minimales Deployment
Schritt 1
Erstelle die Datei deployment.yaml mit folgendem Inhalt:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: web
image: nginx:1.31.0-alpine3.23
resources:
requests:
cpu: "50m"
memory: "16Mi"
limits:
cpu: "50m"
memory: "16Mi"
.metadata.namedefiniert, wie das Kubernetes Deployment heißt.spec.replicasdefiniert wieviele Pods im Deployment gestartet werden.spec.selectordefiniert die Labels, die die Pods des Deployments mindestens haben müssen.spec.templatedefiniert die Vorlage der Pods, die gestartet werden.spec.template.metadata.labelsenthält die Labels der Pods, diese Labels müssen mit.spec.selector.matchLabelsübereinstimmen, damit das Deployment weiß, welche Pods es verwalten soll
Schritt 2
Erstelle das Deployment mit folgendem Befehl in deinem Kubernetes Cluster:
kubectl apply -f deployment.yaml
Kubernetes meldet sich im Erfolgsfall mit deployment.apps/nginx created zurück.
Schritt 3
Überprüfe, dass das Deployment erfolgreich erstellt wurde:
kubectl get deploy/nginx
NAME READY UP-TO-DATE AVAILABLE AGE
nginx 1/1 1 1 113m
In der Spalte READY ist 1/1 zu sehen, das bedeutet 1 Pod läuft tatsächlich / 1 gewünschter Pod.
Skalierung
Ein Deployment kann horizontal skaliert werden, d.h. die Anzahl der Pods kann erhöht und reduziert werden.
Deployment skalieren
Skaliere das Deployment mit diesem Befehl auf 5 Replikas:
kubectl scale deploy/nginx --replicas 5
Überprüfe sofort danach, dass die Skalierung funktioniert hat:
kubectl get pods
Du solltest jetzt 5 nginx Pods sehen, die alle den Status Running haben.
Kubernetes erhält den Zustand des Deployments
Um das Self-Healing zu testen, wähle einen dieser Pods aus und lösche ihn:
kubectl get pods
NAME READY STATUS RESTARTS AGE
nginx-5589648df4-7qck7 1/1 Running 0 80m
nginx-5589648df4-9g952 1/1 Running 0 20s
nginx-5589648df4-jvjwc 1/1 Running 0 20s
nginx-5589648df4-pvlv7 1/1 Running 0 20s
nginx-5589648df4-sjq2s 1/1 Running 0 20s
kubectl delete pod/nginx-5589648df4-7qck7
dann wird dieser Pod tatsächlich auch entfernt, aber sofort durch das Deployment mit einem neuen nginx-Pod ersetzt. Das Deployment muss den eigenen Zustand mit 5 Pods erhalten. Mit kubectl get pods kann überprüft werden, dass ein neuer Pod tatsächlich gestartet wurde und erneut 5 nginx-Pods laufen.
Replikas reduzieren
Natürlich kann die Anzahl der Replicas eines Deployments auch reduziert werden, zum Beispiel auf 2:
kubectl scale deploy/nginx --replicas 2
Rolling Update
Öffne ein neues Terminal-Fenster und gebe dort den Befehl:
kubectl events --watch
ein. Du siehst nun in diesem Fenster die Kubernetes Events, die auftreten, wenn sich zum Beispiel der Zustand des Clusters ändert. Durch die --watch-Option werden die Events laufend angezeigt.
Events
Das Deployment hat momentan 2 Replicas. Skaliere es jetzt auf 3 Pods:
kubectl scale deploy/nginx --replicas 3
Du siehst im Event-Fenster anhand der Events, die dort angezeigt werden, dass ein neuer Pod erzeugt und gestartet wurde:
0s Normal ScalingReplicaSet Deployment/nginx Scaled up replica set nginx-788f9dcfbf from 2 to 3
0s Normal SuccessfulCreate ReplicaSet/nginx-788f9dcfbf Created pod: nginx-788f9dcfbf-hrb6p
0s Normal Scheduled Pod/nginx-788f9dcfbf-hrb6p Successfully assigned tutorials/nginx-788f9dcfbf-hrb6p to k3s
0s Normal Pulled Pod/nginx-788f9dcfbf-hrb6p Container image "nginx:1.31.0-alpine3.23" already present on machine and can be accessed by the pod
0s Normal Created Pod/nginx-788f9dcfbf-hrb6p Container created
0s Normal Started Pod/nginx-788f9dcfbf-hrb6p Container started
Das nginx-Deployment hat nun 3 Replikas.
Neue Version des Images
Starte den Watch auf die Events im Cluster mit folgendem Befehl:
kubectl events --watch | grep ScalingReplicaSet
d.h. wir interessieren uns lediglich für ScalingReplicaSet Events.
Nehmen wir mal an, dass das Deployment eine neue Version der Software benötigt, also nicht mehr das Image nginx:1.31.0-alpine3.23 sondern den Patch nginx:1.31.1-alpine3.23. Wir bauen hier das typische Szenario eines Versionsupdates der Software. Das Update des Images kann mit dem Befehl:
kubectl set image deploy/nginx web=nginx:1.31.1-alpine3.23
durchgeführt werden. Beobachte parallel zum kubectl set image ...-Befehl welche Events nun auftreten:
Scaled up replica set nginx-5644799d59 from 0 to 1
Scaled down replica set nginx-5589648df4 from 3 to 2
Scaled up replica set nginx-5644799d59 from 1 to 2
Scaled down replica set nginx-5589648df4 from 2 to 1
Scaled up replica set nginx-5644799d59 from 2 to 3
Scaled down replica set nginx-5589648df4 from 1 to 0
Das Deployment erhält ein neues Replicaset, das schrittweise um einen Pod hochskaliert wird, während gleichzeitig das alte Replicaset um einen Pod herunterskaliert wird. Dieses Verhalten wird auch Rolling Update genannt. Das heißt, die neue Version der Software wird schrittweise, Pod für Pod hochgefahren, während die alte Version schrittweise heruntergefahren wird.
Tritt ein Problem beim Hochfahren der neuen Version auf, so wird dieser Prozess gestoppt und die alte Version der Software läuft wie gehabt. D.h. der Benutzer der Software merkt gar nicht, dass das Deployment der neuen Version fehlgeschlagen ist.
Rollout Status und Undo
Mit dem Befehl
kubectl rollout status deploy/nginx
kann man sich den Status des Rollouts, also des Rolling Updates anschauen. Mit kubectl describe pod/nginx-... sieht man, dass die neuen Pods die richtige, gepatchte Version 1.31.1 des Images haben.
Containers:
web:
Container ID: containerd://1322934d3f030465bc27c480e9ce0a500e9ed8e1aa4d58295a8827cbeda8f594
Image: nginx:1.31.1-alpine3.23
...
Möchte man das Rollout des Images rückgängig machen, so hilft einem der Befehl:
kubectl rollout undo deploy/nginx
Man erhält dabei eine Warnung von Kubernetes, dass möglicherweise ein erneutes kubectl apply ... diesen Undo rückgängig machen könnte. Der Undo war aber trotz dieser Warnung erfolgreich und die Pods des nginx-Deployments haben nun erneut das ursprüngliche Image in der Version 1.31.0.
Strategie beim Update
Man kann die Strategie beim Updaten der Software im Deployment Manifest mit dem Parameter .spec.strategy.type einstellen. Grundsätzlich gibt es zwei Strategien:
RollingUpdatewird als Default verwendet und entspricht dem schrittweisen Hochfahren der neuen Version und gleichzeitig dem schrittweise Herunterfahren der alten Version der Software. Dieses Verhalten ist das was wir oben in diesem Tutorial schon gesehen haben.Recreatealle Pods des Deployments werden entfernt bevor die neuen hochgefahren werden.
Die RollingUpdate Strategie hat noch zwei zusätzliche Parameter mit denen man das Verhalten beim Rolling Update steuern kann:
-
.spec.strategy.rollingUpdate.maxUnavailablegibt an wieviele Pods insgesamt nicht verfügbar sein dürfen beim Update. Diese Zahl kann als ganze positive Anzahl von Pods angegeben werden oder als Prozentzahl der Replicas des Deployments. -
.spec.strategy.rollingUpdate.maxSurgegibt an wieviele Pods insgesamt über die reguläre Anzahl der Pods beim Update vorhanden sein dürfen. Hier wird der Wert auch entweder in Anzahl Pods oder als Prozentwert angegeben.
Beispiel maxUnavailable=0 und maxSurge=1
Wird maxUnavailable=0 und maxSurge=1 gesetzt:
spec:
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 0
maxSurge: 1
so wird sichergestellt, dass die Anzahl der tatsächlich laufenden Pods beim Update zu jedem Zeitpunkt der Anzahl der spezifizierten Replikas entspricht. Durch maxSurge=1 kann ein neuer Pod hochgefahren werden. Zu diesem Zeitpunkt überschreitet die Anzahl der tatsächlichen Pods die Anzahl der spezifizierten Pods um 1 und ein alter Pod kann heruntergefahren werden.
Dies ist eine sehr sichere aber gleichzeitig auch langsame Strategie beim Update eines Deployment. Man sieht hier auch, dass maxUnavailable und maxSurge nicht gleichzeitig 0 sein können.
Aufgabe maxUnavailable=100%
Erstelle ein nginx-Deployment mit 5 Replicas wie im obigen Beispiel in diesem Tutorial und setze nur maxUnavailable=100%. Führe ein Update auf eine neue Version durch und beobachte gleichzeitig mit kubectl events --watch | grep ScalingReplicaSet wie das Update durch Kubernetes durchgeführt wird.
Lösung:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 5
selector:
matchLabels:
app: nginx
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 100%
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: web
image: nginx:1.31.0-alpine3.23
resources:
requests:
cpu: "50m"
memory: "16Mi"
limits:
cpu: "50m"
memory: "16Mi"
Beobachtung der Events:
Scaled up replica set nginx-5644799d59 from 0 to 2
Scaled down replica set nginx-5589648df4 from 5 to 0
Scaled up replica set nginx-5644799d59 from 2 to 5
zeigt, dass ein neues Replicaset um 2 neue Pods erhöht wurde, danach das alte Replicaset auf 0 heruntergefahren wurde und anschließend das neue Replicaset auf 5 erhöht wurde. Warum ist das so? Man kann mit:
kubectl describe deploy/nginx
sehen, dass in der RollingUpdateStrategy der Wert maxUnavailable zwar gesetzt ist (siehe Deployment Manifest) aber der Default-Wert von maxSurge auf 25% steht. Damit werden zuerst 25% neue Pods (aufgerundet 2 Pods) hochgefahren, bevor alle alten Pods heruntergefahren werden und anschließend die neuen Pods komplett hochgefahren werden.
Werden beide Werte maxUnavailable und maxSurge nicht gesetzt, so gelten die Standardwerte von 25% für beide Werte.
Replicasets bereinigen
Beim Ausführen von Deployment Updates sind dir sicherlich die alten Replicasets aufgefallen, die von Kubernetes anscheinend nicht aufgeräumt werden. Die alten Replicasets werden aufbewahrt um ein Rollback mit Hilfe von kubectl rollout undo durchführen zu können. Im Standard werden maximal 10 Replicasets aufbewahrt.
Mit dem Parameter .spec.revisionHistoryLimit kann die Anzahl der aufbewahrten Replicasets geändert werden.
Aufgabe revisionHistoryLimit=1
Erstelle ein nginx-Deployment mit einem Pod wie oben in diesem Tutorial und setze im Deployment Manifest revisionHistoryLimit auf 1. Führe ein Rolling Update auf die Version nginx:1.31.1-alpine3.23 durch und beobachte die Anzahl der Replicasets. Führe erneut ein Rolling Update, diesmal auf die Version nginx:1.31.0-alpine3.23 und beobachte erneut die Anzahl der Replicasets.
Lösung:
Erstelle eine YAML-Datei mit folgendem Inhalt:
apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx
spec:
replicas: 1
revisionHistoryLimit: 1
selector:
matchLabels:
app: nginx
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: web
image: nginx:1.31.0-alpine3.23
resources:
requests:
cpu: "50m"
memory: "16Mi"
limits:
cpu: "50m"
memory: "16Mi"
erstelle das Deployment im Cluster und beobachte das Verhalten von Kubernetes:
kubectl set image deploy/nginx web=nginx:1.31.1-alpine3.23
kubectl get replicasets
kubectl set image deploy/nginx web=nginx:1.31.0-alpine3.23
kubectl get replicasets
Die Anzahl der “alten” Replicasets bleibt auf 1 und insgesamt hat man nach einem Rolling Update zwei Replicasets, das aktuell aktive und das alte.
Fazit
Du hast in diesem Tutorial folgendes gelernt:
- Deployments erstellen und skalieren,
- Rolling Updates durchführen und zurückrollen, dabei
- die Strategie beim Rolling Update justieren und
- die Anzahl der aufbewahrten Replicasets bestimmen.
Newsletter
Erhalte praxisnahe Tutorials, Best Practices und echte Lösungen für die häufigsten DevOps-Probleme direkt in Dein Postfach.
Datenschutz: Deine E-Mail-Adresse wird DSGVO-konform in Deutschland gespeichert. Keine Spam, nur relevante Inhalte. Eine E-Mail alle 1 bis 2 Wochen.