Containerisierung mit Docker und Kubernetes

Die Containerisierung hat die Art und Weise revolutioniert, wie wir Software erstellen, versenden und ausführen. Durch das Packen von Anwendungen mit ihren Abhängigkeiten in leichte, tragbare Einheiten lösen Container das Problem „Es funktioniert auf meinem Computer“ und ermöglichen eine konsistente Bereitstellung in Entwicklungs-, Test- und Produktionsumgebungen.
Einführung
Die Containerisierung hat die Art und Weise revolutioniert, wie wir Software erstellen, versenden und ausführen. Durch das Packen von Anwendungen mit ihren Abhängigkeiten in leichte, tragbare Einheiten lösen Container das Problem „Es funktioniert auf meinem Computer“ und ermöglichen eine konsistente Bereitstellung in Entwicklungs-, Test- und Produktionsumgebungen.
Docker hat Container zugänglich gemacht. Kubernetes machte sie im großen Maßstab beherrschbar. Zusammen bilden sie das Rückgrat der modernen Cloud-nativen Anwendungsbereitstellung.
Was sind Container?
Container vs. virtuelle Maschinen
┌───────────────────────┐ ┌───────────────────────┐
│ Virtual Machine │ │ Container │
├───────────────────────┤ ├───────────────────────┤
│ ┌─────────────────┐ │ │ ┌─────────────────┐ │
│ │ Application │ │ │ │ Application │ │
│ ├─────────────────┤ │ │ ├─────────────────┤ │
│ │ Guest OS │ │ │ │ Dependencies │ │
│ │ (full kernel) │ │ │ ├─────────────────┤ │
│ ├─────────────────┤ │ │ │ Container │ │
│ │ Hypervisor │ │ │ │ Runtime │ │
│ ├─────────────────┤ │ │ ├─────────────────┤ │
│ │ Host OS │ │ │ │ Host OS │ │
│ └─────────────────┘ │ │ │ Kernel (shared)│ │
└───────────────────────┘ │ └─────────────────┘ │
└───────────────────────┘
| Besonderheit | VM | Container |
|---|---|---|
| Bootzeit | Minuten | Millisekunden |
| Größe | GB | MB |
| OS-Overhead | Vollständiges Betriebssystem pro VM | Gemeinsamer Kernel |
| Isolierung | Stark (Hardware-Ebene) | Prozessebene |
| Leistung | Fast einheimisch | Fast einheimisch |
| Portabilität | Gut | Exzellent |
| Dichte | Niedrig (10–100 pro Host) | Hoch (100–1000 pro Host) |
Docker: Die Containerplattform
Schlüsselkonzepte
| Konzept | Beschreibung |
|---|---|
| Bild | Eine schreibgeschützte Vorlage mit Anweisungen zum Erstellen eines Containers |
| Container | Eine ausführbare Instanz eines Bildes |
| Docker-Datei | Eine Textdatei mit Anweisungen zum Erstellen eines Bildes |
| Registrierung | Speicherung und Verteilung für Bilder (Docker Hub, ECR, GCR) |
| Volumen | Permanente Datenspeicherung außerhalb des Container-Dateisystems |
| Netzwerk | Kommunikation zwischen Containern und der Außenwelt |
| Komponieren | Definieren Sie Multi-Container-Anwendungen und führen Sie sie aus |
Best Practices für Dockerfile
# 1. Use specific base images (not 'latest')
FROM node:20-alpine AS builder
# 2. Set working directory
WORKDIR /app
# 3. Copy dependency files first (leverage layer caching)
COPY package*.json ./
RUN npm ci --production
# 4. Copy application code last
COPY . .
# 5. Use multi-stage builds
FROM node:20-alpine AS production
COPY --from=builder /app/node_modules ./node_modules
COPY --from=builder /app/dist ./dist
# 6. Run as non-root user
RUN addgroup -S appgroup && adduser -S appuser -G appgroup
USER appuser
# 7. Expose only necessary ports
EXPOSE 3000
# 8. Use exec form of CMD
CMD ["node", "dist/server.js"]
Spickzettel für Docker-Befehle
# Build image
docker build -t myapp:1.0 .
# Run container
docker run -d --name myapp -p 3000:3000 myapp:1.0
# Execute command in running container
docker exec -it myapp bash
# View logs
docker logs -f myapp
# List containers
docker ps -a
# Stop and remove
docker stop myapp && docker rm myapp
# Volumes (persistent data)
docker volume create data-volume
docker run -v data-volume:/app/data myapp:1.0
# Compose (multi-service)
docker compose up -d
docker compose logs -f
docker compose down
Docker-Netzwerk
# docker-compose.yml
version: '3.8'
services:
web:
image: myapp:latest
ports:
- "3000:3000"
networks:
- frontend
- backend
depends_on:
- api
- db
api:
image: api:latest
networks:
- backend
environment:
- DB_HOST=db
db:
image: postgres:16-alpine
volumes:
- postgres_data:/var/lib/postgresql/data
networks:
- backend
environment:
POSTGRES_PASSWORD_FILE: /run/secrets/db_password
secrets:
- db_password
networks:
frontend:
backend:
volumes:
postgres_data:
secrets:
db_password:
file: ./secrets/db_password.txt
Kubernetes: Container-Orchestrierung
Kubernetes (K8s) automatisiert die Bereitstellung, Skalierung und Verwaltung von Containeranwendungen in einem Cluster.
Architektur
┌──────────────────────────────────────────────┐
│ Kubernetes Control Plane │
│ ┌──────────┐ ┌──────────┐ ┌──────────────┐ │
│ │ API │ │ Scheduler│ │ Controller │ │
│ │ Server │ │ │ │ Manager │ │
│ └──────────┘ └──────────┘ └──────────────┘ │
│ ┌─────────────────────────────────────────┐│
│ │ etcd (distributed key-value store) ││
│ └─────────────────────────────────────────┘│
└─────────────────┬────────────────────────────┘
│
┌─────────────────▼────────────────────────────┐
│ Worker Nodes │
│ ┌──────────────────────────────────────────┐│
│ │ Node 1 ││
│ │ ┌──────┐ ┌──────┐ ┌──────┐ ││
│ │ │ Pod │ │ Pod │ │ Pod │ ││
│ │ └──────┘ └──────┘ └──────┘ ││
│ │ ┌────────────────────────────────────┐ ││
│ │ │ kubelet ││ kube-proxy ││ container │ ││
│ │ │ ││ ││ runtime │ ││
│ │ └────────────────────────────────────┘ ││
│ └──────────────────────────────────────────┘│
│ ┌──────────────────────────────────────────┐│
│ │ Node 2 (same structure) ││
│ └──────────────────────────────────────────┘│
└──────────────────────────────────────────────┘
Kernobjekte von Kubernetes
Pod – Kleinste einsetzbare Einheit
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
tier: frontend
spec:
containers:
- name: myapp-container
image: nginx:1.25
ports:
- containerPort: 80
resources:
requests:
memory: "128Mi"
cpu: "250m"
limits:
memory: "256Mi"
cpu: "500m"
Bereitstellung – Deklarative Pod-Verwaltung
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp-deployment
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: myapp:1.0
ports:
- containerPort: 3000
livenessProbe:
httpGet:
path: /health
port: 3000
initialDelaySeconds: 5
periodSeconds: 10
readinessProbe:
httpGet:
path: /ready
port: 3000
initialDelaySeconds: 3
periodSeconds: 5
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 1
maxSurge: 1
Dienst – Stabiler Netzwerkzugriff
apiVersion: v1
kind: Service
metadata:
name: myapp-service
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 3000
protocol: TCP
type: ClusterIP # Internal access only
---
# For external access:
apiVersion: v1
kind: Service
metadata:
name: myapp-loadbalancer
spec:
selector:
app: myapp
ports:
- port: 80
targetPort: 3000
type: LoadBalancer
Eingang – HTTP/HTTPS-Routing
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: myapp-ingress
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /
spec:
rules:
- host: myapp.example.com
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: web-service
port:
number: 80
ConfigMap und Secret – Konfiguration
apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
APP_ENV: production
DB_HOST: postgres-service
LOG_LEVEL: info
---
apiVersion: v1
kind: Secret
metadata:
name: app-secrets
type: Opaque
data:
DB_PASSWORD: c3VwZXJzZWNyZXQ= # base64 encoded
Bereitstellen einer Anwendung
# Apply configurations
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
kubectl apply -f ingress.yaml
# Check status
kubectl get pods
kubectl get deployments
kubectl get services
kubectl get ingress
# View logs
kubectl logs -f deployment/myapp-deployment
# Scale
kubectl scale deployment/myapp-deployment --replicas=5
# Rollout update
kubectl set image deployment/myapp-deployment myapp=myapp:2.0
kubectl rollout status deployment/myapp-deployment
# Rollback if needed
kubectl rollout undo deployment/myapp-deployment
Erweiterte Funktionen von Kubernetes
Horizontaler Pod-Autoscaler (HPA)
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: myapp-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: myapp-deployment
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
Persistente Volumes
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: data-claim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 10Gi
storageClassName: standard
---
apiVersion: v1
kind: Pod
metadata:
name: postgres
spec:
containers:
- name: postgres
image: postgres:16-alpine
volumeMounts:
- mountPath: /var/lib/postgresql/data
name: postgres-storage
volumes:
- name: postgres-storage
persistentVolumeClaim:
claimName: data-claim
Namensräume
# Create namespaces for environment isolation
kubectl create namespace dev
kubectl create namespace staging
kubectl create namespace production
# Deploy to specific namespace
kubectl apply -f deployment.yaml -n production
# Resource quotas per namespace
kubectl create quota prod-quota --hard=cpu=40,memory=80Gi,pods=50 -n production
Docker vs. Kubernetes – Wann was zu verwenden
| Szenario | Docker allein | Kubernetes hinzufügen |
|---|---|---|
| Lokale Entwicklung | ✅ Ja | ❌ Übertrieben |
| Bereitstellung auf einem einzelnen Server | ✅ Ja | ❌ Übertrieben |
| 2-3 Mikrodienste | ✅ Docker Compose | ❌ Normalerweise übertrieben |
| Hohe Verfügbarkeit erforderlich | ❌ Manuelles Failover | ✅ Automatische Heilung |
| Automatische Skalierung erforderlich | ❌ Handbuch | ✅ HPA |
| Cluster mit mehreren Knoten | ❌ Begrenzt | ✅ Eingebaut |
| Fortlaufende Updates | ❌ Handbuch | ✅ Eingebaut |
| Canary-Bereitstellungen | ❌ Komplex | ✅ Native Unterstützung |
| Multi-Cloud | ❌ Nicht tragbar | ✅ Tragbar |
Entscheidungsrahmen:
- Beginnen Sie mit Docker – Immer. Container sind das Fundament.
- Verwenden Sie Docker Compose – Für lokale Entwicklungs-, CI- und Einzelhostbereitstellungen.
- Nehmen Sie Kubernetes ein, wenn: Sie HA, Skalierung, mehrere Knoten oder komplexe Orchestrierung benötigen.
- Verwenden Sie verwaltetes Kubernetes (EKS, AKS, GKE) – Vermeiden Sie die Selbstverwaltung der Steuerungsebene.
Best Practices
Imagebildung
- Verwenden Sie spezifische Basis-Image-Tags („node:20-alpine“, nicht „node:latest“).
- Implementieren Sie mehrstufige Builds, um die Bildgröße zu minimieren.
- Bilder auf Schwachstellen scannen: „docker scan myapp:1.0“.
- Bilder signieren: „cosign sign --key cosign.key myapp:1.0“.
Sicherheit
- Führen Sie Container als Nicht-Root-Benutzer aus.
- Legen Sie schreibgeschütztes Root-Dateisystem fest: „readOnlyRootFilesystem: true“.
- Verwenden Sie Geheimnisse für vertrauliche Daten, nicht für Umgebungsvariablen.
- Implementieren Sie Netzwerkrichtlinien, um den Datenverkehr zwischen Pods einzuschränken.
- Aktivieren Sie RBAC für den Kubernetes-API-Zugriff.
Ressourcenmanagement
- Legen Sie immer Ressourcenanforderungen und -limits fest.
- Verwenden Sie Ressourcenkontingente pro Namespace.
- Implementieren Sie HPA für die automatische Skalierung.
- Verwenden Sie PodDisruptionBudget für die Verfügbarkeit während der Wartung.
Überwachung und Beobachtbarkeit
# Sidecar pattern for logging
spec:
containers:
- name: app
image: myapp:latest
- name: log-collector
image: fluentd:latest
volumeMounts:
- name: logs
mountPath: /var/log/app
CI/CD-Pipeline
# GitHub Actions — Build + Deploy to Kubernetes
name: CI/CD
on:
push:
branches: [main]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Build Docker image
run: docker build -t registry.example.com/myapp:${{ github.sha }} .
- name: Push to registry
run: docker push registry.example.com/myapp:${{ github.sha }}
- name: Deploy to Kubernetes
run: |
kubectl set image deployment/myapp-deployment \
myapp=registry.example.com/myapp:${{ github.sha }}
Das Ökosystem
| Kategorie | Werkzeuge |
|---|---|
| Containerlaufzeit | Docker, Containerd, CRI-O |
| Orchestrierung | Kubernetes, Nomad, Docker Swarm |
| Paketmanager | Helm, Kustomize |
| Service Mesh | Istio, Linkerd, Cilium |
| Überwachung | Prometheus + Grafana, Datadog |
| Protokollierung | ELK Stack, Grafana Loki, fließend |
| Sicherheit | Trivy, Falco, OPA/Gatekeeper, Kyverno |
| GitOps | ArgoCD, Flux |
| Entwicklertools | Skaffold, Tilt, DevSpace |
| Lagerung | Rook/Ceph, Longhorn, Portworx |
| Serverlos auf K8s | Knative, OpenFaaS, KEDA |
Abschluss
Docker und Kubernetes bieten zusammen eine leistungsstarke Plattform zum Erstellen, Bereitstellen und Skalieren moderner Anwendungen:
- Beginnen Sie mit Docker – Containerisieren Sie Anwendungen, Master-Docker-Dateien und Compose.
- Erlernen Sie die Grundlagen von Kubernetes – Pods, Bereitstellungen, Dienste, ConfigMaps.
- Verwenden Sie verwaltetes Kubernetes – Lassen Sie Cloud-Anbieter die Steuerungsebene übernehmen.
- GitOps übernehmen – ArgoCD oder Flux für deklarative, versionierte Bereitstellungen.
- In Beobachtbarkeit investieren – Überwachung, Protokollierung und Rückverfolgung sind im großen Maßstab unerlässlich.
Die Investition in das Erlernen der Containerisierung und Orchestrierung zahlt sich in der Bereitstellungszuverlässigkeit, der betrieblichen Effizienz und der Anwendungsportabilität über Umgebungen hinweg aus.
Empfohlene Artikel

6 Coding-Patterns, die ich von Senior Engineers gelernt habe

Einen privaten KI-Assistenten für Notizen bauen
Mache aus Markdown-Notizen einen durchsuchbaren Assistenten, ohne private Entwürfe offenzulegen.

Rechnungsdaten mit OCR automatisiert auslesen
Baue eine Pipeline, die Rechnungen liest, Felder extrahiert und unsichere Werte markiert.
Kommentare
0 KommentareNoch keine freigegebenen Kommentare sichtbar. Neue Antworten können moderiert werden.