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

  1. laufender Kubernetes Cluster
  2. kubectl ist 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"
  1. .metadata.name definiert, wie das Kubernetes Deployment heißt
  2. .spec.replicas definiert wieviele Pods im Deployment gestartet werden
  3. .spec.selector definiert die Labels, die die Pods des Deployments mindestens haben müssen
  4. .spec.template definiert die Vorlage der Pods, die gestartet werden
  5. .spec.template.metadata.labels enthä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:

  1. RollingUpdate wird 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.
  2. Recreate alle 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:

  1. .spec.strategy.rollingUpdate.maxUnavailable gibt 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.

  2. .spec.strategy.rollingUpdate.maxSurge gibt 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:

  1. Deployments erstellen und skalieren,
  2. Rolling Updates durchführen und zurückrollen, dabei
  3. die Strategie beim Rolling Update justieren und
  4. 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.