Die richtige Workload-Ressource wählen

KubernetesBeginner
Jetzt üben

Einführung

Bei CKAD-Aufgaben wird oft erwartet, dass du die richtige Kubernetes-Workload-Ressource auswählst, bevor du ein Manifest erstellst. Ein Pod ist die kleinste ausführbare Einheit, ein Deployment hält lang laufende Anwendungsreplikate verfügbar, ein Job führt eine Aufgabe bis zum Abschluss aus und ein CronJob speichert eine Vorlage für zeitgesteuerte Jobs.

In diesem Lab wirst du diese Ressourcen anhand ihres beobachtbaren Verhaltens vergleichen, anstatt Definitionen auswendig zu lernen. Du wirst sehen, dass ein eigenständiger Pod nach dem Löschen nicht wiederkehrt, ein Deployment seinen Pod neu erstellt, ein Job nach Abschluss seinen Erfolg protokolliert und ein CronJob Zeitplaninformationen für wiederkehrende Aufgaben speichert.

Einen Namespace für den Workload-Vergleich vorbereiten

In diesem Schritt bereitest du einen sauberen Namespace vor, um die Workload-Ressourcen zu vergleichen.

Beginne im Verzeichnis /home/labex/project. Du wirst in diesem Verzeichnis kleine Manifeste erstellen, während du das Verhalten der Workloads vergleichst.

mkdir -p /home/labex/project
cd /home/labex/project

Überprüfe, ob der Kubernetes API-Server erreichbar ist. Falls die VM gerade erst gestartet wurde und der Node noch nicht bereit ist, warte einige Sekunden und führe den Befehl erneut aus.

kubectl get nodes --request-timeout=5s

Die erwartete Ausgabe sieht in etwa so aus:

NAME         STATUS   ROLES           AGE   VERSION
labex-v135   Ready    control-plane   ...   v1.35...

Workloads erstellen Pods, warte also, bis der Cluster-Networking-Pod den Status "Ready" hat.

kubectl wait --namespace kube-system --for=condition=Ready pod -l k8s-app=calico-node --timeout=120s

Erwartete Ausgabe:

pod/calico-node-... condition met

Erstelle einen Namespace namens ckad-prep-workloads:

kubectl create namespace ckad-prep-workloads

Setze diesen Namespace als aktuellen Kontext-Namespace:

kubectl config set-context --current --namespace=ckad-prep-workloads

Bestätige den aktuellen Namespace:

kubectl config view --minify --output 'jsonpath={..namespace}'; echo

Erwartete Ausgabe:

ckad-prep-workloads

Einen Pod mit einem Deployment vergleichen

In diesem Schritt vergleichst du einen eigenständigen Pod mit einem Deployment, indem du beide Pods löschst und beobachtest, wie Kubernetes darauf reagiert.

Ein eigenständiger Pod ist nützlich, wenn du eine direkt verwaltete Laufzeiteinheit für eine sehr kleine Aufgabe oder eine Überprüfung benötigst. Ein Deployment eignet sich besser für eine lang laufende Anwendung, da ein Deployment ein ReplicaSet besitzt und dieses ReplicaSet sicherstellt, dass die angeforderte Anzahl an Pods ausgeführt wird.

Erstelle ein Manifest für einen eigenständigen Pod. Der Container befindet sich im Schlafmodus, damit der Pod lange genug läuft, um ihn zu beobachten. Das Feld terminationGracePeriodSeconds: 0 sorgt dafür, dass das Lab schnell bleibt, wenn du den Pod später löschst.

cat > standalone-pod.yaml <<'EOF'
apiVersion: v1
kind: Pod
metadata:
  name: standalone-task
  labels:
    app: standalone-task
    workload.labex.io/intent: direct-pod
spec:
  terminationGracePeriodSeconds: 0
  containers:
  - name: sleeper
    image: busybox:1.36
    command: ["/bin/sh", "-c", "sleep 3600"]
EOF

Erstelle ein Deployment-Manifest. Dieses Deployment weist Kubernetes an, einen managed-worker Pod am Laufen zu halten, und seine Pod-Vorlage verwendet dieselbe Einstellung für eine schnelle Beendigung.

cat > managed-deployment.yaml <<'EOF'
apiVersion: apps/v1
kind: Deployment
metadata:
  name: managed-worker
  labels:
    workload.labex.io/intent: long-running
spec:
  replicas: 1
  selector:
    matchLabels:
      app: managed-worker
  template:
    metadata:
      labels:
        app: managed-worker
    spec:
      terminationGracePeriodSeconds: 0
      containers:
      - name: sleeper
        image: busybox:1.36
        command: ["/bin/sh", "-c", "sleep 3600"]
EOF

Wende beide Manifeste an:

kubectl apply -f standalone-pod.yaml
kubectl apply -f managed-deployment.yaml

Erwartete Ausgabe:

pod/standalone-task created
deployment.apps/managed-worker created

Warte, bis beide Workloads bereit sind:

kubectl wait --for=condition=Ready pod/standalone-task --timeout=120s
kubectl wait --for=condition=Available deployment/managed-worker --timeout=120s

Erwartete Ausgabe:

pod/standalone-task condition met
deployment.apps/managed-worker condition met

Speichere den Namen des aktuellen Deployment-Pods und lösche dann den eigenständigen Pod sowie den vom Deployment verwalteten Pod:

managed_pod="$(kubectl get pods -l app=managed-worker -o 'jsonpath={.items[0].metadata.name}')"
kubectl delete pod standalone-task "$managed_pod"

Die erwartete Ausgabe enthält:

pod "standalone-task" deleted
pod "managed-worker-..." deleted

Warte darauf, dass das Deployment wieder verfügbar ist:

kubectl wait --for=condition=Available deployment/managed-worker --timeout=120s

Erwartete Ausgabe:

deployment.apps/managed-worker condition met

Liste die Pods auf. Der eigenständige Pod sollte verschwunden sein, während ein neuer managed-worker Pod existieren sollte.

kubectl get pods

Die erwartete Ausgabe enthält einen managed-worker Pod, aber nicht standalone-task:

NAME                              READY   STATUS    RESTARTS   AGE
managed-worker-...                1/1     Running   0          ...

Einen Job für den Abschluss wählen

In diesem Schritt wählst du einen Job für Aufgaben aus, die erfolgreich abgeschlossen werden sollen, anstatt ewig zu laufen.

Ein Deployment ist gut geeignet, wenn der gewünschte Zustand lautet: "Diese Anwendung am Laufen halten". Ein Job ist besser geeignet, wenn der gewünschte Zustand lautet: "Diese Aufgabe ausführen, bis sie abgeschlossen ist". Deshalb werden Migrationen, Batch-Verarbeitungen und einmalige Wartungsbefehle normalerweise als Jobs abgebildet.

Erstelle einen Job namens schema-migration:

kubectl create job schema-migration --image=busybox:1.36 -- /bin/sh -c 'echo migration-start; echo migration-complete'

Erwartete Ausgabe:

job.batch/schema-migration created

Warte, bis der Job den Status Complete erreicht:

kubectl wait --for=condition=Complete job/schema-migration --timeout=120s

Erwartete Ausgabe:

job.batch/schema-migration condition met

Überprüfe die Zusammenfassung des Jobs. COMPLETIONS sollte 1/1 anzeigen, was bedeutet, dass die Aufgabe einmal erfolgreich ausgeführt wurde.

kubectl get job schema-migration

Die erwartete Ausgabe enthält:

NAME               STATUS     COMPLETIONS   DURATION   AGE
schema-migration   Complete   1/1           ...        ...

Lies die Logs des Jobs:

kubectl logs job/schema-migration

Erwartete Ausgabe:

migration-start
migration-complete

Einen CronJob für wiederkehrende Aufgaben wählen

In diesem Schritt wählst du einen CronJob für Aufgaben aus, die nach einem Zeitplan ausgeführt werden sollen.

Ein CronJob ist eine Vorlage für zeitgesteuerte Jobs. Er ist die richtige Wahl, wenn die Aufgabe später wiederholt werden soll und nicht nur einmalig abgeschlossen werden muss. Um dieses geführte Lab deterministisch zu halten, erstellst du den CronJob im ausgesetzten (suspended) Zustand. So kannst du den Zeitplan und die Vorlage überprüfen, ohne auf eine Zeitgrenze warten zu müssen.

Erstelle cleanup-cronjob.yaml:

cat > cleanup-cronjob.yaml <<'EOF'
apiVersion: batch/v1
kind: CronJob
metadata:
  name: cleanup-schedule
  labels:
    workload.labex.io/intent: recurring-task
spec:
  schedule: "*/5 * * * *"
  suspend: true
  successfulJobsHistoryLimit: 1
  failedJobsHistoryLimit: 1
  jobTemplate:
    spec:
      template:
        spec:
          restartPolicy: OnFailure
          containers:
          - name: cleanup
            image: busybox:1.36
            command:
            - /bin/sh
            - -c
            - 'echo cleanup-ready'
EOF

Wende das Manifest an:

kubectl apply -f cleanup-cronjob.yaml

Erwartete Ausgabe:

cronjob.batch/cleanup-schedule created

Überprüfe die Zusammenfassung des CronJobs. SUSPEND ist True, da dieses Lab die CronJob-Definition verwendet, um die Ressourcenwahl zu erlernen, ohne auf geplante Jobs zu warten.

kubectl get cronjob cleanup-schedule

Die erwartete Ausgabe enthält:

NAME               SCHEDULE      TIMEZONE   SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cleanup-schedule   */5 * * * *   <none>     True      0        <none>          ...

Lies den Zeitplan und das Image der Vorlage direkt aus dem Objekt aus:

kubectl get cronjob cleanup-schedule -o 'jsonpath={.spec.schedule}{" "}{.spec.suspend}{" "}{.spec.jobTemplate.spec.template.spec.containers[0].image}{"\n"}'

Erwartete Ausgabe:

*/5 * * * * true busybox:1.36

Liste die Workload-Ressourcen auf, die du in diesem Lab erstellt hast. Diese Ansicht verknüpft den Ressourcentyp mit dem beabsichtigten Verhalten: ein Deployment für ein lang laufendes Replikat, ein Job für den Abschluss und ein CronJob für die Wiederholung.

kubectl get deployment,job,cronjob

Die erwartete Ausgabe enthält:

NAME                             READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/managed-worker   1/1     1            1           ...

NAME                         STATUS     COMPLETIONS   DURATION   AGE
job.batch/schema-migration   Complete   1/1           ...        ...

NAME                               SCHEDULE      TIMEZONE   SUSPEND   ACTIVE   LAST SCHEDULE   AGE
cronjob.batch/cleanup-schedule     */5 * * * *   <none>     True      0        <none>          ...

Zusammenfassung

Du hast Kubernetes-Workload-Ressourcen anhand ihres Verhaltens verglichen. Ein eigenständiger Pod kehrte nach dem Löschen nicht zurück, ein Deployment erstellte seinen Pod neu, um ein Replikat verfügbar zu halten, ein Job führte eine Aufgabe bis zum erfolgreichen Abschluss aus und ein CronJob speicherte eine Vorlage für wiederkehrende Jobs. Diese Beobachtungen helfen dir dabei, die richtige Ressource auszuwählen, bevor du ein Manifest im CKAD-Stil schreibst.