Veröffentlicht am

Docker und Kubernetes Grundlagen: Einstieg in Container

Teilen:
Authors

Docker und Kubernetes: Grundlagen, Zusammenspiel und Einstieg in die Container-Orchestrierung

TL;DR

  • Docker baut und verpackt Anwendungen in Container. Kubernetes verwaltet und orchestriert diese Container im Cluster.
  • Container sind keine leichtgewichtigen VMs -- sie teilen sich den Host-Kernel und isolieren nur den Userspace (Namespaces, cgroups).
  • Ein Kubernetes-Deployment beschreibt den Soll-Zustand deklarativ in YAML. Kubernetes sorgt dafuer, dass der Ist-Zustand dem entspricht.
  • Fuer den Einstieg reichen drei Konzepte: Pod, Deployment, Service. Alles andere kommt spaeter.
  • Managed Kubernetes (EKS, AKS, GKE) nimmt die Komplexitaet der Control Plane ab. Fuer lokale Tests eignet sich kind oder k3d.

Docker: Was Container wirklich sind

Ein Docker-Container ist kein Mini-Server und keine leichtgewichtige VM. Ein Container ist ein isolierter Prozess, der auf dem Host-Kernel laeuft. Die Isolation basiert auf zwei Linux-Kernel-Features:

  • Namespaces trennen die Sicht auf Prozesse, Netzwerk, Dateisystem und User-IDs
  • cgroups begrenzen CPU, RAM und I/O pro Container

Ein Docker-Image ist ein Schichtensystem (Layer). Jede Zeile im Dockerfile erzeugt einen neuen Layer. Gleiche Layer werden zwischen Images geteilt, was Speicher und Download-Zeiten spart.

Dockerfile-Beispiel: Multi-Stage Build

Multi-Stage Builds trennen die Build-Umgebung von der Runtime-Umgebung. Das Ergebnis ist ein deutlich kleineres Image.

# Build Stage
FROM golang:1.22 AS builder
WORKDIR /app
COPY go.mod go.sum ./
RUN go mod download
COPY . .
RUN CGO_ENABLED=0 GOOS=linux go build -o /app/server .

# Runtime Stage
FROM gcr.io/distroless/static-debian12:nonroot
COPY --from=builder /app/server /server
EXPOSE 8080
USER nonroot:nonroot
ENTRYPOINT ["/server"]

Wichtige Best Practices fuer Docker-Images:

PraxisWarum
Multi-Stage BuildsKleinere Images, keine Build-Tools in Produktion
Distroless oder Alpine als BasisWeniger Pakete = weniger Angriffsflaeche
USER nonrootContainer laeuft nicht als Root
.dockerignore pflegenVerhindert, dass Secrets oder Build-Artefakte ins Image gelangen
Pinned Versions (golang:1.22, nicht golang:latest)Reproduzierbare Builds

Kubernetes: Container im Cluster verwalten

Docker baut Container. Kubernetes verwaltet sie. Auf einem einzelnen Server reicht Docker. Sobald mehrere Server, Skalierung und Hochverfuegbarkeit gefragt sind, braucht man einen Orchestrierer.

Kubernetes loest konkret diese Probleme:

  • Scheduling: Auf welchem Node laeuft welcher Container?
  • Scaling: Automatisch mehr Container starten, wenn die Last steigt
  • Self-Healing: Abgestuerzte Container automatisch neu starten
  • Service Discovery: Container finden sich gegenseitig ueber DNS
  • Rolling Updates: Neue Versionen ohne Downtime deployen

Kubernetes-Architektur auf einen Blick

Ein Kubernetes-Cluster besteht aus der Control Plane und Worker Nodes.

Control Plane:

  • API Server: Einziger Einstiegspunkt fuer alle Operationen (kubectl, Controller, Scheduler)
  • etcd: Key-Value Store, haelt den gesamten Cluster-State
  • Scheduler: Entscheidet, auf welchem Node ein Pod laeuft
  • Controller Manager: Stellt sicher, dass Ist-Zustand = Soll-Zustand

Worker Nodes:

  • kubelet: Agent auf jedem Node, startet und ueberwacht Pods
  • Container Runtime: containerd oder CRI-O (Docker wird seit K8s 1.24 nicht mehr direkt unterstuetzt)
  • kube-proxy: Netzwerk-Routing fuer Services

Die drei wichtigsten Kubernetes-Objekte

Fuer den Einstieg reichen drei Konzepte:

Pod: Die kleinste Einheit in Kubernetes. Ein Pod enthaelt einen oder mehrere Container, die sich Netzwerk und Storage teilen. In der Praxis laeuft fast immer ein Container pro Pod.

Deployment: Beschreibt den gewuenschten Zustand: Welches Image, wie viele Replicas, welche Ressourcen. Der Deployment Controller sorgt dafuer, dass dieser Zustand eingehalten wird.

Service: Gibt einer Gruppe von Pods eine stabile Netzwerkadresse. Pods sind fluechtig -- ein Service bleibt bestehen und leitet Traffic an die aktuellen Pods weiter.

Praxisbeispiel: Anwendung auf Kubernetes deployen

1. Deployment-Manifest

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
  labels:
    app: web
spec:
  replicas: 3
  selector:
    matchLabels:
      app: web
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 1
      maxUnavailable: 0
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: registry.example.com/web-app:1.4.2
          ports:
            - containerPort: 8080
          resources:
            requests:
              cpu: "100m"
              memory: "128Mi"
            limits:
              cpu: "500m"
              memory: "512Mi"
          livenessProbe:
            httpGet:
              path: /healthz
              port: 8080
            initialDelaySeconds: 10
            periodSeconds: 15
          readinessProbe:
            httpGet:
              path: /ready
              port: 8080
            initialDelaySeconds: 5
            periodSeconds: 5

Einige Details, die in vielen Tutorials fehlen:

  • requests und limits muessen gesetzt sein. Ohne Requests kann der Scheduler schlecht planen. Ohne Limits kann ein einzelner Container den ganzen Node lahmlegen.
  • livenessProbe prueft, ob der Container noch lebt. Fehlschlag fuehrt zum Restart.
  • readinessProbe prueft, ob der Container Traffic annehmen kann. Fehlschlag entfernt den Pod aus dem Service.
  • maxUnavailable: 0 bei Rolling Updates stellt sicher, dass waehrend eines Deployments nie weniger als die gewuenschte Anzahl Pods laufen.

2. Service und Ingress

# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: web-app-svc
spec:
  selector:
    app: web
  ports:
    - port: 80
      targetPort: 8080
      protocol: TCP
  type: ClusterIP
---
# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: web-app-ingress
  annotations:
    cert-manager.io/cluster-issuer: "letsencrypt-prod"
spec:
  ingressClassName: nginx
  tls:
    - hosts:
        - app.example.com
      secretName: web-app-tls
  rules:
    - host: app.example.com
      http:
        paths:
          - path: /
            pathType: Prefix
            backend:
              service:
                name: web-app-svc
                port:
                  number: 80

3. Deployen und pruefen

# Manifeste anwenden
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml

# Rollout-Status pruefen
kubectl rollout status deployment/web-app

# Pods ansehen
kubectl get pods -l app=web

# Logs eines Pods lesen
kubectl logs -l app=web --tail=50

# In einen Pod eine Shell oeffnen (Debugging)
kubectl exec -it deployment/web-app -- /bin/sh

Docker Compose vs. Kubernetes: Wann brauche ich was?

KriteriumDocker ComposeKubernetes
EinsatzzweckLokale Entwicklung, kleine ProjekteProduktion, Multi-Node, Skalierung
Definitionsformatdocker-compose.ymlYAML-Manifeste (Deployment, Service, ...)
SkalierungManuell (docker compose up --scale)Automatisch (HPA, VPA)
Self-HealingRestart-Policy, kein echtes ReschedulingPod wird auf anderen Node verschoben
Service DiscoveryContainer-Name als DNSCoreDNS, Service-Objekte
KomplexitaetNiedrigHoch (aber Managed Services helfen)
Multi-NodeNein (nur Docker Swarm)Ja, Kern-Feature

Docker Compose ist kein Kubernetes-Ersatz und Kubernetes ist kein Docker-Compose-Ersatz. Compose ist perfekt fuer die lokale Entwicklung, Kubernetes fuer den produktiven Betrieb.

Einstieg: Lokaler Kubernetes-Cluster in 5 Minuten

Fuer Tests und Lernen braucht man keinen Cloud-Account. Mit kind (Kubernetes in Docker) laesst sich ein vollstaendiger Cluster lokal starten:

# kind installieren (macOS)
brew install kind

# Cluster erstellen
kind create cluster --name dev

# Cluster pruefen
kubectl cluster-info --context kind-dev
kubectl get nodes

# Einen nginx deployen
kubectl create deployment nginx --image=nginx:1.25
kubectl expose deployment nginx --port=80 --type=NodePort

# Aufraeumen
kind delete cluster --name dev

Alternativen zu kind:

ToolBeschreibungIdeal fuer
kindCluster in Docker-ContainernCI/CD, schnelle Tests
k3dk3s (leichtgewichtiges K8s) in DockerLokale Entwicklung
minikubeVM-basiert, viele AddonsEinsteiger, Addons testen
Docker DesktopEingebauter K8s-ClustermacOS/Windows-Entwickler

Typische Stolperfallen beim Einstieg

latest Tag verwenden. image: myapp:latest fuehrt zu unvorhersehbaren Deployments. Kubernetes kann nicht erkennen, ob sich das Image geaendert hat. Immer einen konkreten Tag oder SHA nutzen.

Keine Resource Requests und Limits setzen. Ohne Limits kann ein Container unbegrenzt Speicher verbrauchen und den gesamten Node zum OOM-Kill zwingen. Ohne Requests plant der Scheduler blind.

Liveness Probe zu aggressiv konfiguriert. Eine Liveness Probe mit initialDelaySeconds: 0 und periodSeconds: 1 restartet Container, die einfach nur langsam starten. Besonders bei Java-Anwendungen mit langer Startup-Zeit ein Problem.

Kein Namespace-Konzept. Alles im default Namespace zu deployen macht ab zehn Services die Uebersicht unmoeglich. Mindestens pro Team oder Umgebung (dev, staging, prod) eigene Namespaces verwenden.

Kubernetes-Manifeste nicht versionieren. YAML-Dateien gehoeren genauso ins Git wie Anwendungscode. Aenderungen am Cluster sollten immer ueber Git und CI/CD laufen, nie manuell mit kubectl edit.

Naechste Schritte nach dem Einstieg

Wer die Grundlagen verstanden hat, sollte sich diese Themen als naechstes ansehen:

  1. Helm -- Package Manager fuer Kubernetes, vereinfacht das Management komplexer Deployments
  2. Namespaces und RBAC -- Zugriffssteuerung und Mandantentrennung
  3. Persistent Volumes -- Daten, die Pod-Neustarts ueberleben
  4. Horizontal Pod Autoscaler -- Automatische Skalierung basierend auf CPU/Memory oder Custom Metrics
  5. Network Policies -- Netzwerk-Segmentierung zwischen Pods

Weiterfuehrende Artikel


Wenn Sie Unterstuetzung beim Einstieg in Kubernetes brauchen -- sei es ein Workshop fuer Ihr Team, eine Architektur-Review oder Hilfe bei der Migration bestehender Anwendungen -- melden Sie sich gerne unter /kontakt.

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