Veröffentlicht am

CKAD Übungsaufgaben: 20 Hands-on Aufgaben mit Lösungen

Teilen:
Authors

TL;DR

  • 20 realistische CKAD Uebungsaufgaben sortiert nach den fuenf Pruefungsdomains mit Loesungen
  • Jede Aufgabe simuliert den Schwierigkeitsgrad der echten CKAD-Pruefung
  • Zeitmanagement ist entscheidend: Uebe jede Aufgabe unter Zeitdruck (3-5 Minuten pro Aufgabe)
  • Nutze die Uebungen als Ergaenzung zu Killer.sh fuer eine optimale CKAD Vorbereitung
  • Richte dir kubectl-Aliase und Auto-Completion ein, bevor du loslegst

Setup und wichtige Shortcuts

Starte einen lokalen Cluster mit minikube start oder kind create cluster. Richte dir dann diese Aliase ein:

alias k=kubectl
export do="--dry-run=client -o yaml"
source <(kubectl completion bash)
complete -o default -F __start_kubectl k

Mit kubectl run nginx --image=nginx $do generierst du sofort YAML-Vorlagen. Mehr Shortcuts findest du im CKAD-Guide.


Domain 1: Application Design and Build (20%)

Aufgabe 1: Deployment erstellen und skalieren

Erstelle ein Deployment webapp im Namespace dev mit Image nginx:1.25, 3 Replicas, CPU-Request 100m, Memory-Request 128Mi.

kubectl create namespace dev
kubectl create deployment webapp --image=nginx:1.25 --replicas=3 -n dev $do > webapp.yaml
# Resource Requests in der YAML ergaenzen, dann:
kubectl apply -f webapp.yaml

Aufgabe 2: Rolling Update und Rollback

Aktualisiere webapp auf nginx:1.26, pruefe den Status, dann Rollback.

kubectl set image deployment/webapp nginx=nginx:1.26 -n dev
kubectl rollout status deployment/webapp -n dev
kubectl rollout undo deployment/webapp -n dev

Aufgabe 3: Multi-Container Pod mit Init Container

Erstelle Pod app-with-init: Init Container (busybox) laedt eine Datei nach /work-dir, Haupt-Container (nginx) mountet dasselbe emptyDir Volume.

apiVersion: v1
kind: Pod
metadata:
  name: app-with-init
spec:
  initContainers:
  - name: init-download
    image: busybox
    command: ['wget', '-O', '/work-dir/index.html', 'http://info.cern.ch']
    volumeMounts:
    - name: workdir
      mountPath: /work-dir
  containers:
  - name: nginx
    image: nginx:1.25
    volumeMounts:
    - name: workdir
      mountPath: /work-dir
  volumes:
  - name: workdir
    emptyDir: {}

Aufgabe 4: CronJob erstellen

Erstelle CronJob db-backup, jede Stunde, Image busybox, Befehl echo "Backup done". Setze successfulJobsHistoryLimit: 3.

kubectl create cronjob db-backup --image=busybox --schedule="0 * * * *" \
  --dry-run=client -o yaml > cj.yaml
# successfulJobsHistoryLimit und failedJobsHistoryLimit ergaenzen
kubectl apply -f cj.yaml

Domain 2: Application Deployment (20%)

Aufgabe 5: Rolling Update Strategie

Erstelle Deployment api-server (httpd:2.4, 5 Replicas) mit maxSurge: 2 und maxUnavailable: 1.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: api-server
spec:
  replicas: 5
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 2
      maxUnavailable: 1
  selector:
    matchLabels:
      app: api-server
  template:
    metadata:
      labels:
        app: api-server
    spec:
      containers:
      - name: httpd
        image: httpd:2.4

Aufgabe 6: Helm-Grundlagen

Fuege Bitnami Repo hinzu, installiere nginx als Release my-web im Namespace helm-test mit replicaCount=2.

helm repo add bitnami https://charts.bitnami.com/bitnami && helm repo update
kubectl create namespace helm-test
helm install my-web bitnami/nginx -n helm-test --set replicaCount=2

Aufgabe 7: Labels und Selektoren

Erstelle drei Pods (app-v1, app-v2: version=stable; app-v3: version=canary). Filtere nach version=stable.

kubectl run app-v1 --image=nginx:1.25 --labels="app=myapp,version=stable"
kubectl run app-v2 --image=nginx:1.25 --labels="app=myapp,version=stable"
kubectl run app-v3 --image=nginx:1.25 --labels="app=myapp,version=canary"
kubectl get pods -l version=stable

Aufgabe 8: Annotations aendern

Fuege Pod app-v3 die Annotation release-note="canary test" hinzu und aendere das Label auf version=stable.

kubectl annotate pod app-v3 release-note="canary test"
kubectl label pod app-v3 version=stable --overwrite

Domain 3: Application Observability and Maintenance (15%)

Aufgabe 9: Liveness Probe

Erstelle Pod health-check (nginx:1.25) mit HTTP Liveness Probe auf Port 80, Pfad /, initialDelaySeconds: 10, periodSeconds: 5.

apiVersion: v1
kind: Pod
metadata:
  name: health-check
spec:
  containers:
  - name: nginx
    image: nginx:1.25
    livenessProbe:
      httpGet:
        path: /
        port: 80
      initialDelaySeconds: 10
      periodSeconds: 5
      failureThreshold: 3

Aufgabe 10: Readiness Probe

Erstelle Pod ready-check (nginx:1.25) mit TCP Readiness Probe (Port 80) und HTTP Liveness Probe.

apiVersion: v1
kind: Pod
metadata:
  name: ready-check
spec:
  containers:
  - name: nginx
    image: nginx:1.25
    readinessProbe:
      tcpSocket:
        port: 80
      initialDelaySeconds: 5
      periodSeconds: 10
    livenessProbe:
      httpGet:
        path: /
        port: 80
      initialDelaySeconds: 15
      periodSeconds: 20

Aufgabe 11: Container Logs

Erstelle Pod log-generator (busybox), der jede Sekunde loggt. Zeige letzte 5 Zeilen und Logs der letzten 30s.

kubectl run log-generator --image=busybox \
  --command -- /bin/sh -c 'while true; do echo "$(date) - Log"; sleep 1; done'
kubectl logs log-generator --tail=5
kubectl logs log-generator --since=30s

Aufgabe 12: Resource Monitoring

Zeige CPU/Memory aller Pods in Namespace dev, sortiert nach CPU. Pruefe Events.

kubectl top pods -n dev --sort-by=cpu
kubectl get events -n dev --sort-by='.lastTimestamp'

Domain 4: Configuration and Security (25%)

Diese Domain hat das groesste Gewicht. Investiere hier besonders viel Uebungszeit. Fuer Security-Details siehe unseren CKS-Guide.

Aufgabe 13: ConfigMap als Umgebungsvariable

Erstelle ConfigMap app-config (DB_HOST=mysql.default.svc, DB_PORT=3306). Binde sie als envFrom in Pod config-pod ein.

kubectl create configmap app-config \
  --from-literal=DB_HOST=mysql.default.svc --from-literal=DB_PORT=3306
apiVersion: v1
kind: Pod
metadata:
  name: config-pod
spec:
  containers:
  - name: nginx
    image: nginx:1.25
    envFrom:
    - configMapRef:
        name: app-config
kubectl exec config-pod -- env | grep DB_

Aufgabe 14: Secret als Volume mounten

Erstelle Secret db-credentials (username=admin, password=S3cureP4ss). Mounte es unter /etc/credentials in Pod secret-pod.

kubectl create secret generic db-credentials \
  --from-literal=username=admin --from-literal=password='S3cureP4ss'
apiVersion: v1
kind: Pod
metadata:
  name: secret-pod
spec:
  containers:
  - name: nginx
    image: nginx:1.25
    volumeMounts:
    - name: cred-vol
      mountPath: /etc/credentials
      readOnly: true
  volumes:
  - name: cred-vol
    secret:
      secretName: db-credentials

Aufgabe 15: SecurityContext

Erstelle Pod secure-pod (nginx:1.25): runAsUser 1000, readOnlyRootFilesystem true, allowPrivilegeEscalation false. Mounte emptyDir nach /tmp und /var/cache/nginx.

apiVersion: v1
kind: Pod
metadata:
  name: secure-pod
spec:
  securityContext:
    runAsUser: 1000
  containers:
  - name: nginx
    image: nginx:1.25
    securityContext:
      readOnlyRootFilesystem: true
      allowPrivilegeEscalation: false
    volumeMounts:
    - name: tmp
      mountPath: /tmp
    - name: cache
      mountPath: /var/cache/nginx
  volumes:
  - name: tmp
    emptyDir: {}
  - name: cache
    emptyDir: {}

Aufgabe 16: ServiceAccount

Erstelle ServiceAccount app-sa in Namespace dev. Erstelle Pod sa-pod mit diesem SA, automountServiceAccountToken: false.

kubectl create serviceaccount app-sa -n dev
apiVersion: v1
kind: Pod
metadata:
  name: sa-pod
  namespace: dev
spec:
  serviceAccountName: app-sa
  automountServiceAccountToken: false
  containers:
  - name: nginx
    image: nginx:1.25

Domain 5: Services and Networking (20%)

Aufgabe 17: ClusterIP und NodePort

Erstelle Deployment web-app (nginx:1.25, 3 Replicas). Expose als ClusterIP web-svc und NodePort web-np.

kubectl create deployment web-app --image=nginx:1.25 --replicas=3
kubectl expose deployment web-app --name=web-svc --port=80
kubectl expose deployment web-app --name=web-np --port=80 --type=NodePort

Aufgabe 18: Ingress Ressource

Erstelle Ingress web-ingress: Host app.example.com, Pfad / auf web-svc:80, Pfad /api auf api-svc:8080.

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-ingress
spec:
  rules:
  - host: app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: web-svc
            port:
              number: 80
      - path: /api
        pathType: Prefix
        backend:
          service:
            name: api-svc
            port:
              number: 8080

Aufgabe 19: NetworkPolicy

Erstelle NetworkPolicy db-policy in dev: Erlaube nur Ingress auf Port 3306 von Pods mit app=webapp zu Pods mit app=mysql.

apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: db-policy
  namespace: dev
spec:
  podSelector:
    matchLabels:
      app: mysql
  policyTypes:
  - Ingress
  ingress:
  - from:
    - podSelector:
        matchLabels:
          app: webapp
    ports:
    - protocol: TCP
      port: 3306

Aufgabe 20: PersistentVolumeClaim

Erstelle PVC data-pvc (1Gi, ReadWriteOnce). Mounte ihn in Pod data-pod unter /data.

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: data-pod
spec:
  containers:
  - name: nginx
    image: nginx:1.25
    volumeMounts:
    - name: data
      mountPath: /data
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: data-pvc

Pruefungsstrategie und Killer.sh

In der Pruefung hast du 2 Stunden fuer ca. 15-20 Aufgaben. Trainiere deshalb jede dieser CKAD Uebungsaufgaben unter Zeitdruck.

Killer.sh optimal nutzen:

  • Session 1: 2 Wochen vor der Pruefung (Schwaechen identifizieren)
  • Session 2: 3-4 Tage vorher (Generalprobe)
  • Killer.sh ist schwieriger als die echte Pruefung. 60-70% dort bedeutet: du bist bereit.

Die wichtigsten Prinzipien:

  • Imperativ vor deklarativ: kubectl create ist schneller als YAML von Hand
  • --dry-run=client -o yaml fuer YAML-Grundgerueste nutzen
  • Schwere Aufgaben ueberspringen und spaeter zurueckkommen
  • Zwischen Namespaces wechseln: kubectl config set-context --current --namespace=dev

Fuer die vollstaendige CKAD-Vorbereitung mit Lernplan schau dir den CKAD-Zertifizierungs-Guide an. Wenn du die CKA anstrebst, hilft der CKA-Guide. Den kompletten Zertifizierungsweg beschreibt unser Vorbereitungs-Guide.


Verwandte Artikel


Du willst dich intensiv auf die CKAD-Pruefung vorbereiten und brauchst individuelles Coaching? Wir bieten praxisorientierte Trainings mit echten Kubernetes-Umgebungen an. Kontaktiere uns fuer ein unverbindliches Gespraech.

Kubernetes-Beratung gesucht?

Wir helfen deutschen Unternehmen bei der Kubernetes-Implementierung, Migration und Optimierung. DSGVO-konform und praxiserprobt.

📖 Verwandte Artikel

Weitere interessante Beiträge zu ähnlichen Themen