Kubernetes Lab

Praktische Übungen zu Kubernetes und Container-Orchestrierung

Kubernetes Lab

Praktische Übungen sind der beste Weg, Kubernetes und Container-Orchestrierung zu lernen. Diese Seite bietet eine Sammlung von Übungen – von einfachen Pods bis zu fortgeschrittenen Themen wie Ingress, Storage und Helm. Ideal für Einsteiger und angehende DevOps-Engineers, die praktische Erfahrung sammeln möchten.

Level 1: Grundlagen Level 2: Deployments & Services Level 3: Helm & Ingress

1. Kubernetes-Cluster einrichten

Bevor es losgeht, brauchen Sie einen Kubernetes-Cluster. Hier sind die Optionen für verschiedene Umgebungen:

Option A: Minikube (lokal)

Minikube ist die einfachste Möglichkeit, einen lokalen Cluster zu betreiben.

# Minikube installieren (Linux)
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

# Cluster starten
minikube start --driver=docker --cpus=2 --memory=4096

# Status prüfen
minikube status

Option B: Cloud (Managed Kubernetes)

Managed Kubernetes in der Cloud (kostenloses Kontingent nutzen):

  • Google Cloud (GKE): 300$ Free Trial
  • AWS (EKS): 12 Monate Free Tier
  • Azure (AKS): 200$ Free Trial
# Beispiel: GKE-Cluster erstellen
gcloud container clusters create mein-cluster --num-nodes=3 --zone=europe-west3-a

Option C: Kind (Docker in Docker)

Kind (Kubernetes in Docker) ist ideal für CI/CD und Tests.

# Kind installieren
curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.20.0/kind-linux-amd64
chmod +x ./kind
sudo mv ./kind /usr/local/bin/kind

# Cluster erstellen
kind create cluster --name lab-cluster

2. Grundlagen (Level 1) – Erste Schritte mit kubectl

Diese Übungen helfen Ihnen, die grundlegenden kubectl-Befehle kennenzulernen.

Übung 1.1: kubectl einrichten und testen
  1. Installieren Sie kubectl (falls nicht vorhanden).
  2. Prüfen Sie die kubectl-Version: kubectl version --client.
  3. Zeigen Sie die Cluster-Informationen an: kubectl cluster-info.
  4. Zeigen Sie alle verfügbaren Nodes an: kubectl get nodes.
Lösungen:
# 1. kubectl installieren (Linux)
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/

# 2. Version prüfen
kubectl version --client

# 3. Cluster-Info anzeigen
kubectl cluster-info

# 4. Nodes anzeigen
kubectl get nodes
Übung 1.2: Erste Pods erstellen
  1. Starten Sie einen einfachen Nginx-Pod: kubectl run nginx --image=nginx.
  2. Zeigen Sie alle Pods an: kubectl get pods.
  3. Zeigen Sie detaillierte Informationen zum Pod an: kubectl describe pod nginx.
  4. Löschen Sie den Pod: kubectl delete pod nginx.
Lösungen:
# 1. Pod erstellen
kubectl run nginx --image=nginx

# 2. Pods anzeigen
kubectl get pods
kubectl get pods -o wide # Mit mehr Details

# 3. Pod beschreiben
kubectl describe pod nginx

# 4. Pod löschen
kubectl delete pod nginx
Übung 1.3: Pods mit YAML definieren
  1. Erstellen Sie eine Datei pod.yaml mit folgendem Inhalt:
apiVersion: v1
kind: Pod
metadata:
  name: mein-pod
  labels:
    app: web
spec:
  containers:
  - name: nginx
    image: nginx:alpine
    ports:
    - containerPort: 80
  1. Erstellen Sie den Pod mit: kubectl apply -f pod.yaml.
  2. Zeigen Sie den Pod an: kubectl get pods -l app=web.
  3. Löschen Sie den Pod mit: kubectl delete -f pod.yaml.
Lösungen:
# 1. YAML-Datei erstellen
nano pod.yaml
# (Inhalt einfügen)

# 2. Pod erstellen
kubectl apply -f pod.yaml

# 3. Pod mit Label anzeigen
kubectl get pods -l app=web

# 4. Pod löschen
kubectl delete -f pod.yaml

3. Deployments (Level 2)

Deployments verwalten ReplicaSets und ermöglichen Rolling Updates.

Übung 2.1: Erstes Deployment erstellen
  1. Erstellen Sie ein Deployment mit 3 Replicas:
apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:alpine
        ports:
        - containerPort: 80
  1. Wenden Sie das Deployment an: kubectl apply -f deployment.yaml.
  2. Zeigen Sie das Deployment an: kubectl get deployments.
  3. Zeigen Sie die Pods an: kubectl get pods.
  4. Skalieren Sie das Deployment auf 5 Replicas: kubectl scale deployment nginx-deployment --replicas=5.
Lösungen:
# 1. YAML-Datei erstellen
nano deployment.yaml
# (Inhalt einfügen)

# 2. Deployment anwenden
kubectl apply -f deployment.yaml

# 3. Deployments anzeigen
kubectl get deployments

# 4. Pods anzeigen
kubectl get pods -l app=nginx

# 5. Skalieren
kubectl scale deployment nginx-deployment --replicas=5

# 6. Rolling Update durchführen
kubectl set image deployment/nginx-deployment nginx=nginx:latest
Übung 2.2: Rolling Update und Rollback
  1. Aktualisieren Sie das Image auf eine neue Version: kubectl set image deployment/nginx-deployment nginx=nginx:1.25.
  2. Überwachen Sie den Update-Status: kubectl rollout status deployment/nginx-deployment.
  3. Zeigen Sie die Rollout-Historie an: kubectl rollout history deployment/nginx-deployment.
  4. Führen Sie ein Rollback durch: kubectl rollout undo deployment/nginx-deployment.
Lösungen:
# 1. Image aktualisieren
kubectl set image deployment/nginx-deployment nginx=nginx:1.25

# 2. Rollout-Status prüfen
kubectl rollout status deployment/nginx-deployment

# 3. Rollout-Historie
kubectl rollout history deployment/nginx-deployment

# 4. Rollback durchführen
kubectl rollout undo deployment/nginx-deployment

4. Services (Level 2)

Services ermöglichen den Netzwerkzugriff auf Pods.

Übung 3.1: ClusterIP Service
  1. Erstellen Sie einen Service für das nginx-Deployment:
apiVersion: v1
kind: Service
metadata:
  name: nginx-service
spec:
  selector:
    app: nginx
  ports:
  - protocol: TCP
    port: 80
    targetPort: 80
  1. Wenden Sie den Service an: kubectl apply -f service.yaml.
  2. Zeigen Sie alle Services an: kubectl get services.
  3. Testen Sie den Service mit einem temporären Pod: kubectl run test --rm -it --image=alpine -- wget -O- nginx-service.
Lösungen:
# 1. Service-YAML erstellen
nano service.yaml
# (Inhalt einfügen)

# 2. Service anwenden
kubectl apply -f service.yaml

# 3. Services anzeigen
kubectl get svc

# 4. Service testen
kubectl run test --rm -it --image=alpine -- wget -O- http://nginx-service
Übung 3.2: NodePort Service
  1. Erstellen Sie einen NodePort-Service, der von außen erreichbar ist:
apiVersion: v1
kind: Service
metadata:
  name: nginx-nodeport
spec:
  type: NodePort
  selector:
    app: nginx
  ports:
  - port: 80
    targetPort: 80
    nodePort: 30080
  1. Wenden Sie den Service an.
  2. Finden Sie die Node-IP heraus: kubectl get nodes -o wide (bei Minikube: minikube ip).
  3. Testen Sie den Service im Browser: http://node-ip:30080.
Lösungen:
# 1. NodePort-Service erstellen
nano nodeport.yaml
# (Inhalt einfügen)

# 2. Anwenden
kubectl apply -f nodeport.yaml

# 3. Node-IP finden (Minikube)
minikube ip

# 4. Service testen
curl http://$(minikube ip):30080

5. ConfigMaps & Secrets (Level 2)

Konfigurationen und sensible Daten von Containern trennen.

Übung 4.1: ConfigMap erstellen und verwenden
  1. Erstellen Sie eine ConfigMap mit Umgebungsvariablen:
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  database_url: postgres://db:5432/app
  log_level: debug
  1. Erstellen Sie einen Pod, der die ConfigMap nutzt:
apiVersion: v1
kind: Pod
metadata:
  name: config-test
spec:
  containers:
  - name: alpine
    image: alpine
    command: ["sleep", "3600"]
    envFrom:
    - configMapRef:
      name: app-config
  1. Prüfen Sie, ob die Umgebungsvariablen gesetzt sind: kubectl exec config-test -- env | grep database.
Lösungen:
# 1. ConfigMap erstellen
kubectl apply -f configmap.yaml

# 2. Pod mit ConfigMap starten
kubectl apply -f pod-config.yaml

# 3. Umgebungsvariablen prüfen
kubectl exec config-test -- env | grep database_url
Übung 4.2: Secrets erstellen
  1. Erstellen Sie ein Secret für Datenbank-Zugangsdaten:
# Secret mit kubectl erstellen (empfohlen)
kubectl create secret generic db-secret \
  --from-literal=username=admin \
  --from-literal=password=geheim123
  1. Zeigen Sie das Secret an: kubectl get secrets.
  2. Zeigen Sie die Details an (verschlüsselt): kubectl describe secret db-secret.
  3. Löschen Sie das Secret: kubectl delete secret db-secret.
Lösungen:
# 1. Secret erstellen
kubectl create secret generic db-secret --from-literal=username=admin --from-literal=password=geheim123

# 2. Secrets anzeigen
kubectl get secrets

# 3. Secret beschreiben (Werte nicht sichtbar)
kubectl describe secret db-secret

# 4. Secret löschen
kubectl delete secret db-secret

6. Persistente Volumes (Level 3)

Persistente Daten in Kubernetes mit PersistentVolumes und PersistentVolumeClaims.

Übung 5.1: PersistentVolumeClaim erstellen
  1. Erstellen Sie einen PersistentVolumeClaim (PVC):
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: mein-pvc
spec:
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi
  1. Erstellen Sie einen Pod, der den PVC nutzt:
apiVersion: v1
kind: Pod
metadata:
  name: pvc-test
spec:
  volumes:
  - name: data
    persistentVolumeClaim:
      claimName: mein-pvc
  containers:
  - name: alpine
    image: alpine
    command: ["sleep", "3600"]
    volumeMounts:
    - name: data
      mountPath: /data
  1. Schreiben Sie eine Datei in das Volume und löschen Sie den Pod.
  2. Erstellen Sie einen neuen Pod mit dem gleichen PVC – die Datei sollte noch vorhanden sein.
Lösungen:
# 1. PVC erstellen
kubectl apply -f pvc.yaml

# 2. Pod mit PVC starten
kubectl apply -f pod-pvc.yaml

# 3. Datei schreiben
kubectl exec pvc-test -- sh -c "echo 'Test' > /data/test.txt"

# 4. Pod löschen
kubectl delete pod pvc-test

# 5. Neuen Pod mit gleichem PVC starten
kubectl apply -f pod-pvc.yaml

# 6. Datei prüfen
kubectl exec pvc-test -- cat /data/test.txt

7. Ingress (Level 3)

Ingress ermöglicht den externen Zugriff auf Services mit Host-basiertem Routing.

Übung 6.1: Ingress Controller aktivieren und Ingress erstellen
  1. Aktivieren Sie den Ingress Controller (bei Minikube): minikube addons enable ingress.
  2. Erstellen Sie zwei Deployments und Services (z.B. app1 und app2).
  3. Erstellen Sie einen Ingress, der den Traffic routet:
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: mein-ingress
spec:
  rules:
  - host: app1.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app1-service
            port:
              number: 80
  - host: app2.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: app2-service
            port:
              number: 80
  1. Testen Sie den Ingress (mit /etc/hosts-Eintrag oder Minikube-IP).
Lösungen:
# 1. Ingress Controller aktivieren (Minikube)
minikube addons enable ingress

# 2. Ingress erstellen
kubectl apply -f ingress.yaml

# 3. Ingress anzeigen
kubectl get ingress

# 4. Ingress testen (Minikube)
echo "$(minikube ip) app1.example.com app2.example.com" | sudo tee -a /etc/hosts
curl http://app1.example.com

8. Helm – Package Manager für Kubernetes (Level 3)

Helm vereinfacht die Installation und Verwaltung von Kubernetes-Anwendungen.

Übung 7.1: Helm installieren und erste Charts
  1. Installieren Sie Helm (Linux/macOS): curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash.
  2. Fügen Sie ein Helm-Repository hinzu: helm repo add bitnami https://charts.bitnami.com/bitnami.
  3. Suchen Sie nach verfügbaren Charts: helm search repo nginx.
  4. Installieren Sie ein Chart: helm install mein-nginx bitnami/nginx.
  5. Zeigen Sie installierte Releases an: helm list.
Lösungen:
# 1. Helm installieren
curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
chmod 700 get_helm.sh
./get_helm.sh

# 2. Repository hinzufügen
helm repo add bitnami https://charts.bitnami.com/bitnami
helm repo update

# 3. Nach Charts suchen
helm search repo nginx

# 4. Chart installieren
helm install mein-nginx bitnami/nginx

# 5. Releases anzeigen
helm list

9. Troubleshooting – Fehlersuche

Typische Kubernetes-Probleme erkennen und lösen.

Problem: Pod startet nicht (ImagePullBackOff)

Szenario: Pod bleibt im Status "ImagePullBackOff".

Lösungsansätze:

  • Pod beschreiben: kubectl describe pod <pod-name>
  • Image-Name prüfen (Rechtschreibung, Tag)
  • Internetverbindung des Clusters prüfen
  • Bei privaten Images: ImagePullSecret konfigurieren

Problem: Pod bleibt in "Pending"

Szenario: Pod wird nicht gestartet, bleibt "Pending".

Lösungsansätze:

  • Knoten-Ressourcen prüfen: kubectl describe nodes
  • PVC-Status prüfen (falls verwendet): kubectl get pvc
  • Node-Selektor/Tolerations prüfen

Problem: Service nicht erreichbar

Szenario: Service antwortet nicht.

Lösungsansätze:

  • Pods hinter dem Service prüfen: kubectl get pods -l app=meine-app
  • Endpoints prüfen: kubectl get endpoints <service-name>
  • Service-Typ prüfen (ClusterIP vs. NodePort)

10. Kubernetes Best Practices

Eine Checkliste für saubere und effiziente Kubernetes-Deployments.

  • Ressourcenlimits für Container definieren (CPU, Memory)
  • Healthchecks (Liveness, Readiness, Startup Probes) konfigurieren
  • Labels für alle Ressourcen verwenden (konsistentes Schema)
  • Namespace für verschiedene Umgebungen (dev, staging, prod) nutzen
  • Pod Security Standards oder Pod Security Admission verwenden
  • Images nicht mit "latest"-Tag verwenden (sondern Versionen)
  • ConfigMaps und Secrets für Konfigurationen nutzen
  • RBAC für Zugriffskontrolle konfigurieren
  • Network Policies für Netzwerk-Isolation nutzen
  • Regelmäßige Updates von Kubernetes-Versionen
  • Backup von etcd (bei selbstverwalteten Clustern)
  • Monitoring mit Prometheus/Grafana einrichten
  • Resource Quotas und LimitRanges für Namespaces definieren

Weiterführende Themen

Docker Lab

Grundlagen zu Containern – Voraussetzung für Kubernetes.

Zu Docker
Container & Orchestrierung

Theoretische Grundlagen zu Containern und Orchestrierung.

Zu Containern
Networking Lab

Netzwerk-Grundlagen für Kubernetes.

Zu Networking
Cloud-Computing

Managed Kubernetes in der Cloud (EKS, AKS, GKE).

Zur Cloud