- Authors

- Name
- Phillip Pham
- @ddppham
TL;DR
Legacy-Modernisierung folgt den 6 Rs: Rehost, Replatform, Refactor, Repurchase, Retire, Retain. Für die meisten VM-basierten Applikationen ist Replatform der pragmatische Weg — Containerisierung ohne vollständiges Rewrite. Starte mit dem Frontend, dann Backend, Datenbanken zuletzt. Nicht alles muss in Container.
Von VMs zu Kubernetes: Schritt für Schritt
Deine Java-App läuft seit 8 Jahren auf einer VM. Deployment bedeutet SSH, WAR-File kopieren, Tomcat neustarten. Monitoring ist tail -f catalina.out. Das funktioniert — bis es nicht mehr funktioniert.
Hier ist das Dockerfile für genau diese Art von Legacy-App:
# Dockerfile für Legacy-Java-Applikation (Spring Boot / Tomcat)
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
# Health-Check-Endpunkt
HEALTHCHECK \
CMD wget -qO- http://localhost:8080/actuator/health || exit 1
# Konfiguration externalisieren
ENV SPRING_PROFILES_ACTIVE=production
ENV JAVA_OPTS="-Xms256m -Xmx512m -XX:+UseG1GC"
COPY target/legacy-app.jar app.jar
EXPOSE 8080
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]
Die 6 Rs der Modernisierung
Nicht jede Applikation braucht denselben Ansatz. Die 6 Rs helfen bei der Entscheidung:
Rehost (Lift & Shift): Die VM wird 1:1 in einen Container gepackt. Schnell, aber wenig Kubernetes-Vorteile. Taugt als Zwischenschritt.
Replatform (Lift & Reshape): Die App wird containerisiert und leicht angepasst — Konfiguration über Environment-Variablen, Health-Checks eingebaut, Logs auf stdout. Der pragmatische Weg für die meisten Applikationen.
Refactor: Architektur-Umbau zu Microservices. Teuer, zeitaufwändig, aber maximaler Kubernetes-Nutzen. Nur für strategisch wichtige Applikationen.
Repurchase: Alte Software durch SaaS ersetzen. Dein selbstgebautes Ticketsystem? Vielleicht ist Jira doch günstiger.
Retire: Abschalten. 20% der Enterprise-Applikationen werden kaum genutzt. Frag die Nutzer — oft vermisst niemand die App.
Retain: Bewusst auf der VM lassen. Mainframe-Anbindungen oder Software mit Hardware-Dongles gehören nicht in Container.
Eine 3-Tier-App containerisieren
Typisches Setup: React-Frontend, Java-Backend, PostgreSQL-Datenbank. So bringst du das auf Kubernetes.
Backend-Deployment
# backend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: legacy-backend
namespace: production
spec:
replicas: 2
selector:
matchLabels:
app: legacy-backend
template:
metadata:
labels:
app: legacy-backend
spec:
containers:
- name: backend
image: registry.internal/legacy-app:v1.0.0
ports:
- containerPort: 8080
env:
- name: DB_HOST
value: "postgres-service.production.svc.cluster.local"
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
- name: SPRING_PROFILES_ACTIVE
value: "kubernetes"
resources:
requests:
cpu: 250m
memory: 512Mi
limits:
cpu: "1"
memory: 1Gi
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 20
periodSeconds: 10
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 45
periodSeconds: 15
---
apiVersion: v1
kind: Service
metadata:
name: legacy-backend-service
namespace: production
spec:
selector:
app: legacy-backend
ports:
- port: 80
targetPort: 8080
Frontend als separater Container
# frontend-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: legacy-frontend
namespace: production
spec:
replicas: 2
selector:
matchLabels:
app: legacy-frontend
template:
metadata:
labels:
app: legacy-frontend
spec:
containers:
- name: frontend
image: registry.internal/legacy-frontend:v1.0.0
ports:
- containerPort: 80
resources:
requests:
cpu: 100m
memory: 128Mi
limits:
cpu: 250m
memory: 256Mi
Datenbank-Strategien
Die Datenbank ist der heikelste Teil. Drei Optionen:
Option 1: Datenbank auf der VM lassen. Backend in Kubernetes verbindet sich zur bestehenden DB. Einfach, sicher, null Risiko für die Daten. Für den Anfang die beste Wahl.
Option 2: Managed Database nutzen. RDS, Cloud SQL oder Azure Database. Du gibst Betriebsverantwortung ab und gewinnst Backups, Failover, Skalierung.
Option 3: Datenbank in Kubernetes. Mit StatefulSets und Operatoren (z.B. CloudNativePG, Zalando Postgres Operator) möglich. Verlangt aber Kubernetes-Erfahrung und solides Storage.
| Ansatz | Komplexität | Risiko | Kubernetes-Erfahrung |
|---|---|---|---|
| DB auf VM lassen | Niedrig | Niedrig | Einsteiger |
| Managed DB (RDS etc.) | Mittel | Niedrig | Mittel |
| DB in Kubernetes | Hoch | Mittel | Fortgeschritten |
Starte mit Option 1. Migriere die Datenbank erst, wenn das Team Kubernetes-Erfahrung hat und Persistent Volumes im Cluster stabil laufen.
Typische Stolperfallen
Session-State: Legacy-Apps speichern Sessions im Arbeitsspeicher. Bei mehreren Replicas geht das schief. Lösung: Sessions in Redis oder als JWT-Tokens auslagern.
File-System-Zugriffe: Schreibt die App Dateien lokal? In Kubernetes sind Container ephemeral. Nutze PersistentVolumes oder Object Storage (S3/MinIO).
Hartcodierte IPs: 192.168.1.50 als Datenbank-Adresse funktioniert nicht in Kubernetes. Externalisiere alle Konfiguration in ConfigMaps und Secrets.
Startup-Zeit: Java-Applikationen mit 60 Sekunden Startup brauchen angepasste initialDelaySeconds in den Probes. Sonst killt Kubernetes den Pod, bevor er bereit ist.
FAQ
Muss ich die gesamte App auf einmal migrieren?
Nein. Strangler-Fig-Pattern: Migriere Komponente für Komponente. Frontend zuerst, dann Backend-Services einzeln, Datenbank zuletzt. Ein API-Gateway oder Reverse Proxy routet Traffic zwischen alter und neuer Infrastruktur.
Wie gehe ich mit Legacy-Datenbanken wie Oracle um?
Oracle in Kubernetes zu betreiben ist möglich, aber selten sinnvoll. Lass Oracle auf der bestehenden Infrastruktur und verbinde dich über einen Kubernetes-Service vom Typ ExternalName. Langfristig: Migration auf PostgreSQL evaluieren.
Was ist der minimale Umbau für eine Legacy-App?
Drei Dinge: Logs auf stdout/stderr statt in Dateien schreiben, Konfiguration über Environment-Variablen akzeptieren, und einen Health-Check-Endpunkt bereitstellen. Das reicht für Replatform.
Wie lange dauert die Containerisierung einer typischen App?
Eine einfache stateless App: 1-2 Tage. Eine komplexe Applikation mit Datenbank, File-Uploads und Session-State: 1-3 Wochen inklusive Tests. Der Aufwand steckt selten im Dockerfile, sondern in der Konfigurationsexternalisierung.
Lohnt sich Modernisierung für Apps die bald abgelöst werden?
Nein. Wenn die App in 12 Monaten durch eine neue Lösung ersetzt wird, investiere die Zeit nicht. Setze sie auf die Retain-Liste und fokussiere dich auf strategisch wichtige Systeme.
Legacy zu Kubernetes migrieren?
Wir begleiten Ihre Migration von VMs zu Containern – ohne Produktionsausfall. Erfahrung aus 50+ Migrationsprojekten.
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
Docker zu Kubernetes Migration: 10 häufige Fehler vermeiden
Die 10 häufigsten Fehler bei der Docker-zu-Kubernetes-Migration vermeiden: Resource Limits, Stateful Workloads, Health Checks und Networking praxisnah erklärt.
Java Spring Boot auf Kubernetes containerisieren
Spring Boot Anwendungen für Kubernetes containerisieren: Multi-Stage Dockerfile, JVM-Tuning, Health Checks mit Actuator und fertige Deployment-YAMLs.
Lift-and-Shift vs Refactoring: Migration im Vergleich
Lift-and-Shift oder Refactoring für Kubernetes? Entscheidungsmatrix, praktische Beispiele und das Strangler-Fig-Pattern als Mittelweg für Legacy-Migrationen.
Kubernetes-Migration: Enterprise-Strategie planen
Enterprise-Migrationsstrategie für Kubernetes: Von der Application-Portfolio-Analyse über Migration-Waves bis zur Team-Readiness und Risikominimierung.
Node.js auf Kubernetes: Express-App deployen
Express-Apps auf Kubernetes deployen mit Multi-Stage Dockerfile, Graceful Shutdown, Resource Limits und HPA für stabile Production-Cluster.