Führen Sie kubectl run nginx --image=nginx:1.27 aus, und Kubernetes erstellt genau einen Pod namens nginx. Löschen Sie ihn mit kubectl delete pod nginx, und er ist endgültig weg — niemand bemerkt es, niemand ersetzt ihn. Ein Pod ist die kleinste bereitstellbare Einheit in Kubernetes: ein oder mehrere Container, die sich einen Netzwerk-Namespace und eine Reihe von Volumes teilen und zusammen auf einem einzelnen Node eingeplant werden.

Dieser einzelne Pod ist in Produktion eine Sackgasse. Stürzt der Container darin ab, startet der kubelet ihn an Ort und Stelle neu. Startet der Node neu, oder löscht jemand den Pod, stellt ihn nichts wieder her. Ein nackter Pod weiß nicht, dass er eigentlich existieren sollte.

Was ein Deployment zu einem Pod hinzufügt

Ein Deployment ist ein Kubernetes-Objekt, das festlegt, wie viele Kopien eines Pods existieren sollen und wie Änderungen an ihnen ausgerollt werden. Sie verwalten Pods nicht mehr direkt, sondern beschreiben den gewünschten Zustand; eine Kontrollschleife sorgt fortlaufend dafür, dass dieser Zustand eintritt. Es ist dasselbe Reconciliation-Modell, das hinter allem anderen in Kubernetes steckt.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web-app
  template:
    metadata:
      labels:
        app: web-app
    spec:
      containers:
        - name: web-app
          image: nginx:1.27
          ports:
            - containerPort: 80
1
2
kubectl apply -f web-app-deployment.yaml
kubectl get pods
1
2
3
4
NAME                       READY   STATUS    RESTARTS   AGE
web-app-7d9f8c7b86-4kxqz   1/1     Running   0          8s
web-app-7d9f8c7b86-9wj2p   1/1     Running   0          8s
web-app-7d9f8c7b86-x2p6t   1/1     Running   0          8s

Drei Pods, nicht einer, und keiner heißt web-app. Dieses Namensmuster (web-app-7d9f8c7b86-4kxqz) ist ein erstes Anzeichen dafür, dass etwas anderes sie verwaltet.

replicas: 3 ist dieselbe Anweisung wie docker compose up --scale web=3 in Docker Compose. Der Unterschied ist, dass hier ein Controller diese Zahl durchsetzt, lange nachdem der Befehl abgeschlossen ist.

Wie ein Deployment tatsächlich Pods erstellt: das ReplicaSet dazwischen

Ein Deployment erstellt Pods nicht direkt. Es erstellt ein ReplicaSet, und das ReplicaSet erstellt die Pods. Sie können die ganze Kette sehen:

1
2
3
kubectl get deployment web-app
kubectl get replicaset -l app=web-app
kubectl get pods -l app=web-app
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
NAME      READY   UP-TO-DATE   AVAILABLE   AGE
web-app   3/3     3            3           2m

NAME                 DESIRED   CURRENT   READY   AGE
web-app-7d9f8c7b86   3         3         3       2m

NAME                       READY   STATUS    RESTARTS   AGE
web-app-7d9f8c7b86-4kxqz   1/1     Running   0          2m
web-app-7d9f8c7b86-9wj2p   1/1     Running   0          2m
web-app-7d9f8c7b86-x2p6t   1/1     Running   0          2m

Der Name des ReplicaSets ist der Name des Deployments plus ein Hash der Pod-Vorlage (7d9f8c7b86); der Name jedes Pods ist der Name des ReplicaSets plus ein zufälliges Suffix. kubectl describe pod web-app-7d9f8c7b86-4kxqz zeigt die Beziehung direkt im Feld Controlled By: ReplicaSet/web-app-7d9f8c7b86.

Löschen Sie einen dieser Pods, und die Anzahl sinkt auf 2. Innerhalb von Sekunden erscheint ein Ersatz. Das ReplicaSet bemerkt die Lücke und erstellt einen neuen Pod aus derselben Vorlage — nicht das Deployment, das direkt eingreift. Das ReplicaSet übernimmt die Überwachung. Das Deployment existiert für die eine Sache, die ein ReplicaSet allein nicht kann: eine Pod-Vorlage schrittweise statt auf einmal zu ersetzen.

Was ein Rollout mit den ReplicaSets macht

Ändern Sie das Image und wenden Sie es an:

1
2
kubectl set image deployment/web-app web-app=nginx:1.27.1
kubectl rollout status deployment/web-app
1
2
3
Waiting for deployment "web-app" rollout to finish: 1 out of 3 new replicas have been updated...
Waiting for deployment "web-app" rollout to finish: 2 out of 3 new replicas have been updated...
deployment "web-app" successfully rolled out

Hinter dieser Statuszeile hat das Deployment ein zweites ReplicaSet für die neue Pod-Vorlage erstellt und hochskaliert, während es das alte herunterskaliert hat. Mit der Standardstrategie RollingUpdate bei 3 Replicas läuft das auf einen Pod nach dem anderen hinaus:

1
kubectl get replicaset -l app=web-app
1
2
3
NAME                 DESIRED   CURRENT   READY   AGE
web-app-7d9f8c7b86   0         0         0       6m
web-app-6b8f6d9c4d   3         3         3       40s

Das alte ReplicaSet wird nicht gelöscht. Es bleibt bei null Replicas und behält die vorherige Pod-Vorlage bei. Das macht das Rollback schnell:

1
kubectl rollout undo deployment/web-app

Kubernetes skaliert das alte ReplicaSet wieder hoch und das neue herunter — kein erneuter Build, kein erneuter Pull eines alten Images, wenn es auf dem Node noch im Cache liegt. kubectl rollout history deployment/web-app --revision=1 zeigt immer noch genau, welches Image diese Revision ausgeführt hat.

Wann ein nackter Pod die richtige Wahl ist

Ein nackter Pod ist nicht in jedem Kontext ein Fehler, nur in den meisten:

  1. Ein einmaliger Diagnose-Container, den Sie in fünf Minuten wieder löschen: kubectl run debug --image=busybox -it --rm -- sh.
  2. Ein Job oder CronJob, der über seinen eigenen Controller Pods erstellt, weil die Arbeit bis zum Abschluss laufen muss, statt dauerhaft aktiv zu bleiben.
  3. Das Untersuchen oder Kennenlernen der Pod-Spec selbst, bevor sie in etwas verpackt wird, das sie verwaltet.

Alles, was einen Absturz, einen Node-Ausfall oder ein Update überstehen soll, läuft über ein Deployment. Oder über ein StatefulSet, für Pods, die eine stabile Identität und eigenen Storage brauchen — ein anderes Problem und ein anderes Objekt. Schreiben Sie standardmäßig das Deployment-Manifest und greifen Sie nur in den drei genannten Fällen auf einen nackten Pod zurück.

Pod, ReplicaSet und Deployment im Vergleich

PodReplicaSetDeployment
Was es verwaltetContainerPodsReplicaSets
Ersetzt eine gelöschte InstanzNeinJaJa, über sein ReplicaSet
Skaliert auf N ReplicasNeinJaJa
Rolling UpdatesNeinNeinJa
Rollback auf eine frühere VersionNeinNeinJa
Sie erstellen es direktSeltenFast nieNormalerweise

Prüfen Sie, ob Ihre eigenen Pods ein Deployment dahinter haben

Führen Sie den folgenden Befehl gegen das aus, was in Ihrem Cluster bereits läuft:

1
kubectl get deployment,replicaset,pod -l app=<ihr-label>

Kommen nur Pod-Zeilen zurück, sind das nackte Pods. Das ist die Lücke, die Sie schließen sollten, bevor der nächste Node-Drain die App gleich mit wegräumt.

Verwandte Artikel