Pod Management 2
Ziel
In diesem Projekt geht es um fortgeschrittene Techniken zur Erstellung von Pods. Sie werden:
- StatefulSets, (Cron-)Jobs und DaemonSets erstellen
- Unterschiedliche Deployment-Strategien anwenden
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.
- StatefulSets, DaemonSets und Jobs werden auch in der offiziellen Kubernetes-Dokumentation erklärt.
Aufgabe 1: StatefulSet
Aufgabe 1.1: StatefulSets skalieren
Erstellen Sie eine Datei statefulset-scaling.yaml
mit dem folgenden Inhalt:
---
apiVersion: v1
kind: Service
metadata:
name: db-headless
labels:
app: blog
component: db
spec:
ports:
- port: 3306
name: mysql
clusterIP: None
selector:
app: blog
component: db
---
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: db
labels:
app: blog
component: db
spec:
serviceName: db
replicas: 1
minReadySeconds: 10
selector:
matchLabels:
app: blog
component: db
template:
metadata:
labels:
app: blog
component: db
spec:
containers:
- name: mysql
image: mysql:5
env:
- name: MYSQL_RANDOM_ROOT_PASSWORD
value: "yes"
- name: MYSQL_DATABASE
value: wordpress
- name: MYSQL_USER
value: wordpress
- name: MYSQL_PASSWORD
value: "notthesecret"
ports:
- name: mysql
containerPort: 3306
- Deployen Sie das StatefulSet
- Überprüfen Sie, ob das StatefulSet erfolgreich erstellt wurde
- Lassen Sie sich das StatefulSet und den Pod anzeigen mit
kubectl get all
- Lassen Sie dieses Terminal offen und beobachten Sie es bei den weiteren Schritten
watch kubectl get all
- Skalieren Sie das StatefulSet auf 4 Pods
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl scale statefulset db --replicas=4
- Löschen Sie einen oder mehrere Pods und beobachten Sie, wie Kubernetes die Pods wiederherstellt
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl delete pod db-3
kubectl delete pod db-1
- Skalieren Sie das StatefulSet auf 2 Pods
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl scale statefulset db --replicas=2
Aufgabe 1.2: StatefulSets updaten
- Skalieren Sie das StatefulSet aus der vorherigen Aufgabe wieder auf 4 Pods
indem Sie die
yaml
-Datei bearbeiten und das Update durchführen
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl apply -f statefulset-scaling.yaml
- Ändern Sie das Image des Containers auf
mysql:8.3
und führen Sie ein Update des StatefulSets durch - Beachten Sie dabei, dass das Update der Pods sequentiell erfolgt
Aufgabe 1.3: DNS in StatefulSets
- Starten Sie einen interaktiven Busybox-Pod
- Führen Sie
nslookup
auf den Servicedb-headless
aus
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl run -it --rm busybox --image=busybox --restart=Never -- sh
nslookup db-headless
- Sie sollten eine Ausgabe ähnlich der folgenden erhalten:
Name: db-headless.default.svc.cluster.local
Address: 10.42.129.48
Name: db-headless.default.svc.cluster.local
Address: 10.42.129.219
Name: db-headless.default.svc.cluster.local
Address: 10.42.128.250
Name: db-headless.default.svc.cluster.local
Address: 10.42.129.126
Aufgabe 2: DaemonSets
- Die offizielle Dokumentation zu DaemonSets finden Sie hier
- DaemonSets sind eine spezielle Art von Controller, die Pods auf jedem Node im Cluster starten
Aufgabe 2.1: Skalierung und Scheduling von DaemonSets
- Ein typisches Anwendungsbeispiel für DaemonSets ist das Starten eines Monitoring-Agents auf jedem Node im Cluster
- Erstellen Sie eine Datei
daemonset.yaml
und fügen Sie das DaemonSet-Manifest hinzu:
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: node-exporter
labels:
app: monitoring
component: node-exporter
exercise: daemonsets
spec:
selector:
matchLabels:
app: monitoring
component: node-exporter
template:
metadata:
labels:
app: monitoring
component: node-exporter
spec:
containers:
- name: node-exporter
image: prom/node-exporter
ports:
- containerPort: 9100
- Deployen Sie das DaemonSet
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl apply -f daemonset.yaml
- Überprüfen Sie, ob das DaemonSet erfolgreich erstellt wurde
- Lassen Sie sich das DaemonSet und die Pods anzeigen mit
kubectl get all -o wide
Durch das Flag -o wide
erhalten Sie zusätzliche Informationen zu den Pods, wie
z.B. den Node, auf dem sie laufen. Damit können Sie überprüfen, ob das DaemonSet
auf jedem Node im Cluster Pods erstellt hat.
- Löschen Sie das DaemonSet
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl delete daemonset node-exporter
Aufgabe 3: Jobs (Optional)
Aufgabe 3.1: Einfacher Job
Erstellen Sie eine Datei job.yaml
und fügen Sie das folgende Job-Manifest hinzu:
---
apiVersion: batch/v1
kind: Job
metadata:
name: echo-hello
labels:
exercise: jobs
spec:
template:
spec:
containers:
- name: echo-hello
image: alpine
command: ["echo", "Hello"]
restartPolicy: Never
- Deployen Sie den Job
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl apply -f job.yaml
- Untersuchen Sie den Job mit
kubectl get jobs
undkubectl describe job echo-hello
- Untersuchen Sie den Pod, der vom Job erstellt wurde, mit
kubectl get pods
undkubectl describe pod echo-hello-<hash>
- Untersuchen Sie die Logs des Pods mit
kubectl logs echo-hello
- Löschen Sie den Job
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl delete job echo-hello
Aufgabe 3.2: Parallelisierung von Jobs
Erstellen Sie eine Datei job-parallel.yaml
und fügen Sie das folgende Job-Manifest hinzu:
---
apiVersion: batch/v1
kind: Job
metadata:
name: echo-hello-parallel
labels:
exercise: jobs
spec:
template:
spec:
containers:
- name: echo-hello
image: alpine
command: ["echo", "Hello"]
restartPolicy: Never
- Erweitern Sie das Job-Manifest um
parallelism: 2
undcompletions: 6
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
apiVersion: batch/v1
kind: Job
metadata:
name: echo-hello-parallel
labels:
exercise: jobs
spec:
parallelism: 2
completions: 6
template:
spec:
containers:
- name: echo-hello
image: alpine
command: ["echo", "Hello"]
restartPolicy: Never
- Deployen Sie den Job
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl apply -f job-parallel.yaml
- Beobachten Sie die vom Job erstellten Pods mit
watch kubectl get pods
- Untersuchen Sie den Job mit
kubectl get jobs
undkubectl describe job echo-hello-parallel
- Untersuchen Sie die vom Job erstellten Pods mit
kubectl get pods
- Löschen Sie den Job
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl delete job echo-hello-parallel
Aufgabe 3.3: Umgang mit fehlgeschlagenen Jobs
- Erstellen Sie eine Datei
job-failing.yaml
und fügen Sie das folgende Job-Manifest hinzu:
---
apiVersion: batch/v1
kind: Job
metadata:
name: failing-job
labels:
exercise: jobs
spec:
backoffLimit: 3
template:
spec:
containers:
- name: failing
image: alpine
command: ["sh", "-c", "echo failing && sleep 5 && exit 1"]
restartPolicy: Never
- Deployen Sie den Job
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl apply -f job-failing.yaml
- Untersuchen Sie den Job mit
kubectl get jobs
undkubectl describe job failing-job
- Beobachten Sie die vom Job erstellten Pods mit
watch kubectl get pods
- Sie sollten sehen, dass die Pods erstellt werden und nach 5 Sekunden fehlschlagen
- Dies wird nur 3 Mal passieren, da dies das Backoff-Limit ist, das wir mit
.spec.backoffLimit
festgelegt haben - Fehlgeschlagene Pods, die mit dem Job verbunden sind, werden vom Job-Controller mit einer exponentiellen Backoff-Verzögerung (10s, 20s, 40s ...) erstellt, die auf sechs Minuten begrenzt ist
- Löschen Sie den Job
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl delete job failing-job
- Ändern Sie die restart policy des Jobs auf
OnFailure
und deployen Sie den Job erneut
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
apiVersion: batch/v1
kind: Job
metadata:
name: failing-job
spec:
backoffLimit: 3
template:
spec:
containers:
- name: failing
image: alpine
command: ["sh", "-c", "echo failing && sleep 5 && exit 1"]
restartPolicy: OnFailure
- Beobachten Sie die vom Job erstellten Pods mit
watch kubectl get pods
- Lassen Sie sich Details zum Job ausgeben
- Wie unterscheidet sich das Verhalten von dem vorherigen Job?
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
- Sie können sehen, dass der Container nach einem Fehler neu gestartet wird
- Der Container wird 3 Mal neu gestartet, da dies das Backoff-Limit ist, das wir mit
.spec.backoffLimit
festgelegt haben - Nach dem dritten Fehler wird der Job als fehlgeschlagen markiert und der Pod beendet
- Löschen Sie den Job
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl delete job failing-job
Aufgabe 4: CronJobs (Optional)
Erstellen Sie eine Datei cronjob.yaml
und fügen Sie das folgende CronJob-Manifest hinzu:
---
apiVersion: batch/v1
kind: CronJob
metadata:
name: hello-every-minute
labels:
exercise: jobs
spec:
schedule: "*/1 * * * *"
jobTemplate:
spec:
template:
spec:
containers:
- name: hello
image: alpine
command: ["echo", "Hello"]
restartPolicy: OnFailure
- Deployen Sie den CronJob
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl apply -f cronjob.yaml
- Untersuchen Sie den CronJob mit
kubectl get cronjobs
undkubectl describe cronjob hello-every-minute
- Nach einer Minute wird der Controller einen Job und einen Pod erstellen
- Untersuchen Sie den Job mit
kubectl get jobs
undkubectl describe job hello-every-minute-<hash>
- Untersuchen Sie den Pod, der vom Job erstellt wurde, mit
kubectl get pods
- Löschen Sie den CronJob
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl delete cronjob hello-every-minute
Aufgabe 5: Deployment-Strategien (Optional)
- Die offizielle Dokumentation zur rollingUpdate-Strategie finden Sie hier
Aufgabe 5.1: Erstellen und Untersuchen eines Deployments mit RollingUpdate-Strategie
- Erstellen Sie eine Datei
rolling.yaml
und fügen Sie das folgende Deployment-Manifest hinzu:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: rolling-update
labels:
exercise: deployment-strategies
spec:
strategy:
rollingUpdate:
maxSurge: 25%
maxUnavailable: 25%
replicas: 10
selector:
matchLabels:
app: rolling
template:
metadata:
labels:
app: rolling
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
- Deployen Sie das Deployment
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl apply -f rolling.yaml
- Überprüfen Sie, ob das Deployment erfolgreich erstellt wurde
- Lassen Sie sich das Deployment und die ReplicaSets anzeigen mit
kubectl get all
- Verändern Sie das Deployment, indem Sie das
imagePullPolicy
aufAlways
setzen - Beobachten Sie die Änderungen, die an den ReplicaSets vorgenommen werden
Aufgabe 5.2: Erstellen und Untersuchen eines Deployments mit Recreate-Strategie
- Erstellen Sie eine Datei
recreate.yaml
und fügen Sie das folgende Deployment-Manifest hinzu:
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: recreate
labels:
exercise: deployment-strategies
spec:
strategy:
type: Recreate
replicas: 10
selector:
matchLabels:
app: recreate
template:
metadata:
labels:
app: recreate
spec:
containers:
- name: nginx
image: nginx
imagePullPolicy: IfNotPresent
- Deployen Sie das Deployment
Lösung (Klicken Sie auf den Pfeil, falls Sie nicht weiterkommen)
kubectl apply -f recreate.yaml
- Überprüfen Sie, ob das Deployment erfolgreich erstellt wurde
- Lassen Sie sich das Deployment und die ReplicaSets anzeigen mit
kubectl get all
- Verändern Sie das Deployment, indem Sie das
imagePullPolicy
aufAlways
setzen - Beobachten Sie die Änderungen, die an den ReplicaSets vorgenommen werden
Cleanup
- Löschen Sie alle erstellten Ressourcen