Pod Status
Ziel
In diesem Projekt geht es um fortgeschrittene Techniken rund um Pods. Sie werden:
- Pod Status verstehen
 - mit Image Pull Secrets arbeiten
 - Pod-Probes definieren
 
Hilfsmittel
- Versuchen Sie, die unten stehenden Aufgaben mit Hilfe der Folien und des Cheatsheets eigenständig zu lösen.
 - Sollten Sie dabei Probleme haben, finden Sie bei jeder Aufgabe einen ausklappbaren Block, in dem der Lösungsweg beschrieben wird.
 
Aufgabe 1: Pod Status verstehen
Aufgabe 1.1: Pods mit einem erfolgreich abgeschlossenen Container
- Erstellen Sie eine YAML-Datei 
completed.yamlmit folgendem Inhalt: 
---
apiVersion: v1
kind: Pod
metadata:
  name: completed
  labels:
    exercise: pod-status
spec:
  containers:
  - name: completed
    image: alpine
    command:
    - "true"
  restartPolicy: Never
- Deployen Sie den Pod
 
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl apply -f completed.yaml
- Untersuchen Sie den Pod-Status (
.status.phase) und die Pod-Status Conditions (.status.conditions) mitkubectl get pod 
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl get pod completed -o json | jq .status.phase
kubectl get pod completed -o json | jq .status.conditions
Der Pod hat vier verschiedene Zustände durchlaufen, die sind:
PodScheduledbedeutet, dass der Pod einem Node zugewiesen wurde.Initializedbedeutet, dass alle initContainers erfolgreich abgeschlossen wurden.
Da wir keine initContainer haben, ist die Bedingung erfüllt.
ContainersReadybedeutet, dass alle Container im Pod bereit sind.Readybedeutet, dass der Pod Anfragen bearbeiten kann und allen passenden Services hinzugefügt werden sollten. Wie durchPodCompletedangezeigt, hat unser Pod denReady-Zustand bereits verlassen, weil der Containerprozess beendet wurde und die RestartPolicy einen Neustart verhinderte.
Leider ist die Reihenfolge der Bedingungen, wie sie in kubectl get pod erscheinen, nicht immer korrekt.
Aufgabe 1.2: Pods mit fehlerhaftem Container mit Neustarts
- Erstellen Sie eine YAML-Datei 
crashloopbackoff.yamlmit folgendem Inhalt: 
---
apiVersion: v1
kind: Pod
metadata:
  name: crashloopbackoff
  labels:
    exercise: pod-status
spec:
  containers:
  - name: crashloopbackoff
    image: alpine
    command:
    - "false"
  restartPolicy: Always
- Deployen Sie den Pod
 
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl apply -f crashloopbackoff.yaml
- Untersuchen Sie den Pod-Status (
.status.phase) und die Pod-Status Conditions (.status.conditions) mitkubectl get pod 
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl get pod crashloopbackoff -o json | jq .status.phase
kubectl get pod crashloopbackoff -o json | jq .status.conditions
Der Pod hat folgende Zustände durchlaufen:
PodScheduled: Der Pod wurde erfolgreich geplantInitialized: Der Pod hat den ZustandInitializederreicht, da es keine initContainers gibtContainersReady: Der Pod ist nicht bereit, da der Containerprozess sofort beendet wird und damit auch der Container beendet wird- 
Ready: Der Pod ist nicht bereit, da die RestartPolicy und der beendete Containerprozess eine Endlosschleife verursachen - 
Lassen Sie sich den ContainerStatus (
.status.containerStatuses) mitkubectl get podausgeben 
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl get pod crashloopbackoff -o json | jq .status.containerStatuses
Der Container befindet sich in einem "CrashLoopBackOff"-Zustand, weil der
Container mit einem Non-Zero-Exit-Code beendet wurde und die restartPolicy
den Pod dazu zwingt, den Container neu zu starten, bis er in einem
"Ready"-Zustand ist. Wir können auch sehen, ob Kubernetes den Container bereits
mehrmals neu gestartet hat. Standardmäßig wird alle 5 Minuten ein Neustart
ausgelöst.
Aufgabe 1.3: Pods mit einem fehlerhaften Container ohne Neustarts
- Erstellen Sie eine YAML-Datei 
error.yamlmit folgendem Inhalt: 
---
apiVersion: v1
kind: Pod
metadata:
  name: error
  labels:
    exercise: pod-status
spec:
  containers:
  - name: error
    image: alpine
    command:
    - "false"
  restartPolicy: Never
- Deployen Sie den Pod
 
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl apply -f error.yaml
- Untersuchen Sie den Pod-Status (
.status.phase) und die Pod-Status Conditions (.status.conditions) mitkubectl get pod 
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl get pod error -o json | jq .status.phase
Failed bedeutet, dass alle Container im Pod beendet wurden und mindestens ein
Container mit einem Fehler beendet wurde. Das bedeutet, dass der Container
entweder mit einem Non-Zero-Status beendet wurde oder vom System beendet
wurde.  In unserem Fall wurde der Containerbefehl false mit einem Non-Zero-Status
beendet.
Der Pod hat folgende Zustände durchlaufen:
PodScheduled: Der Pod wurde erfolgreich geplantInitialized: Der Pod hat den ZustandInitializederreicht, da es keine initContainers gibtContainersReady: Der Pod ist nicht bereit, da der Containerprozess sofort beendet wird und damit auch der Container beendet wird- 
Ready: Der Pod ist nicht bereit, da der Containerprozess mit einem Non-Zero-Exit-Code beendet wurde - 
Lassen Sie sich den ContainerStatus (
.status.containerStatuses) mitkubectl get podausgeben 
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl get pod error -o json | jq .status.containerStatuses
Der Container befindet sich in einem terminated-Zustand, da der Prozess mit
ExitCode 1 beendet wurde.
Aufgabe 1.4: Pods mit nicht existierendem Container-Image
- Erstellen Sie eine YAML-Datei 
imagepullbackoff.yamlmit folgendem Inhalt: 
---
apiVersion: v1
kind: Pod
metadata:
  name: imagepullbackoff
  labels:
    exercise: pod-status
spec:
  containers:
  - name: imagepullbackoff
    image: alpaine
  restartPolicy: Always
- Deployen Sie den Pod
 
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl apply -f imagepullbackoff.yaml
- Untersuchen Sie den Pod-Status (
.status.phase) und die Pod-Status Conditions (.status.conditions) mitkubectl get pod 
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl get pod imagepullbackoff -o json | jq .status.phase
kubectl get pod imagepullbackoff -o json | jq .status.conditions
Der Pod hat folgende Zustände durchlaufen:
Pendingbedeutet, dass der Pod akzeptiert wurde, aber mindestens einer der Container nicht eingerichtet und bereit zum Ausführen ist. Dies beinhaltet die Zeit, die ein Pod darauf wartet, geplant zu werden, sowie die Zeit, die zum Herunterladen von Container-Images über das Netzwerk benötigt wird.
In unserem Fall schlägt das Herunterladen von Container-Images über das Netzwerk fehl.
Die Pod-Status Conditions sind die gleichen wie in Aufgabe 2, außer dass der Loopback-Grund "imagepullbackoff" anstelle von "crashloopbackoff" ist.
- Lassen Sie sich den ContainerStatus (
.status.containerStatuses) mitkubectl get podausgeben 
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl get pod imagepullbackoff -o json | jq .status.containerStatuses
Der Container befindet sich in einem "waiting"-Zustand, weil das Container-Image nicht gefunden wurde, aber Kubernetes wird versuchen, das Image erneut herunter zu laden.
- Führen Sie 
kubectl describeaus, um die Pod-Events zu untersuchen 
Der Pod wurde geplant und Kubernetes hat versucht, das Image "alpaine"
herunterzuladen.  Das schlägt jedoch fehl, da das Repository nicht existiert.
Der Status ErrImagePull bedeutet, dass das Herunterladen des Images
fehlgeschlagen ist, was als nicht-permanenter Fehler interpretiert wird.
Deshalb ändert sich der Pod-Status in "ImagePullBackOff", was bedeutet, dass
Kubernetes versucht, das Image erneut herunterzuladen.
Aufgabe 2: Image Pull Secrets nutzen
Aufgabe 2.1: Pull Secret erstellen
- Verwenden Sie 
kubectl create secret docker-registryum ein Pull Secret mit dem Namenregistry.corewire.iound den folgenden Einstellungen zu erstellen:- docker-server: 
registry.corewire.io - docker-username: 
${COREWIRE_TRAINING_REGISTRY_USER} - docker-password: 
${COREWIRE_TRAINING_REGISTRY_TOKEN} 
 - docker-server: 
 - Die Variablen $COREWIRE_TRAINING_REGISTRY_USER und $COREWIRE_TRAINING_REGISTRY_TOKEN sind schon für Sie gesetzt
 
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl create secret docker-registry registry.corewire.io \
--docker-server=registry.corewire.io \
--docker-username=${COREWIRE_TRAINING_REGISTRY_USER} \
--docker-password=${COREWIRE_TRAINING_REGISTRY_TOKEN}
- Untersuchen Sie das Secret mit
 
kubectl get secrets registry.corewire.io -o yaml
Aufgabe 2.2: Pod erstellen
- Erstellen Sie eine Datei 
pull-secret.yamlmit der Beschreibung eines Pods, der:- das imagePullSecrets 
registry.corewire.ioverwendet - das Container-Image 
registry.corewire.io/hands-on/docker-demoapp:1.0.0verwendet - den Port 5000 freigibt
 
 - das imagePullSecrets 
 
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
---
apiVersion: v1
kind: Pod
metadata:
  name: pull-secret
spec:
  imagePullSecrets:
  - name: registry.corewire.io
  containers:
  - name: demoapp
    image: registry.corewire.io/hands-on/docker-demoapp:1.0.0
    ports:
    - name: web
      containerPort: 5000
- Deployen Sie den Pod
 
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl apply -f pull-secret.yaml
- Überprüfen Sie den Pod mit 
kubectl get podund stellen Sie sicher, dass er sich im Zustand "Running" befindet - Lassen Sie sich den Pod mit 
kubectl get pod pull-secret -o yamlanzeigen und überprüfen Sie, ob das ImagePullSecret korrekt konfiguriert ist 
Aufgabe 2.3: Zum Pod verbinden
- Verbinden Sie sich mit dem Pod durch Port-Forwarding.
 
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl port-forward pods/pull-secret 8082:5000
- Überprüfen Sie, ob die Demoapp erreichbar ist.
 
Aufgabe 3: Probes (Optional)
Aufgabe 3.1: Web Server Liveness Probe
Sie erhalten ein Basismanifest für ein Webserver-Deployment. Ihre Aufgabe ist es, eine Liveness-Probe hinzuzufügen, um den Webserver-Container neu zu starten, wenn er nicht mehr reagiert.
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-server
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web-server
  template:
    metadata:
      labels:
        app: web-server
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
- Fügen Sie der Container-Spezifikation eine HTTP-Liveness-Probe hinzu, um den
Root-Pfad 
/auf Port80zu überprüfen 
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-server
  labels:
    exercise: probes
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web-server
  template:
    metadata:
      labels:
        app: web-server
    spec:
      containers:
      - name: nginx
        image: nginx:latest
        ports:
        - containerPort: 80
        livenessProbe:
          httpGet:
            path: /
            port: 80
- Wenden Sie das aktualisierte Manifest an
 
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl apply -f web-server.yaml
- Beobachten Sie das Deployment mit den Befehlen 
kubectl get podsundkubectl describe pod 
Aufgabe 3.2: Datenbank-Readiness-Probe
Passen Sie das Basismanifest für ein MySQL-Datenbank-Deployment an, indem Sie eine Readiness-Probe hinzufügen. Diese Probe sollte sicherstellen, dass die Datenbank bereit ist, Verbindungen zu akzeptieren, bevor sie als bereit markiert wird.
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-db
  labels:
    exercise: probes
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql-db
  template:
    metadata:
      labels:
        app: mysql-db
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "password"
        ports:
        - containerPort: 3306
- Fügen Sie der Container-Spezifikation eine Readiness-Probe hinzu, um die
Datenbankbereitschaft mit dem Befehl 
mysqladmin pingzu überprüfen 
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: mysql-db
  labels:
    exercise: probes
spec:
  replicas: 1
  selector:
    matchLabels:
      app: mysql-db
  template:
    metadata:
      labels:
        app: mysql-db
    spec:
      containers:
      - name: mysql
        image: mysql:5.7
        env:
        - name: MYSQL_ROOT_PASSWORD
          value: "password"
        ports:
        - containerPort: 3306
        readinessProbe:
          exec:
            command:
            - mysqladmin
            - ping
- Wenden Sie das aktualisierte Manifest an
 
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl apply -f mysql-db.yaml
- Beobachten Sie das Deployment mit den Befehlen 
kubectl get podsundkubectl describe pod 
Aufgabe 3.3: Exec Liveness Probe zur Selbstheilung
Das folgende Manifest startet eine benutzerdefinierte Anwendung basierend auf Alpine
Linux. Es enthält eine exec Liveness-Probe, die das Vorhandensein einer
bestimmten Datei überprüft. Wenn die Datei nicht vorhanden ist, sollte die Probe
fehlschlagen und darauf hinweisen, dass die Anwendung in einem schlechten
Zustand ist.
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: custom-app
  labels:
    exercise: probes
spec:
  replicas: 1
  selector:
    matchLabels:
      app: custom-app
  template:
    metadata:
      labels:
        app: custom-app
    spec:
      containers:
      - name: alpine-app
        image: alpine:latest
        command: ["/bin/sh", "-c"]
        args: ["touch /tmp/alive; sleep 15; rm -f /tmp/alive; sleep 600"]
        livenessProbe:
          exec:
            command:
            - cat
            - /tmp/alive
          initialDelaySeconds: 5
          periodSeconds: 5
          failureThreshold: 3
- Wenden Sie das Manifest an
 
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl apply -f custom-app.yaml
- Überwachen Sie das Verhalten der Liveness-Probe mit dem Befehl 
kubectl get events -w - Untersuchen Sie den Status des Pods mit 
kubectl describe pod - Sie können auch mit den Eigenschaften 
initialDelaySeconds,periodSecondsundfailureThresholdspielen, um das Verhalten der Liveness-Probe besser zu verstehen 
Aufgabe 3.4: Redis TCP Liveness Probe
- Passen Sie folgendes Basismanifest für ein Redis-Deployment an. Ihre Aufgabe ist es, eine TCP-Liveness-Probe hinzuzufügen, um sicherzustellen, dass der Redis-Server reagiert.
 
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-server
  labels:
    app: redis
    exercise: probes
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: redis:alpine
        ports:
        - containerPort: 6379
- Fügen Sie der Container-Spezifikation eine TCP-Liveness-Probe hinzu, um Port 
6379zu überprüfen 
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
apiVersion: apps/v1
kind: Deployment
metadata:
  name: redis-server
  labels:
    app: redis
    exercise: probes
spec:
  replicas: 1
  selector:
    matchLabels:
      app: redis
  template:
    metadata:
      labels:
        app: redis
    spec:
      containers:
      - name: redis
        image: redis:alpine
        ports:
        - containerPort: 6379
    livenessProbe:
      tcpSocket:
        port: 6379
      initialDelaySeconds: 15
      periodSeconds: 20
- Wenden Sie das aktualisierte Manifest an
 
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl apply -f redis-deployment.yaml
- Beobachten Sie das Deployment mit den Befehlen 
kubectl get podsundkubectl describe pod 
Aufgabe 3.5: Startup Probes
Das Kubelet verwendet Startup-Probes, um zu wissen, wann eine Container-Anwendung gestartet ist. Wenn eine solche Probe konfiguriert ist, starten Liveness- und Readiness-Probes erst, wenn die Startup-Probe erfolgreich ist. Das stellt sicher, dass diese Probes nicht mit dem Anwendungsstart interferieren. Dies kann verwendet werden, um Liveness-Checks auf langsam startenden Containern zu übernehmen, um zu verhindern, dass sie vom Kubelet neugestartet werden, bevor sie vollständig gestartet sind.
- Sie erhalten ein Basismanifest für ein Deployment, das eine Anwendung startet, die 15 Sekunden benötigt, um vollständig zu starten
 
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: slow-startup-app
  labels:
    exercise: probes
spec:
  replicas: 1
  selector:
    matchLabels:
      app: slow-startup-app
  template:
    metadata:
      labels:
        app: slow-startup-app
    spec:
      containers:
      - name: alpine-app
        image: alpine:latest
        command: ["/bin/sh", "-c"]
        args: ["sleep 15; touch /tmp/alive; sleep infinity"]
        livenessProbe:
          exec:
            command:
            - cat
            - /tmp/alive
          initialDelaySeconds: 1
          periodSeconds: 5
          failureThreshold: 2
        readinessProbe:
          exec:
            command:
            - cat
            - /tmp/alive
          initialDelaySeconds: 1
          periodSeconds: 2
          failureThreshold: 5
- Wenden Sie das gegebenen Manifest an
 - Beobachten Sie das Verhalten des Containers mit den Befehlen 
kubectl get events -wundkubectl describe pod 
Sie sollten sehen, dass der Container neu gestartet wird, wenn die Liveness- und Readiness-Probes fehlschlagen, bevor die Startup-Probe erfolgreich ist.
- Fügen Sie der Container-Spezifikation eine Startup-Probe hinzu, um das Vorhandensein der Datei 
/tmp/alivezu überprüfen. Konfigurieren Sie die Probe mit:initialDelaySeconds: 10periodSeconds: 5failureThreshold: 30
 
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: slow-startup-app
  labels:
    exercise: probes
spec:
  replicas: 1
  selector:
    matchLabels:
      app: slow-startup-app
  template:
    metadata:
      labels:
        app: slow-startup-app
    spec:
      containers:
      - name: alpine-app
        image: alpine:latest
        command: ["/bin/sh", "-c"]
        args: ["sleep 15; touch /tmp/alive; sleep infinity"]
        livenessProbe:
          exec:
            command:
            - cat
            - /tmp/alive
          initialDelaySeconds: 1
          periodSeconds: 5
          failureThreshold: 2
        readinessProbe:
          exec:
            command:
            - cat
            - /tmp/alive
          initialDelaySeconds: 1
          periodSeconds: 2
          failureThreshold: 5
        startupProbe:
          exec:
            command:
            - cat
            - /tmp/alive
          initialDelaySeconds: 10
          periodSeconds: 5
          failureThreshold: 30
- Wenden Sie das aktualisierte Manifest an
 - Beobachten Sie das Verhalten des Containers mit den Befehlen 
kubectl get events -wundkubectl describe pod 
Cleanup
- Löschen Sie alle Objekte die Sie erstellt haben mit 
kubectl delete