Tipp: Auf iPhone/Safari bleiben Navigation und Inhalte ohne JavaScript lesbar; die Buttons sind nur Komfort.
Enterprise Platform Lab
Neu aus Roh-Markdown konsolidiert: logisch gegliedert, offlinefähig, mit sichtbarer Hauptteil-Übersicht, stabiler Navigation, sauberem Text, JetBrains-Dark-Codeblöcken und Inline-SVGs.
Schnellübersicht: alle Hauptteile
Finale Leselogik: Das Buch ist thematisch aufgebaut. Die Rohschritte bleiben im ZIP erhalten, die HTML folgt aber einer fachlichen Reihenfolge.
Für schnelles Lernen zuerst Teil A bis E lesen, danach Praxisfälle und Glossar als Nachschlagewerk verwenden.
Lesepfad ArchitekturTeil A, B, C, H und I: Zielbild, Infrastruktur, Security, Praxisfälle und Glossar.
Lesepfad EntwicklerTeil D, E, F und G: Anwendungen, Datenfluss, Codebeispiele und End-to-End-Sprint.
Lesepfad BetriebTeil B, C, H und Anhang K: Plattform, Observability, DR, Qualität und Abnahme.
Lesepfad PrüfungGlossar, Runbooks, Übungen und Quality-Report für Wiederholung und Kontrolle.
Diese Übersicht ist bewusst sichtbar, damit auf iPhone/Safari nicht nur ein später Anhang wirkt. Die Inhalte selbst bleiben unten klappbar und standardmäßig geschlossen.
Diese Fassung wurde neu aus den Roh-Markdown-Schritten konsolidiert. Die Struktur folgt nicht mehr der Entstehungsreihenfolge, sondern einer fachlichen Lernlogik: Zielbild, Infrastruktur, Plattform, Security, Anwendungen, Daten, Betrieb, DevOps, Beispielprojekt, Praxisfälle, Übungen und Glossar.
Die Build-, Abnahme- und Pflegekapitel stehen nicht als normale Hauptkapitel im Lernweg. Sie sind im Anhang gebündelt, damit das Buch nicht wie eine Chat-Historie wirkt.
Strukturprinzipien
Fachliche Kapitel statt künstlicher Schrittfolge.
Praxis direkt im passenden Kontext.
Glossar und Begriffe als Referenz, nicht als Ersatz für Inhalt.
Code, YAML, SQL, Terraform, Bash und Konfigurationsbeispiele bleiben erhalten.
HTML-Ausgabe ist offlinefähig, mit zentralem JetBrains-Dark-Codeblock-Stil und klappbarer Navigation.
Hauptteile
Teil A: Orientierung, Unternehmenskontext und Zielarchitektur
Teil B: Hybrid-Infrastruktur: Netzwerk, Cloud, VM, Bare Metal und OpenShift
Teil C: Identity, Security, Governance und Plattformregeln
Teil D: Moderne Anwendungen, Datenflüsse, Messaging und Integration
Teil E: Observability, Betrieb, Backup, Disaster Recovery und Resilienz
Teil F: DevOps, GitOps, Release Management und AI-Unterstützung
Teil G: Komplettes Beispielprojekt und große Codebasis
Teil H: Praxisfälle, Betriebsstörungen und End-to-End-Szenarien
Teil I: Übungen, Runbooks, Musterlösungen, kompakte SVGs und Fachglossar
Anhang K: Build-, Abnahme- und Pflegeprozess
---
Teil A: Orientierung, Unternehmenskontext und Zielarchitektur
Teil A: Orientierung, Unternehmenskontext und Zielarchitektur
Konsolidiert aus Rohmaterial: Teil 1.
Unternehmenskontext und Zielbild
Hybrid-Plattform auf einen Blick
Kompakte Themenübersicht
1. Warum dieses Projekt existiert
Ein modernes Enterprise-System entsteht selten auf einer grünen Wiese. In vielen Unternehmen gibt es bereits Anwendungen, Datenbanken, Server, Batchjobs, Integrationen, Berechtigungsmodelle und Betriebsprozesse. Manche Systeme laufen auf virtuellen Maschinen, manche auf Bare-Metal-Servern, manche bereits in Kubernetes oder OpenShift, andere teilweise in der Cloud. Genau daraus entsteht die zentrale Herausforderung dieses Lernprojekts.
Das Ziel ist nicht, eine einzelne kleine Demo-Anwendung zu bauen. Das Ziel ist, eine realistische Enterprise-Landschaft zu verstehen und daraus Schritt für Schritt eine moderne Plattform abzuleiten. Diese Plattform soll mehrere Infrastrukturarten gleichzeitig nutzen: Cloud, virtuelle Maschinen, Bare Metal und Kubernetes/OpenShift. Moderne Anwendungen sollen nicht isoliert betrachtet werden, sondern als Teil eines größeren Betriebsmodells.
In einem echten Unternehmen reicht es nicht, nur einen Spring Boot Service zu starten. Man muss wissen, wie dieser Service authentifiziert wird, wie er Logs schreibt, wie er Metriken liefert, wie er deployt wird, wie Secrets verwaltet werden, wie Daten gesichert werden, wie Störungen behandelt werden und wie Änderungen nachvollziehbar dokumentiert werden. Genau deshalb verbindet dieses Projekt Architektur, Infrastruktur, Entwicklung, Security, Betrieb und DevOps.
Der wichtigste Lernpunkt lautet:
Vorlage / Textauszug
Eine moderne Enterprise-Plattform ist nicht nur Code.
Sie ist das Zusammenspiel aus Anwendungen, Infrastruktur, Security, Betrieb, Deployment, Monitoring, Dokumentation und klaren Entscheidungen.
Dieses Projekt soll zeigen, wie man eine solche Plattform fachlich sauber plant und technisch nachvollziehbar umsetzt.
2. Das Beispielunternehmen
Für das Lernprojekt verwenden wir ein fiktives Unternehmen:
Vorlage / Textauszug
Name: Alpine Retail & Services Group
Branche: Handel, Service, Kundenportal, Abrechnung und Partnerintegration
Standorte: Österreich, Deutschland, Schweiz
Betriebsmodell: Hybrid
Die Alpine Retail & Services Group betreibt mehrere digitale Systeme. Kunden bestellen Produkte und Dienstleistungen über ein modernes Portal. Interne Mitarbeiter bearbeiten Aufträge, prüfen Zahlungen, verwalten Kunden und analysieren Kennzahlen. Partnerunternehmen liefern Daten über Schnittstellen. Einige Prozesse laufen in Echtzeit, andere als nächtliche Verarbeitung.
Die bestehende IT-Landschaft ist historisch gewachsen. Es gibt alte Anwendungen auf virtuellen Maschinen, einige Datenbanken auf Bare-Metal-Servern, einzelne Cloud-Dienste und erste Container-Plattformen. Die Organisation möchte nicht alles auf einmal ersetzen. Stattdessen soll eine moderne Plattform entstehen, die neue Anwendungen sauber aufnimmt und alte Systeme kontrolliert integriert.
Das Unternehmen hat folgende Ziele:
Vorlage / Textauszug
Neue Anwendungen schneller entwickeln
Deployment-Prozesse automatisieren
Sicherheit nachvollziehbar verbessern
Betrieb und Monitoring vereinheitlichen
Alte Systeme kontrolliert anbinden
Cloud, VM, Bare Metal und OpenShift sinnvoll kombinieren
Wissen dokumentieren und wiederholbar machen
Dieses Unternehmen ist bewusst realistisch gewählt. Es gibt keine perfekte Ausgangslage. Genau dadurch wird das Projekt nützlich.
3. Ausgangslage der IT-Landschaft
Die Ausgangslandschaft besteht aus mehreren Bereichen.
Es gibt klassische virtuelle Maschinen für interne Anwendungen. Diese Systeme sind stabil, aber oft schwer automatisierbar. Updates werden teilweise manuell durchgeführt. Konfigurationen liegen nicht immer vollständig in Git. Monitoring existiert, aber nicht überall einheitlich.
Es gibt Bare-Metal-Server für datenintensive oder besonders performante Systeme. Dazu gehören große Datenbanken, File-Verarbeitung und Backup-Systeme. Diese Systeme sind wichtig, weil nicht jede Enterprise-Last sinnvoll in Kubernetes verschoben wird. Manche Workloads brauchen direkten Zugriff auf Storage, spezielle Hardware oder besonders planbare Performance.
Es gibt erste Cloud-Komponenten. Diese werden für Object Storage, Testumgebungen, externe APIs oder skalierbare Web-Komponenten genutzt. Die Cloud bringt Flexibilität, aber auch neue Risiken: Kostenkontrolle, Identitätsmanagement, Netzwerkdesign und Datenklassifizierung müssen sauber geregelt werden.
Außerdem gibt es eine OpenShift-Plattform. Auf dieser Plattform sollen moderne Services laufen: Order Service, Billing Service, Customer Portal, Admin Portal, Reporting-Komponenten und Integrationsservices. OpenShift dient als standardisierte Laufzeitumgebung für containerisierte Anwendungen.
Die Ausgangslage ist also nicht:
Vorlage / Textauszug
Alles läuft in Kubernetes.
sondern:
Vorlage / Textauszug
Ein Teil läuft in Kubernetes.
Ein Teil läuft auf VMs.
Ein Teil läuft auf Bare Metal.
Ein Teil nutzt Cloud-Dienste.
Alle Teile müssen zusammen funktionieren.
Das ist der Kern des Projekts.
4. Warum Hybrid statt nur Cloud oder nur Kubernetes?
Viele Lernprojekte zeigen eine sehr einfache Welt: Anwendung bauen, Dockerfile schreiben, Kubernetes Deployment erstellen, fertig. Das ist für den Einstieg gut, aber nicht ausreichend für Enterprise-Architektur.
In echten Unternehmen gibt es Gründe, warum nicht alles in die Cloud oder nach Kubernetes wandert.
Eine relationale Hauptdatenbank kann auf Bare Metal bleiben, weil sie sehr große Datenmengen verarbeitet, spezielle Backup-Strategien nutzt oder bestehende Lizenzmodelle hat. Ein altes Reporting-System kann auf einer VM bleiben, weil es noch nicht modernisiert wurde, aber weiterhin gebraucht wird. Ein File Processing Service kann bewusst außerhalb von Kubernetes laufen, weil er sehr große Dateien verarbeitet und direkten Zugriff auf ein internes Dateisystem benötigt.
Gleichzeitig ist Kubernetes oder OpenShift sehr sinnvoll für moderne Services. Neue APIs, Web-Portale, Event Consumer, Backend-for-Frontend-Komponenten und Integrationsservices profitieren von Containerisierung, automatisierten Deployments, Health Checks, Skalierung und GitOps.
Cloud-Dienste sind wiederum stark bei Object Storage, globaler Verfügbarkeit, temporären Umgebungen, Managed Services und externer Integration.
Die Architekturentscheidung lautet daher:
Vorlage / Textauszug
Nicht jede Anwendung muss auf dieselbe Infrastruktur.
Jede Anwendung soll auf die Infrastruktur, die zu ihren Anforderungen passt.
Das Ziel ist keine ideologische Plattformentscheidung, sondern eine fachlich begründete Zuordnung.
5. Zielplattform des Projekts
Die Zielplattform heißt:
Vorlage / Textauszug
Enterprise Platform Lab
Sie besteht aus folgenden Bausteinen:
Vorlage / Textauszug
Moderne Anwendungen auf OpenShift
Datenbanken teilweise auf Bare Metal oder Managed Cloud
interne Systeme auf virtuellen Maschinen
Object Storage in Cloud oder MinIO
zentrale Identität über Keycloak und LDAP/Active Directory
Messaging über Kafka oder RabbitMQ
GitOps mit Argo CD
CI/CD mit GitHub Actions, GitLab CI oder Jenkins
Observability mit Prometheus, Grafana, Loki und Tempo
Secret Management mit Vault oder External Secrets
Backup und Restore mit klaren Runbooks
Dokumentation über README, ADRs und Betriebsanleitungen
Diese Plattform ist kein einzelnes Produkt. Sie ist ein Betriebsmodell.
6. Die wichtigsten Anwendungen im Lab
Customer Portal
Das Customer Portal ist die Weboberfläche für Kunden. Es zeigt Bestellungen, Rechnungen, Statusinformationen und Benachrichtigungen. Es läuft als moderne Frontend-Anwendung, zum Beispiel mit React oder Angular. Die Anwendung nutzt OIDC für Login und ruft Backend-APIs auf.
Das Customer Portal eignet sich gut für OpenShift oder Cloud Hosting, weil es skaliert werden kann und häufige Releases möglich sind.
Order Service
Der Order Service verwaltet Bestellungen. Er nimmt neue Bestellungen entgegen, validiert sie, speichert sie in PostgreSQL und veröffentlicht Events. Dieser Service ist ein typischer moderner Backend-Service.
Er läuft auf OpenShift, weil er gut containerisierbar ist, Health Checks unterstützt und über GitOps deployt werden kann.
Billing Service
Der Billing Service verarbeitet abrechnungsrelevante Events. Er erstellt Rechnungsentwürfe, prüft Zahlungsstatus und schreibt Audit-Informationen. Er konsumiert Events aus Kafka oder RabbitMQ.
Dieser Service zeigt, wie eventgetriebene Architektur funktioniert.
Reporting Service
Der Reporting Service erzeugt Auswertungen. Er kann teilweise als Kubernetes CronJob laufen, teilweise aber auch auf einer VM, wenn er alte Reporting-Werkzeuge oder spezielle Treiber benötigt.
Dieses Beispiel zeigt bewusst, dass nicht jeder Prozess automatisch ein dauerhafter Kubernetes-Service sein muss.
File Processing Service
Der File Processing Service verarbeitet große Dateien von Partnern. Er prüft Dateiformate, extrahiert Inhalte, schreibt Fehlerprotokolle und übergibt gültige Daten an interne Services.
Dieser Service kann auf Bare Metal oder VM laufen, wenn er sehr große Dateien verarbeitet oder direkten Zugriff auf Storage benötigt. Alternativ kann er modernisiert und als containerisierter Worker betrieben werden.
Admin Portal
Das Admin Portal ist für interne Mitarbeiter. Es erlaubt manuelle Korrekturen, Statusprüfungen und administrative Aktionen. Wegen sensibler Funktionen braucht es starke Authentifizierung, Rollenmodell, Audit Logging und klare Berechtigungen.
Dieses Portal zeigt, warum Security nicht am Ende angeklebt werden darf.
7. Zielarchitektur im Überblick
Skizze / Textauszug
Kunden
↓
Customer Portal
↓
API Gateway / Ingress / Route
↓
Order Service
↓
PostgreSQL
↓
Outbox Events
↓
Kafka / RabbitMQ
↓
Billing Service
↓
Invoice Store / Audit Log
Die Zielarchitektur verwendet bewusst unterschiedliche Infrastrukturtypen.
OpenShift wird für moderne Services genutzt. Dazu gehören Order Service, Billing Service, Customer Portal, API Gateway, kleinere Worker und GitOps-gesteuerte Anwendungen. Diese Workloads profitieren von standardisierten Deployments, automatischem Neustart, Skalierung und Observability.
Virtuelle Maschinen bleiben wichtig für Systeme, die noch nicht containerisiert sind oder die besondere Betriebsvorgaben haben. Dazu gehören interne Tools, ältere Reporting-Komponenten, Migrationshelfer oder Dienste mit speziellen Betriebssystemabhängigkeiten.
Bare Metal wird dort genutzt, wo Performance, Storage, Latenz oder Hardwarebindung entscheidend sind. Beispiele sind große Datenbanken, Backup-Systeme, Storage Gateways oder besonders datenintensive File-Verarbeitung.
Cloud wird dort eingesetzt, wo Flexibilität, schnelle Bereitstellung oder externe Verfügbarkeit wichtig ist. Beispiele sind Object Storage, Testumgebungen, externe Schnittstellen, CDN-nahe Webauslieferung oder temporäre Analyseumgebungen.
10. Erste Architekturentscheidung
ADR 001: Hybrid statt Single Platform
Vorlage / Textauszug
ADR 001: Hybrid Platform statt Single Platform
Status
Akzeptiert
Kontext
Die Alpine Retail & Services Group betreibt Anwendungen auf virtuellen Maschinen, Bare-Metal-Servern, Cloud-Diensten und einer OpenShift-Plattform. Eine vollständige Migration aller Workloads auf eine einzige Plattform wäre teuer, riskant und fachlich nicht sinnvoll.
Entscheidung
Das Zielsystem wird als hybride Enterprise-Plattform aufgebaut.
OpenShift wird als Standardplattform für moderne containerisierte Anwendungen verwendet. Virtuelle Maschinen bleiben für bestehende interne Anwendungen und Übergangssysteme erlaubt. Bare Metal bleibt für datenintensive Systeme und Storage-nahe Verarbeitung erlaubt. Cloud-Dienste werden gezielt für Object Storage, Testumgebungen und externe Integrationen eingesetzt.
Konsequenzen
Die Plattform benötigt klare Regeln für Netzwerk, Identität, Monitoring, Deployment und Dokumentation über Infrastrukturgrenzen hinweg.
In vielen Projekten wird Dokumentation als Zusatz betrachtet. Man schreibt zuerst Code, danach vielleicht eine README. In einem Enterprise-Projekt ist das zu spät.
Dokumentation ist ein Architekturartefakt. Eine README erklärt den Zweck eines Systems. Ein ADR erklärt, warum eine Entscheidung getroffen wurde. Ein Runbook erklärt, wie der Betrieb reagiert, wenn etwas schiefgeht. Ein Manifest zeigt die technische Umsetzung. Ein Test zeigt, ob eine Annahme überprüfbar ist.
13. Beispiel: README für den Order Service
Vorlage / Textauszug
Order Service
Zweck
Der Order Service verwaltet Kundenbestellungen. Er nimmt Bestellungen über eine REST API entgegen, validiert fachliche Regeln, speichert Bestellungen in PostgreSQL und veröffentlicht fachliche Events über das Outbox Pattern.
Grenzen
Der Service erstellt keine Rechnungen. Rechnungen werden vom Billing Service erzeugt.
Der Service versendet keine E-Mails. Benachrichtigungen werden über einen separaten Notification Service verarbeitet.
Der Service führt keine Kundenauthentifizierung selbst durch. Authentifizierung erfolgt über Keycloak und OIDC.
14. Erste technische Leitplanken
Für Java-Services gilt Java 21, Spring Boot oder Quarkus, REST APIs mit OpenAPI, strukturierte Logs, Health Checks, Metriken, Testcontainers, Flyway oder Liquibase und eine klare Paketstruktur.
Für Frontends gilt React oder Angular, OIDC Login, Trennung von API Client und UI-Komponenten, sichtbare Fehlerzustände, keine Secrets im Frontend und Build als Container Image.
Für OpenShift gilt Deployment, Service, Route, ConfigMap, Secret oder ExternalSecret, Resource Requests und Limits, Probes, NetworkPolicy, ServiceMonitor und Argo CD Application.
package com.seb4u.demo.spring.order.application;
import com.seb4u.demo.spring.order.domain.Order;
import com.seb4u.demo.spring.order.domain.OrderRepository;
import com.seb4u.demo.spring.order.domain.OrderStatus;
import com.seb4u.demo.spring.order.domain.events.OrderCreatedEvent;
import com.seb4u.demo.spring.order.infrastructure.messaging.OutboxPublisher;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.time.Clock;
import java.time.Instant;
import java.util.Objects;
@Servicepublicclass OrderApplicationService implements CreateOrderUseCase {
privatefinal OrderRepository orderRepository;
privatefinal OutboxPublisher outboxPublisher;
privatefinal Clock clock;
public OrderApplicationService(OrderRepository orderRepository, OutboxPublisher outboxPublisher, Clock clock) {
this.orderRepository = orderRepository;
this.outboxPublisher = outboxPublisher;
this.clock = clock;
}
@Override@Transactionalpublic CreateOrderResult createOrder(CreateOrderCommand command) {
validate(command);
Order order = Order.create(command.customerId(), command.items(), OrderStatus.CREATED, Instant.now(clock));
Order savedOrder = orderRepository.save(order);
outboxPublisher.store(new OrderCreatedEvent(
savedOrder.id().value(),
savedOrder.customerId().value(),
savedOrder.totalAmount(),
savedOrder.createdAt()
));
returnnew CreateOrderResult(savedOrder.id().value(), savedOrder.status().name());
}
privatevoid validate(CreateOrderCommand command) {
Objects.requireNonNull(command, class="str">"command must not be null");
if (command.customerId() == null || command.customerId().isBlank()) {
thrownew IllegalArgumentException(class="str">"customerId must not be blank");
}
if (command.items() == null || command.items().isEmpty()) {
thrownew IllegalArgumentException(class="str">"order must contain at least one item");
}
}
}
17. Warum Outbox wichtig ist
Ohne Outbox könnte der Order Service eine Bestellung speichern und danach ein Event an Kafka senden. Wenn Kafka in diesem Moment nicht erreichbar ist, wurde die Bestellung gespeichert, aber kein Event veröffentlicht. Der Billing Service erfährt nichts davon.
Das Outbox Pattern löst dieses Problem, indem das Event zunächst in derselben Datenbanktransaktion gespeichert wird wie die Bestellung.
18. Erste Datenbankmigration
sql
CREATETABLE orders (
id UUID PRIMARYKEY,
customer_id VARCHAR(80) NOTNULL,
status VARCHAR(40) NOTNULL,
total_amount NUMERIC(12, 2) NOTNULL,
created_at TIMESTAMP WITH TIME ZONE NOTNULL,
updated_at TIMESTAMP WITH TIME ZONE
);
CREATETABLE outbox_events (
id UUID PRIMARYKEY,
aggregate_type VARCHAR(120) NOTNULL,
aggregate_id VARCHAR(120) NOTNULL,
event_type VARCHAR(160) NOTNULL,
payload JSONB NOTNULL,
created_at TIMESTAMP WITH TIME ZONE NOTNULL,
published_at TIMESTAMP WITH TIME ZONE,
publish_attempts INTEGER NOTNULL DEFAULT 0,
last_error TEXT
);
Ein häufiger Fehler ist, sofort Code zu schreiben, ohne Zielbild und Betriebsmodell zu klären. Ein zweiter Fehler ist, Kubernetes als Lösung für alles zu betrachten. Ein dritter Fehler ist, Security zu spät einzubauen. Ein vierter Fehler ist fehlende Dokumentation. Ein fünfter Fehler ist fehlende Observability.
21. Übung und Musterlösung
Erstelle eine eigene Zielbeschreibung mit Anwendungen, Plattformzuordnung, Authentifizierung, Event-Verarbeitung und Monitoring. Eine mögliche Lösung ordnet Customer Portal, Admin Portal, Order Service und Billing Service OpenShift zu, lässt Reporting vorerst auf VM, hält große Datenbanken auf Bare Metal und nutzt Keycloak, Kafka, Prometheus, Loki und Grafana als gemeinsame Plattformdienste.
22. Merksätze
Eine Enterprise-Plattform ist kein einzelnes Tool. Eine Hybrid-Architektur ist oft die realistische Antwort auf unterschiedliche Anforderungen. OpenShift eignet sich sehr gut für moderne Services, aber nicht jeder Workload muss dort laufen. Dokumentation ist Teil der Architektur, nicht Nacharbeit.
Teil B: Hybrid-Infrastruktur: Netzwerk, Cloud, VM, Bare Metal und OpenShift
Teil B: Hybrid-Infrastruktur: Netzwerk, Cloud, VM, Bare Metal und OpenShift
Konsolidiert aus Rohmaterial: Teil 2, Teil 3, Teil 4, Teil 5.
Infrastruktur-Fundament
Netzwerkzonen kompakt
Kompakte Themenübersicht
1. Warum Infrastruktur zuerst verstanden werden muss
Moderne Anwendungen hängen nicht in der Luft. Jede Anwendung braucht Netzwerk, DNS, Zertifikate, Routing, Storage, Identität, Monitoring und Zugriff auf andere Systeme. Wenn diese Grundlagen unklar sind, wird selbst ein sauber geschriebener Service im Betrieb instabil.
Viele Entwickler sehen Infrastruktur erst, wenn ein Problem entsteht: Die Anwendung startet lokal, aber im Cluster nicht. Die API funktioniert intern, aber von außen ist sie nicht erreichbar. Der Login funktioniert in der Testumgebung, aber in Produktion scheitert OIDC wegen falscher Redirect-URI. Die Datenbank ist erreichbar, aber nur aus einem Namespace, nicht aus dem anderen.
Deshalb beginnt ein Enterprise-Projekt nicht nur mit Code. Es beginnt mit einer klaren Infrastruktur-Landkarte.
2. Netzwerkzonen im Unternehmen
Netzwerkzonen
Kompakte Lernhilfe
Ein Unternehmen trennt sein Netzwerk in Zonen. Diese Trennung schützt Systeme, begrenzt Schäden und macht Zugriffe kontrollierbar.
Eine einfache Enterprise-Landschaft kann folgende Zonen haben:
Vorlage / Textauszug
Internet
DMZ
Application Zone
Data Zone
Management Zone
Backup Zone
Development Zone
Die DMZ ist eine Übergangszone zwischen Internet und internem Netzwerk. Hier stehen Systeme, die von außen erreichbar sein müssen, aber nicht direkt Zugriff auf alle internen Systeme bekommen sollen.
Die Application Zone enthält interne Anwendungen, APIs, OpenShift Worker Nodes oder virtuelle Maschinen mit Applikationsdiensten. Die Data Zone enthält Datenbanken, Message Broker, Storage-Systeme und andere datenführende Komponenten. Die Management Zone enthält Administrationszugänge, Monitoring-Systeme, Jump Hosts, Bastion Hosts, Deployment-Server oder zentrale Management-Dienste.
Die DMZ ist eine Sicherheitsgrenze. Ein Customer Portal oder API Gateway muss von außen erreichbar sein. Trotzdem soll ein Angreifer, der diese Komponente erreicht, nicht automatisch Zugriff auf interne Datenbanken bekommen.
In einer vereinfachten Architektur sieht der Zugriff so aus:
Skizze / Textauszug
Internet
↓
Firewall
↓
DMZ Load Balancer
↓
API Gateway
↓
interner Service
↓
Datenbank
Jede Stufe hat eigene Regeln.
5. VLANs und Subnetze
Subnetz-Aufteilung
Kompakte Lernhilfe
Ein VLAN trennt Netzwerkverkehr logisch. Ein Subnetz beschreibt den IP-Adressbereich. In Unternehmen werden VLANs oft genutzt, um Zonen technisch zu trennen.
Eine IP-Adresse ist nicht nur eine Adresse. Sie verrät oft, in welcher Zone ein System steht.
6. Firewall-Regeln als Architekturartefakt
Firewall-Regeln sollten nicht nur in einer Firewall-Oberfläche existieren. Sie sollten dokumentiert werden. Eine gute Regel beschreibt Quelle, Ziel, Port, Protokoll, Zweck, verantwortlichen Service und Review-Datum.
Beispiel:
Vorlage / Textauszug
Quelle: OpenShift Namespace order-prod
Ziel: PostgreSQL Cluster orders-db
Port: 5432
Protokoll: TCP
Zweck: Order Service schreibt und liest Bestellungen
Verantwortlich: Team Order
Review: alle 6 Monate
Das ist besser als eine breite Regel wie Allow 10.10.30.0/24 to 10.10.40.0/24 any.
7. DNS
DNS wird oft unterschätzt. Wenn DNS falsch ist, sehen Fehler häufig wie Anwendungsfehler aus. Typische Symptome sind fehlerhafte OIDC-Redirects, TLS-Probleme, falsche Umgebung oder nicht erreichbare Datenbanken.
Beispielhafte Namen:
Vorlage / Textauszug
customer.alpine.example.com
admin.alpine.example.com
api.alpine.example.com
keycloak.alpine.example.com
grafana.alpine.example.com
orders-db.internal.alpine.example.com
kafka.internal.alpine.example.com
8. Load Balancer
Ein Load Balancer verteilt Anfragen auf mehrere Ziele. In Enterprise-Architekturen gibt es oft mehrere Load-Balancer-Ebenen:
Skizze / Textauszug
Externer Load Balancer
↓
OpenShift Router
↓
Service
↓
Pod
Wenn eine Anwendung nicht erreichbar ist, kann der Fehler an DNS, Firewall, Load Balancer, OpenShift Route, Service Selector, Pod Readiness oder Anwendungsport liegen.
9. Beispiel: Fehlersuche bei nicht erreichbarer API
bash
# 1. DNS prüfen
nslookup api.alpine.example.com
# 2. Verbindung prüfen
curl -vk https://api.alpine.example.com/order
# 3. OpenShift Route prüfen
oc get route -n order-prod
# 4. Service prüfen
oc get svc -n order-prod
# 5. Endpoints prüfen
oc get endpoints -n order-prod order-service
# 6. Pods prüfen
oc get pods -n order-prod -l app=order-service
# 7. Logs prüfen
oc logs -n order-prod deployment/order-service --tail=100
10. Virtuelle Maschinen im Lab
VMs eignen sich für Anwendungen mit Betriebssystemabhängigkeiten, alte Reporting-Systeme, interne Admin-Tools, Migrationshelfer, Tools mit grafischer Oberfläche, Systeme, die noch nicht containerisiert wurden, und Übergangsarchitekturen.
Eine VM braucht Patchmanagement, SSH-Kontrolle, lokale Logs, Systemdienste, Dateisystemüberwachung, Backup und Konfigurationsmanagement.
Bare Metal bedeutet, dass ein System direkt auf physischer Hardware läuft. Das kann sinnvoll sein, wenn Performance, Storage oder Hardwarezugriff wichtig sind. Beispiele sind große relationale Datenbanken, Backup-Repositories, Storage-Systeme, große File Processing Jobs und Systeme mit spezieller Hardware.
13. Storage-Grundlagen
Es gibt Block Storage, File Storage, Object Storage, Database Storage, Backup Storage und Ephemeral Storage. Ein typischer Anfängerfehler ist, Dateien im Container-Dateisystem zu speichern und zu erwarten, dass sie nach einem Neustart noch da sind. Container sind vergänglich.
14. File Processing mit Object Storage
Skizze / Textauszug
Partner
↓
SFTP Gateway oder Upload API
↓
Object Storage Bucket incoming
↓
File Processing Worker
↓
Validierung
↓
Object Storage Bucket processed oder rejected
↓
Event an Broker
↓
Order Service oder Reporting
15. OpenShift im Infrastrukturkontext
OpenShift ist Teil der Infrastruktur, aber nicht die gesamte Infrastruktur. Ein OpenShift Cluster braucht Nodes, Netzwerk, DNS, Zertifikate, Storage, Registry, Authentifizierung, Monitoring, Logging und Backup.
Ein Service im Cluster braucht Namespace, ServiceAccount, Deployment, Service, Route oder Ingress, ConfigMap, Secret, Resource Limits, Probes und NetworkPolicy.
16. Namespaces
Namespaces helfen bei Zugriffskontrolle, Resource Quotas, NetworkPolicies, Deployment-Trennung, Monitoring-Zuordnung, Kosten- und Verantwortungszuordnung.
Wenn Server unterschiedliche Uhrzeiten haben, entstehen Probleme mit OIDC Tokens, TLS-Zertifikaten, Log-Korrelation, Audit-Nachweisen und Datenbankreplikation. Deshalb braucht jedes System sauberes NTP oder Chrony.
19. Infrastructure as Code
Infrastruktur sollte nicht nur in Oberflächen geklickt werden. Klicks sind schwer wiederholbar.
oc get secret -n order-prod order-db-secret -o yaml
Vorlage / Textauszug
Häufige Ursachen
falscher DNS-Eintrag
Firewall-Regel fehlt
Datenbankdienst gestoppt
Secret enthält falschen Host
NetworkPolicy blockiert Egress
Zertifikat oder TLS-Einstellung falsch
21. Typische Fehler
Typische Fehler sind fehlende Zonierung, fehlende Namenskonvention, manuelle Serverkonfiguration, fehlende Dokumentation von Firewall-Regeln, Storage-Missverständnisse und fehlende Zeit-Synchronisation.
22. Übung und Musterlösung
Erstelle eine Infrastruktur-Landkarte mit mindestens fünf Netzwerkzonen, drei Anwendungen, zwei Datenkomponenten, einem Broker, Monitoring, Backup-Pfad und administrativem Zugriffspfad. Eine mögliche Lösung trennt DMZ, Application Zone, Data Zone, Management Zone und Backup Zone und erlaubt aus dem Internet nur HTTPS auf den externen Load Balancer.
23. Merksätze
Infrastruktur ist Teil der Anwendungsarchitektur. DNS, Firewall, Zertifikate und Routing sind keine Nebensachen. Eine DMZ schützt interne Systeme vor direkter Exposition. Nicht jede Anwendung gehört in Kubernetes. Infrastructure as Code macht Infrastruktur nachvollziehbar.
Cloud-Architektur
Landing Zone und Hybrid-Anbindung
Kompakte Themenübersicht
1. Warum Cloud im Hybrid-Lab wichtig ist
Cloud ist in diesem Lernprojekt kein Ersatz für alles andere. Cloud ist ein zusätzlicher Baustein in einer hybriden Enterprise-Landschaft. Sie wird dort eingesetzt, wo sie echte Vorteile bringt: schnelle Bereitstellung, flexible Testumgebungen, Object Storage, externe Schnittstellen, skalierbare Frontend-Auslieferung, temporäre Analyseumgebungen oder Managed Services.
Der wichtigste Punkt lautet: Cloud ist nicht automatisch modern, sicher oder günstig. Eine schlecht geplante Cloud-Umgebung kann teurer, unübersichtlicher und unsicherer werden als eine klassische VM-Landschaft. Deshalb muss Cloud-Architektur genauso sorgfältig geplant werden wie Netzwerk, OpenShift, Bare Metal oder virtuelle Maschinen.
Für die Alpine Retail & Services Group bedeutet Cloud nicht: Alle Systeme werden in AWS, Azure oder Google Cloud verschoben. Die Cloud übernimmt gezielte Aufgaben. Das Customer Portal kann Cloud-nahe ausgeliefert werden. Partnerdateien können in Object Storage landen. Testumgebungen können temporär erstellt und wieder gelöscht werden. Externe APIs können über Cloud-nahe Gateways angebunden werden. Kritische Hauptdatenbanken können trotzdem auf Bare Metal oder in einer kontrollierten privaten Umgebung bleiben.
Cloud wird also nicht ideologisch verwendet, sondern fachlich begründet.
2. Grundprinzip einer Cloud-Landing-Zone
Eine Cloud-Landing-Zone ist die vorbereitete Grundfläche für Cloud-Workloads. Sie ist vergleichbar mit dem Fundament eines Gebäudes. Bevor Anwendungen einziehen, müssen Netzwerk, Identität, Logging, Sicherheit, Kostenkontrolle und Governance definiert sein.
Eine Landing-Zone beantwortet Fragen wie:
Vorlage / Textauszug
Welche Accounts oder Subscriptions gibt es?
Welche Netzwerke gibt es?
Wie werden Umgebungen getrennt?
Wer darf Ressourcen erstellen?
Wie werden Logs gesammelt?
Wie werden Kosten zugeordnet?
Welche Regionen sind erlaubt?
Welche Daten dürfen in die Cloud?
Wie wird die Cloud mit dem Rechenzentrum verbunden?
Ohne Landing-Zone entstehen schnell einzelne Cloud-Ressourcen ohne Zusammenhang. Ein Entwickler erstellt einen Storage Bucket, ein anderer eine Datenbank, ein dritter ein öffentliches Netzwerk. Nach einigen Monaten weiß niemand mehr, welche Ressource produktiv ist, welche Daten sie enthält und wer verantwortlich ist.
Eine gute Landing-Zone verhindert dieses Chaos nicht vollständig, aber sie setzt klare Leitplanken.
3. Accounts, Subscriptions und Umgebungen
In großen Umgebungen werden Cloud-Ressourcen nicht alle in einem einzigen Konto betrieben. Es gibt eine Trennung nach Umgebung, Verantwortung und Risiko.
platform-shared enthält gemeinsame Plattformdienste. security-logging sammelt Logs, Audit-Ereignisse und Sicherheitsinformationen. network-hub enthält zentrale Netzwerkkomponenten wie VPN, Transit Gateway oder Firewall. dev-workloads, test-workloads und prod-workloads trennen Anwendungen nach Umgebung. sandbox erlaubt Experimente, aber nur mit begrenzten Rechten und Budgetgrenzen.
Diese Trennung ist wichtig. Eine fehlerhafte Testressource darf nicht Produktionsdaten erreichen. Eine Sandbox darf keine unkontrollierten öffentlichen Datenbanken erzeugen. Produktionsressourcen müssen strenger geschützt und stärker überwacht werden als Entwicklungsressourcen.
4. VPC und VNet als Cloud-Netzwerk
Cloud-Netzwerk
Kompakte Lernhilfe
In AWS heißt das virtuelle Netzwerk VPC. In Azure heißt es VNet. Andere Clouds haben ähnliche Konzepte. Die Idee ist dieselbe: Man erstellt ein isoliertes Netzwerk in der Cloud und unterteilt es in Subnetze.
Für das Lab könnte die Cloud-Netzwerkstruktur so aussehen:
Öffentliche Subnetze sind nicht automatisch gefährlich, aber sie müssen streng kontrolliert werden. Dort stehen typischerweise Load Balancer, NAT Gateways oder Reverse Proxies. Anwendungen und Datenbanken gehören normalerweise in private Subnetze.
Ein typischer Fehler ist, eine Datenbank in ein öffentliches Subnetz zu stellen, weil es beim ersten Test einfacher ist. Das ist im Enterprise-Kontext fast immer falsch.
5. Cloud-Netzwerkdiagramm
mermaid
flowchart TB
Internet[Internet] --> PublicLB[Public Load Balancer]
subgraph Cloud[Cloud VPC / VNet]
subgraph Public[Public Subnets]
PublicLB
NAT[NAT Gateway]
end
subgraph PrivateApp[Private App Subnets]
UploadAPI[Partner Upload API]
TestPortal[Test Customer Portal]
Worker[Cloud Worker]
end
subgraph PrivateData[Private Data Subnets]
ObjectStore[(Object Storage Endpoint)]
ManagedDB[(Managed Database optional)]
end
subgraph Mgmt[Management Subnet]
Runner[CI Runner]
Bastion[Cloud Bastion]
end
end
PublicLB --> UploadAPI
UploadAPI --> ObjectStore
Worker --> ObjectStore
Worker --> ManagedDB
Runner --> PrivateApp
Bastion --> PrivateApp
subgraph Datacenter[On-Prem Rechenzentrum]
OCP[OpenShift]
PG[(Bare Metal PostgreSQL)]
Kafka[(Kafka / RabbitMQ)]
end
PrivateApp <-->|VPN / Direct Connect| OCP
PrivateData <-->|VPN / Direct Connect| PG
Worker --> Kafka
Dieses Diagramm zeigt, dass Cloud und Rechenzentrum miteinander verbunden sind. Die Cloud ist nicht isoliert. Sie muss in DNS, Identität, Monitoring, Sicherheit und Betriebsprozesse integriert werden.
6. Public und Private Subnets
Public Subnets haben typischerweise eine Route ins Internet. Private Subnets haben keine direkte öffentliche Erreichbarkeit. Sie erreichen externe Dienste über NAT, Proxy oder definierte Ausgänge.
Für Enterprise-Workloads gilt oft:
Vorlage / Textauszug
Load Balancer: public möglich
Anwendungen: private bevorzugt
Datenbanken: private
Message Broker: private
Management: private
CI Runner: private oder streng kontrolliert
Das Customer Portal kann öffentlich erreichbar sein, aber seine Backend-Services müssen nicht öffentlich sein. Eine Upload API kann extern erreichbar sein, aber sie sollte nicht direkt Datenbanken erreichen. Stattdessen schreibt sie Dateien in Object Storage und veröffentlicht kontrolliert Events oder Metadaten.
Ein gutes Netzwerkdesign reduziert die Angriffsfläche.
7. Security Groups und Network Security Groups
Freigaben in der Cloud
Kompakte Lernhilfe
Cloud-Firewalls werden je nach Anbieter unterschiedlich genannt. In AWS heißen sie Security Groups, in Azure Network Security Groups. Sie definieren, welche Verbindungen erlaubt sind.
Eine gute Security Group ist eng begrenzt:
Vorlage / Textauszug
Erlaube HTTPS von Internet zum Public Load Balancer.
Erlaube HTTPS vom Load Balancer zur Upload API.
Erlaube Zugriff von Worker zu Object Storage Endpoint.
Erlaube keinen direkten Datenbankzugriff aus dem Internet.
Eine schlechte Regel sieht so aus:
Skizze / Textauszug
0.0.0.0/0 darf auf Port 5432 zugreifen.
Das würde bedeuten: Jede Adresse im Internet darf versuchen, PostgreSQL zu erreichen. Auch wenn Benutzername und Passwort stark sind, ist das eine unnötige und gefährliche Exposition.
Security Groups sind Teil der Architektur. Sie gehören in Code, Review und Dokumentation.
Dieses Beispiel ist noch kein vollständiges Netzwerk. Es zeigt aber das Prinzip: Netzwerk wird als Code beschrieben, bekommt Tags und ist reproduzierbar.
9. Object Storage als Cloud-Baustein
Object Storage ist einer der nützlichsten Cloud-Bausteine für hybride Enterprise-Systeme. Er eignet sich für Dateien, Exporte, Partnerdaten, Reports, Backups, statische Assets und Archivdaten.
Im Lab nutzen wir Object Storage für Partnerdateien:
Skizze / Textauszug
incoming/ neue Dateien von Partnern
processing/ Dateien in Verarbeitung
processed/ erfolgreich verarbeitete Dateien
rejected/ fachlich oder technisch abgelehnte Dateien
archive/ langfristige Ablage
Diese Struktur ist einfach, aber sehr hilfreich. Sie macht Zustände sichtbar und erlaubt Wiederholungen.
Eine Datei wird nicht einfach überschrieben. Sie bekommt eine eindeutige ID, Metadaten und einen Verarbeitungsstatus. Dadurch kann man später nachvollziehen, wann sie angekommen ist, wer sie geliefert hat, welche Prüfung fehlgeschlagen ist und ob ein erneuter Lauf möglich ist.
10. Beispiel: Bucket mit Versionierung und Verschlüsselung
Wichtig ist der letzte Block. Ein Bucket mit Partnerdaten darf nicht versehentlich öffentlich werden.
11. IAM: Identität in der Cloud
IAM regelt, wer oder was Cloud-Ressourcen verwenden darf. Dabei geht es nicht nur um menschliche Benutzer. Auch Anwendungen, CI/CD-Pipelines, Worker und externe Integrationen brauchen Identitäten.
Ein gutes IAM-Modell verwendet möglichst kurze, konkrete Rechte.
Nicht gut:
Vorlage / Textauszug
Service bekommt AdministratorAccess.
Besser:
Vorlage / Textauszug
Upload API darf nur in incoming/ schreiben.
File Processor darf aus incoming/ lesen, nach processed/ schreiben und nach rejected/ schreiben.
Reporting darf nur aus archive/ lesen.
Rechte sollten sich an Aufgaben orientieren, nicht an Bequemlichkeit.
Diese Policy ist fachlich verständlich. Sie beschreibt nicht nur technische Rechte, sondern spiegelt den Ablauf des File Processing wider.
13. Managed Databases: Nutzen und Grenzen
Cloud-Anbieter bieten Managed Databases an. Das kann sehr hilfreich sein, weil viele Betriebsaufgaben übernommen werden: Patching, Backups, Replikation, Monitoring-Integration und Hochverfügbarkeit.
Trotzdem ist eine Managed Database nicht automatisch die richtige Wahl.
Sie ist gut, wenn:
Vorlage / Textauszug
das Team weniger Datenbankbetrieb selbst machen möchte
die Daten in der Cloud bleiben dürfen
Latenz zu Cloud-Anwendungen niedrig sein soll
Standardfunktionen ausreichen
Backup und HA durch den Anbieter genutzt werden können
Sie ist problematisch, wenn:
Vorlage / Textauszug
Daten das Rechenzentrum nicht verlassen dürfen
spezielle Erweiterungen benötigt werden
bestehende Lizenzmodelle dagegen sprechen
sehr niedrige Latenz zu On-Prem-Systemen nötig ist
Kosten schwer planbar werden
Im Lab bleibt die Hauptdatenbank zunächst auf Bare Metal. Eine optionale Cloud-Datenbank kann für Testumgebungen oder weniger kritische Dienste genutzt werden.
14. Hybrid-Anbindung: VPN und Direct Connect
Eine hybride Plattform braucht eine Verbindung zwischen Cloud und Rechenzentrum. Dafür gibt es typischerweise VPN oder dedizierte Verbindungen wie Direct Connect, ExpressRoute oder Interconnect.
VPN ist oft schneller einzurichten und günstiger. Es eignet sich für Testumgebungen, kleinere Datenmengen und erste Integrationen.
Dedizierte Verbindungen sind stabiler, planbarer und leistungsfähiger. Sie eignen sich für produktive Lasten, große Datenmengen oder niedrige Latenzanforderungen.
Eine wichtige Regel lautet:
Vorlage / Textauszug
Die Cloud-Verbindung ist ein produktionskritischer Pfad, wenn produktive Anwendungen darüber miteinander kommunizieren.
Dann braucht sie Monitoring, Redundanz, Runbooks und klare Eskalationswege.
15. DNS und Hybrid Cloud
DNS wird in hybriden Architekturen anspruchsvoller. Interne Systeme müssen Cloud-Ressourcen auflösen können. Cloud-Systeme müssen interne Dienste finden können. Gleichzeitig dürfen interne Namen nicht unkontrolliert öffentlich sichtbar sein.
Ein mögliches Modell:
Vorlage / Textauszug
Öffentlich:
api.alpine.example.com
customer.alpine.example.com
Intern:
orders-db.internal.alpine.example.com
kafka.internal.alpine.example.com
object-storage.cloud.internal.alpine.example.com
Wichtig ist eine klare Trennung zwischen öffentlichen und internen Namen. DNS-Forwarding, Private Hosted Zones oder Private DNS-Zonen müssen sauber dokumentiert werden.
16. Cloud-Kostenkontrolle
Cloud-Kosten entstehen schnell. Nicht nur große Server kosten Geld, sondern auch Datenübertragung, Storage, Snapshots, Logs, NAT Gateways, Load Balancer, Managed Databases und dauerhaft laufende Testumgebungen.
Ein Enterprise-Projekt braucht daher Kostenregeln:
Vorlage / Textauszug
Jede Ressource bekommt Tags.
Jede Umgebung bekommt Budgetgrenzen.
Sandbox-Ressourcen haben Ablaufdaten.
Logs haben Retention-Regeln.
Snapshots werden aufgeräumt.
Nicht genutzte IPs und Volumes werden erkannt.
Teure Ressourcen brauchen Review.
Kostenkontrolle ist kein rein kaufmännisches Thema. Architekturentscheidungen beeinflussen Kosten direkt. Ein NAT Gateway, das große Datenmengen verarbeitet, kann teuer werden. Eine falsch konfigurierte Log-Retention kann hohe Speicherkosten erzeugen. Eine Testdatenbank, die monatelang läuft, obwohl sie niemand nutzt, verschwendet Budget.
17. Beispiel: Tagging-Standard
Vorlage / Textauszug
owner: team-integration
environment: prod
application: file-processing
cost-center: retail-platform
data-classification: internal
lifecycle: managed
review-date: 2026-12-31
Tags helfen bei Kosten, Sicherheit, Betrieb und Verantwortlichkeit. Sie ersetzen keine Dokumentation, aber sie machen Cloud-Ressourcen auswertbar.
18. Cloud Security Baseline
Eine Cloud Security Baseline definiert Mindestregeln. Für das Lab verwenden wir diese Baseline:
Vorlage / Textauszug
Keine öffentlichen Datenbanken.
Keine öffentlichen Buckets mit internen Daten.
MFA für menschliche Administratoren.
Least Privilege für Service-Rollen.
Zentrale Logs für Cloud-Audit-Ereignisse.
Verschlüsselung für Storage.
Security Groups ohne breite Any-Regeln.
Keine langfristigen Access Keys in Repositories.
Secrets über Secret Manager oder Vault.
Regelmäßige Prüfung ungenutzter Ressourcen.
Diese Regeln sind nicht spektakulär, aber sie verhindern viele typische Fehler.
19. Beispiel: Cloud-Runbook für öffentlichen Bucket-Fund
Vorlage / Textauszug
Runbook: Öffentlicher Bucket entdeckt
Symptom
Ein Security Scan meldet, dass ein Storage Bucket öffentlich lesbar oder schreibbar ist.
Sofortmaßnahmen
Public Access sofort blockieren.
Bucket Policy sichern und im Incident-Ticket dokumentieren.
Dieses Runbook verbindet Betrieb, Security und Infrastructure as Code.
20. Cloud und OpenShift
Cloud und OpenShift können auf verschiedene Weise zusammenarbeiten.
Variante 1: OpenShift läuft im eigenen Rechenzentrum, Cloud liefert Zusatzdienste wie Object Storage oder externe APIs.
Variante 2: OpenShift läuft als Managed Service in der Cloud, zum Beispiel als OpenShift Dedicated oder vergleichbare Plattform.
Variante 3: Es gibt OpenShift on-prem und zusätzlich Cloud-native Workloads.
Für das Lab betrachten wir vor allem Variante 1 und Variante 3. Das ist realistisch für Unternehmen, die bereits ein Rechenzentrum betreiben und Cloud schrittweise integrieren möchten.
21. Beispiel: Partner Upload API in Cloud, Verarbeitung hybrid
Ein Partner lädt eine Datei in der Cloud hoch. Die Upload API prüft Authentifizierung, Dateigröße und Metadaten. Danach legt sie die Datei im Object Storage ab. Ein File Processing Worker verarbeitet die Datei. Dieser Worker kann in OpenShift, auf einer VM oder auf Bare Metal laufen.
Der Ablauf:
Skizze / Textauszug
Partner sendet Datei
↓
Cloud Load Balancer
↓
Upload API
↓
Object Storage incoming
↓
Event oder Polling
↓
File Processing Worker
↓
Validierung
↓
Object Storage processed/rejected
↓
Event an Kafka/RabbitMQ
↓
Order oder Reporting
Diese Architektur nutzt Cloud dort, wo sie stark ist: externe Erreichbarkeit und Object Storage. Die Verarbeitung bleibt flexibel.
22. Beispielcode: einfache Upload-Validierung
java
package com.seb4u.demo.spring.integration.upload;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import java.util.Set;
@Servicepublicclass PartnerUploadValidator {
privatestaticfinal long MAX_SIZE_BYTES = 100 * 1024 * 1024;
privatestaticfinal Set<String> ALLOWED_CONTENT_TYPES = Set.of(
class="str">"text/csv",
class="str">"application/json",
class="str">"application/xml"
);
publicvoid validate(MultipartFile file, String partnerId) {
if (partnerId == null || partnerId.isBlank()) {
thrownew IllegalArgumentException(class="str">"partnerId must not be blank");
}
if (file == null || file.isEmpty()) {
thrownew IllegalArgumentException(class="str">"file must not be empty");
}
if (file.getSize() > MAX_SIZE_BYTES) {
thrownew IllegalArgumentException(class="str">"file exceeds maximum upload size");
}
if (!ALLOWED_CONTENT_TYPES.contains(file.getContentType())) {
thrownew IllegalArgumentException(class="str">"unsupported content type: " + file.getContentType());
}
}
}
Dieser Code ist nur ein Einstieg. In einer echten Umgebung kommen Virenscan, Prüfsummen, Partnerberechtigungen, Audit Logging, Rate Limiting und Quarantäne hinzu.
23. Cloud Observability
Cloud-Ressourcen müssen genauso beobachtet werden wie Anwendungen im Rechenzentrum. Man braucht Metriken, Logs, Events und Kosteninformationen.
Wichtige Signale:
Vorlage / Textauszug
Bucket-Zugriffe
Fehlgeschlagene API-Aufrufe
IAM-Änderungen
öffentliche Resource Policies
Datenübertragung
NAT Gateway Traffic
Load Balancer Fehler
Datenbankverbindungen
Backup-Status
Cloud-Audit-Logs sind besonders wichtig. Sie zeigen, wer wann welche Ressource verändert hat. Ohne Audit-Logs kann ein öffentlicher Bucket oder eine gelöschte Datenbank schwer aufgeklärt werden.
24. Typische Cloud-Fehler
Ein häufiger Fehler ist ein öffentlicher Storage Bucket. Er entsteht oft durch Tests, unklare Policies oder manuelle Änderungen.
Ein zweiter Fehler ist zu breites IAM. Service-Rollen bekommen Administratorrechte, weil eine konkrete Policy am Anfang aufwendiger erscheint. Später weiß niemand, welche Rechte wirklich gebraucht werden.
Ein dritter Fehler ist fehlende Kostenkontrolle. Temporäre Ressourcen bleiben dauerhaft aktiv. Logs werden ewig gespeichert. Snapshots werden nicht aufgeräumt.
Ein vierter Fehler ist unklare Netzwerkführung. Cloud-Systeme sprechen direkt mit internen Systemen, ohne dass DNS, Firewall, Routing und Monitoring sauber dokumentiert sind.
Ein fünfter Fehler ist fehlende Datenklassifizierung. Teams speichern Daten in der Cloud, ohne zu wissen, ob diese Daten dort liegen dürfen.
25. Übung: Cloud-Zielbild für Partnerdateien
Entwirf ein Cloud-Zielbild für Partnerdateien.
Beantworte:
Vorlage / Textauszug
Wo laden Partner Dateien hoch?
Welche Komponente prüft die Datei?
Wo liegt die Datei vor der Verarbeitung?
Wo liegen abgelehnte Dateien?
Welche Rolle darf lesen?
Welche Rolle darf schreiben?
Wie wird öffentlicher Zugriff verhindert?
Wie wird ein Fehler im Upload-Prozess erkannt?
Wie wird die Ressource kostenmäßig zugeordnet?
26. Musterlösung zur Übung
Eine mögliche Lösung:
Vorlage / Textauszug
Partner laden Dateien über eine Upload API hoch, die hinter einem Cloud Load Balancer liegt. Die API prüft Partner-ID, Dateigröße, Content-Type und Authentifizierung. Danach schreibt sie die Datei in den Bucket-Pfad incoming/.
Der File Processing Worker liest nur aus incoming/ und schreibt Ergebnisse nach processed/ oder rejected/. Abgelehnte Dateien werden mit Fehlerbericht abgelegt.
Öffentlicher Zugriff auf den Bucket wird durch Public Access Block, Bucket Policy und Security Baseline verhindert. IAM-Rollen sind getrennt: Upload API darf nur schreiben, Worker darf lesen und Ergebnisbereiche schreiben, Reporting darf nur archivierte Daten lesen.
Fehler werden über API-Metriken, Bucket-Events, Worker-Logs und Alerts erkannt. Alle Ressourcen tragen Tags für owner, environment, application, cost-center und data-classification.
27. ADR 002: Cloud gezielt nutzen
Vorlage / Textauszug
ADR 002: Cloud gezielt für Object Storage und externe Integration nutzen
Status
Akzeptiert
Kontext
Das Unternehmen betreibt eine hybride Landschaft. Nicht alle Systeme sollen in die Cloud migriert werden. Gleichzeitig gibt es Anforderungen an externe Partnerintegration, skalierbare Uploads, flexible Testumgebungen und Object Storage.
Entscheidung
Die Cloud wird gezielt für Object Storage, Partner Upload API, temporäre Testumgebungen und externe Integrationen genutzt. Kritische Hauptdatenbanken bleiben zunächst im Rechenzentrum oder auf dedizierter Infrastruktur.
Konsequenzen
Cloud-Ressourcen müssen über Infrastructure as Code erzeugt werden. Alle Ressourcen brauchen Tags, Verschlüsselung, Zugriffsbeschränkungen, Logging und Kostenkontrolle. Hybrid-Verbindungen werden als produktionskritische Infrastruktur betrachtet, wenn produktive Workloads sie nutzen.
28. Merksätze
Vorlage / Textauszug
Cloud ist kein Ersatz für Architektur.
Eine Landing-Zone verhindert Cloud-Wildwuchs.
Public Subnet bedeutet nicht: alles darf öffentlich sein.
Object Storage ist sehr nützlich, aber öffentliche Buckets sind ein schwerer Fehler.
IAM muss Aufgaben abbilden, nicht Bequemlichkeit.
Cloud-Kosten sind Architekturfolgen.
Hybrid-Verbindungen sind produktionskritisch, wenn produktive Workloads davon abhängen.
Cloud-Ressourcen ohne Tags, Logs und IaC sind schwer beherrschbar.
VM- und Bare-Metal-Betrieb
Workload-Zuordnung kompakt
Kompakte Themenübersicht
1. Warum VM und Bare Metal weiterhin wichtig sind
In modernen Architekturgesprächen klingt es manchmal so, als müssten alle Systeme sofort in Container, Kubernetes oder Cloud-Dienste verschoben werden. Das ist in echten Unternehmen selten realistisch. Eine Enterprise-Landschaft besteht fast immer aus mehreren Laufzeitmodellen. Neue Services laufen vielleicht auf OpenShift, aber zentrale Datenbanken, alte Reporting-Systeme, File-Verarbeitung, Backup-Repositories oder Spezialsoftware laufen weiterhin auf virtuellen Maschinen oder physischer Hardware.
Das ist kein Fehler. Es ist eine Realität, die sauber gestaltet werden muss.
Eine virtuelle Maschine ist sinnvoll, wenn ein System ein eigenes Betriebssystem braucht, wenn vorhandene Software nicht containerfähig ist oder wenn ein kontrollierter Übergang von alter zu neuer Architektur geplant wird. Bare Metal ist sinnvoll, wenn Hardwareleistung, Storage-Zugriff, Latenz, spezielle Karten, große Datenmengen oder sehr planbare Performance wichtig sind.
Das Ziel dieses Kapitels ist nicht, Container gegen VMs auszuspielen. Das Ziel ist, Workloads fachlich richtig zuzuordnen und für VM- sowie Bare-Metal-Systeme dieselben Qualitätsprinzipien anzuwenden wie für moderne Plattformdienste: Automatisierung, Sicherheit, Monitoring, Backup, Dokumentation und nachvollziehbare Änderungen.
Merksatz:
Vorlage / Textauszug
VM und Bare Metal sind nicht automatisch Legacy.
Legacy entsteht erst, wenn Systeme undokumentiert, ungepatcht, unüberwacht und manuell betrieben werden.
---
2. Die Rolle von virtuellen Maschinen im Lab
Im Enterprise Platform Lab werden virtuelle Maschinen bewusst eingesetzt. Sie bilden Systeme ab, die in Unternehmen häufig vorhanden sind und nicht sofort modernisiert werden können.
Typische VM-Kandidaten im Lab sind:
Vorlage / Textauszug
Reporting Service mit alten Treibern
Legacy Adapter für alte interne Schnittstellen
Migrationshelfer für Datenübernahmen
interne Admin-Tools
SFTP Gateway
Batch Scheduler
Testsysteme für Übergangsarchitekturen
Eine VM bietet eine stabile Umgebung mit eigenem Betriebssystem. Das kann für alte Software wichtig sein. Gleichzeitig entstehen Pflichten: Patchmanagement, Benutzerverwaltung, SSH-Härtung, Firewall, Logrotation, Monitoring-Agent, Backup und Dokumentation.
Ein häufiger Fehler ist, VMs als Ausnahmebereich zu behandeln. Dann entsteht ein Schattenbetrieb: einige Systeme laufen modern mit GitOps, andere werden per SSH von Hand geändert. Das ist gefährlich, weil niemand zuverlässig rekonstruieren kann, wie ein Server wiederhergestellt werden soll.
Deshalb gilt im Lab:
Vorlage / Textauszug
Auch VM-Systeme werden beschrieben, versioniert und überwacht.
---
3. Die Rolle von Bare Metal im Lab
Bare Metal bezeichnet physische Server ohne Hypervisor-Schicht zwischen Betriebssystem und Hardware. In Enterprise-Umgebungen wird Bare Metal oft für besonders datenintensive oder storage-nahe Systeme verwendet.
Im Lab sind typische Bare-Metal-Kandidaten:
Vorlage / Textauszug
große PostgreSQL-Datenbank
Backup Repository
Storage Gateway
große File Processing Workloads
optionaler MinIO-Cluster
Monitoring- oder Logging-Speicher mit hohem Datenvolumen
Bare Metal kann sehr performant sein, aber es nimmt dem Betrieb auch weniger ab. Eine VM kann leichter verschoben, geklont oder gesichert werden. Ein physischer Server braucht klare Hardwaredokumentation, Ersatzteilstrategie, RAID-/Storage-Konzept, Firmwarepflege und definierte Restore-Prozesse.
Ein Bare-Metal-System ohne Runbook ist riskant. Wenn die Hardware ausfällt, reicht es nicht zu wissen, dass dort „die Datenbank“ läuft. Man muss wissen, welche Daten, welche Version, welche Konfiguration, welche Backup-Quelle und welche Wiederherstellungsreihenfolge relevant sind.
---
4. Workload-Zuordnung: VM, Bare Metal oder OpenShift?
Workload-Zuordnung
Kompakte Lernhilfe
Eine gute Architekturentscheidung entsteht nicht aus Geschmack, sondern aus Anforderungen.
Ein moderner REST-Service mit klarer Konfiguration, Health Checks und horizontaler Skalierung passt gut zu OpenShift. Ein altes Reporting-Tool mit lokalen Fonts, nativen Bibliotheken und speziellen ODBC-Treibern passt zunächst besser auf eine VM. Eine große Datenbank mit sehr hohem I/O-Bedarf kann auf Bare Metal besser aufgehoben sein.
Die Leitfrage lautet:
Vorlage / Textauszug
Welche Laufzeitumgebung reduziert Risiko und Betriebsaufwand für genau diesen Workload?
Nicht:
Vorlage / Textauszug
Welche Plattform ist gerade modern?
Beispielentscheidungen im Lab:
Vorlage / Textauszug
Order Service:
Läuft auf OpenShift, weil er containerisierbar ist, über Health Checks verfügt und regelmäßig deployt wird.
Reporting Service:
Läuft zunächst auf VM, weil alte Treiber und bestehende Reporting-Tools genutzt werden.
PostgreSQL Main Database:
Läuft im ersten Schritt auf Bare Metal, weil I/O, Backup und bestehende Betriebsprozesse kritisch sind.
File Processing Worker:
Kann auf VM oder Bare Metal laufen, wenn sehr große Dateien direkt aus internem Storage verarbeitet werden.
Billing Event Consumer:
Läuft auf OpenShift, weil er gut skalierbar und eventgetrieben ist.
---
5. Standard-Baseline für Linux-Server
Jeder Linux-Server im Lab bekommt eine Baseline. Diese Baseline legt Mindeststandards fest. Sie ist unabhängig davon, ob der Server eine VM oder Bare Metal ist.
Die Baseline umfasst:
Vorlage / Textauszug
eindeutiger Hostname
zentrale Zeitquelle
SSH nur mit Schlüssel
keine direkte Root-Anmeldung
Firewall aktiv
Monitoring-Agent installiert
Logrotation konfiguriert
automatische Sicherheitsupdates nach Policy
definierte Benutzergruppen
dokumentierter Zweck
Backup- oder Reinstallationsstrategie
Der Server soll nicht erst nach einem Audit gehärtet werden. Die Härtung beginnt beim Aufbau.
---
6. Beispiel: Ansible-Baseline für VM und Bare Metal
Dieses Playbook ist kein vollständiges Hardening, aber es zeigt den richtigen Ansatz: Server werden nicht per Hand geklickt, sondern reproduzierbar beschrieben.
---
7. Systemd für interne Services
Nicht jede Anwendung läuft in Kubernetes. Ein interner Worker auf einer VM kann als systemd-Service betrieben werden.
Dieser Service zeigt mehrere wichtige Punkte. Die Anwendung läuft nicht als root. Konfiguration liegt außerhalb des JARs. Schreibrechte sind begrenzt. systemd startet den Dienst bei Fehlern neu. Das ist einfacher als Kubernetes, aber trotzdem professionell.
---
8. Konfiguration eines VM-basierten Workers
Eine VM-Anwendung braucht eine klare Konfigurationsdatei. Secrets gehören nicht in Git. Nicht geheime Konfiguration darf versioniert werden.
Sensitive Werte wie Passwörter, Tokens oder private Schlüssel würden über ein Secret-Verfahren bereitgestellt, zum Beispiel über Vault, eine geschützte Datei mit engen Rechten oder ein Betriebssystem-Secret-Management.
Ein häufiger Fehler ist, VM-Konfiguration nicht zu versionieren. Dann unterscheidet sich Produktion von Test, ohne dass es jemand bemerkt.
---
9. Logging auf VMs
Containerisierte Anwendungen schreiben Logs meist nach stdout. Auf VMs landen Logs oft in Dateien oder im systemd Journal. Beide Varianten sind möglich, aber sie müssen zentral gesammelt werden.
Für das Lab gilt:
Vorlage / Textauszug
Anwendungen schreiben strukturierte JSON-Logs
Logs enthalten Service-Name, Umgebung und Trace-ID
In echten Umgebungen würde man Ziele nicht immer statisch pflegen. Man kann Service Discovery, Inventory oder Konfigurationsmanagement verwenden. Für das Lab ist die statische Variante gut verständlich.
---
12. Patchmanagement
Patchmanagement ist ein zentraler Unterschied zwischen Managed Services und selbst betriebenen Systemen. Bei VMs und Bare Metal trägt das Unternehmen mehr Verantwortung.
Ein Patchprozess braucht:
Vorlage / Textauszug
Klassifizierung der Systeme
Wartungsfenster
Testumgebung
Backup vor kritischen Updates
Rollback-Plan
Verantwortliche Personen
Dokumentation der Änderung
Nachkontrolle
Ein Produktivserver darf nicht spontan aktualisiert werden, nur weil ein Paketmanager Updates anbietet. Gleichzeitig dürfen Sicherheitsupdates nicht monatelang liegen bleiben. Enterprise-Betrieb bedeutet, zwischen Stabilität und Sicherheit kontrolliert abzuwägen.
Beispielregel:
Vorlage / Textauszug
Kritische Security-Patches: innerhalb von 72 Stunden bewerten und nach Freigabe einspielen.
VM-Backups können auf mehreren Ebenen erfolgen: Image-Backup, Dateisicherung, Anwendungssicherung oder Datenbankdump. Nicht jede Ebene ersetzt die andere.
Ein VM-Image-Backup kann helfen, ein System schnell zurückzubringen. Es garantiert aber nicht immer konsistente Anwendungsdaten, besonders bei Datenbanken. Für Datenbanken braucht man transaktionskonsistente Backups oder native Datenbankmechanismen.
Für eine Reporting-VM könnte die Backup-Strategie so aussehen:
Vorlage / Textauszug
VM-Image einmal täglich
Konfiguration zusätzlich in Git
Reports als exportierbare Artefakte sichern
keine primären Geschäftsdaten dauerhaft nur auf der VM speichern
Restore-Test quartalsweise
Für einen File Worker:
Vorlage / Textauszug
Anwendungspaket reproduzierbar aus Build
Konfiguration in Ansible/Git
Eingangs- und Ergebnisdateien auf Object/File Storage
lokale temporäre Daten nicht als führende Datenquelle betrachten
Der wichtigste Punkt: Ein Backup ohne Restore-Test ist nur eine Hoffnung.
---
14. Backup für Bare-Metal-Datenbanken
Bei Datenbanken ist Backup besonders kritisch. Es reicht nicht, den Server zu sichern. Man muss wissen, bis zu welchem Zeitpunkt Daten wiederhergestellt werden können.
Für PostgreSQL kann ein produktionsnahes Konzept enthalten:
Dieses Skript ist bewusst einfach. Für produktive PostgreSQL-Backups wären Werkzeuge wie pgBackRest, Barman oder ein professionelles Backup-System besser geeignet. Das Beispiel zeigt aber, welche Nachweise wichtig sind: Backup-Datei, Zeitstempel und Prüfsumme.
---
15. Restore ist wichtiger als Backup
Viele Teams dokumentieren Backups, aber nicht den Restore. Im Ernstfall ist jedoch der Restore entscheidend.
Ein Restore-Runbook muss beantworten:
Vorlage / Textauszug
Wer darf Restore auslösen?
Welche Datenquelle wird wiederhergestellt?
Welcher Zeitpunkt ist gewünscht?
Welche Systeme müssen gestoppt werden?
Welche Reihenfolge ist einzuhalten?
Wie wird geprüft, ob Restore erfolgreich war?
Wie wird Kommunikation an Fachbereich und Betrieb durchgeführt?
Beispiel für eine Prüffrage:
Vorlage / Textauszug
Kann das Team eine Orders-Datenbank auf eine neue Umgebung wiederherstellen, ohne die alte Umgebung zu zerstören?
Wenn die Antwort nein ist, ist der Backup-Prozess nicht reif genug.
---
16. Security-Härtung für VM und Bare Metal
Security für Server beginnt mit einfachen, aber konsequenten Regeln:
Besonders wichtig ist die Trennung von Anwendung und Administration. Ein Service-User sollte keine Administrationsrechte haben. Ein Admin-User sollte nicht für den regulären Anwendungsprozess verwendet werden.
Beispiel:
Vorlage / Textauszug
fileworker: führt Anwendung aus, keine Shell für normale Admins nötig
appops: Gruppe für Betrieb
root: nur über sudo und nachvollziehbar
---
17. Beispiel: sudo-Regel für eingeschränkten Betrieb
Diese Regel erlaubt dem Betriebsteam, den Service zu prüfen und neu zu starten, aber nicht beliebige Root-Kommandos auszuführen. In echten Umgebungen muss man solche Regeln sorgfältig prüfen, weil manche erlaubten Kommandos indirekt Rechte ausweiten können.
---
18. Migration von VM zu OpenShift
Nicht jedes VM-System bleibt für immer auf einer VM. Manche Systeme werden später modernisiert. Dafür braucht man eine Migrationsstrategie.
Ein sinnvoller Weg:
Vorlage / Textauszug
Ist-Zustand dokumentieren
Konfiguration aus Anwendung entfernen
Logs strukturieren
Health Endpoint ergänzen
externe Abhängigkeiten klären
Anwendung containerisieren
Datenhaltung trennen
Testumgebung in OpenShift aufbauen
Parallelbetrieb testen
Umschaltung planen
Der wichtigste Schritt ist oft nicht das Dockerfile. Der wichtigste Schritt ist, die Anwendung so zu verändern, dass sie in einer dynamischen Umgebung laufen kann.
Typische Hindernisse:
Vorlage / Textauszug
lokale Dateipfade
feste IP-Adressen
Konfiguration im Code
Sessions im lokalen Speicher
fehlende Health Checks
fehlende Metriken
schwer automatisierbarer Build
---
19. Beispiel: Containerisierung eines alten Workers
Ein einfacher erster Dockerfile-Ansatz:
dockerfile
FROM eclipse-temurin:21-jre
RUN useradd --system --uid 10001 appuser
WORKDIR /app
COPY target/file-worker.jar /app/file-worker.jar
USER 10001
EXPOSE 8085
ENTRYPOINT [class="str">"java", class="str">"-jar", class="str">"/app/file-worker.jar"]
Das ist nur ein Start. Für OpenShift müssen zusätzlich Schreibpfade, SecurityContext, ConfigMaps, Secrets, Probes und Ressourcenlimits betrachtet werden. Wenn die Anwendung weiterhin lokale Dateien erwartet, braucht sie ein PersistentVolume oder muss auf Object Storage umgebaut werden.
---
20. Betriebliches Szenario: Reporting-VM fällt aus
Ausgangslage: Die Reporting-VM erzeugt jeden Morgen um 06:00 Uhr Management-Berichte. Um 06:30 Uhr meldet der Fachbereich, dass keine Reports vorhanden sind.
Ein unreifer Betrieb würde per SSH auf die VM gehen und zufällig Logs suchen.
Ein reifer Betrieb arbeitet nach Runbook:
Vorlage / Textauszug
Monitoring prüfen: VM erreichbar?
systemd Service prüfen: Reporting Scheduler aktiv?
Logs des Jobs prüfen
Datenbankverbindung prüfen
Speicherplatz prüfen
letzte erfolgreiche Ausführung prüfen
manuelle Wiederholung nur nach Freigabe starten
Fachbereich informieren
Ursache dokumentieren
dauerhafte Korrektur als Ticket erfassen
Das Ziel ist nicht nur, den Report einmal nachzuliefern. Das Ziel ist, die Ursache zu verstehen und Wiederholung zu verhindern.
---
21. Runbook: Reporting-Job fehlgeschlagen
Vorlage / Textauszug
Runbook: Reporting-Job fehlgeschlagen
Symptom
Der tägliche Management-Report wurde nicht erzeugt oder liegt nicht im Zielverzeichnis.
Wenn Datenbank und Storage erreichbar sind, kann der Job einmalig manuell wiederholt werden.
Nacharbeit
Ticket mit Ursache erstellen
Alert-Regel prüfen
falls Datenproblem: Fachbereich informieren
falls Infrastrukturproblem: zuständiges Team einbinden
---
22. Qualitätskriterien für VM- und Bare-Metal-Systeme
Ein VM- oder Bare-Metal-System gilt im Lab als produktionsnah, wenn folgende Kriterien erfüllt sind:
Vorlage / Textauszug
Zweck dokumentiert
Owner bekannt
Konfiguration versioniert
Installation automatisiert oder dokumentiert
Monitoring aktiv
Logs zentral sichtbar
Backup oder Wiederaufbau beschrieben
Restore getestet
Firewall-Regeln dokumentiert
Zugriff kontrolliert
Patchprozess definiert
Runbook vorhanden
Diese Kriterien verhindern, dass klassische Systeme zu unsichtbaren Risiken werden.
---
23. Typische Fehler bei VM und Bare Metal
Ein häufiger Fehler ist manuelle Konfiguration ohne Dokumentation. Dadurch entsteht ein Server, den niemand reproduzieren kann.
Ein zweiter Fehler ist fehlendes Monitoring. Solange niemand bemerkt, dass ein Dienst ausgefallen ist, ist der Betrieb blind.
Ein dritter Fehler ist falsches Backup-Verständnis. Ein VM-Snapshot ersetzt nicht automatisch ein konsistentes Datenbankbackup.
Ein vierter Fehler ist zu breiter Netzwerkzugriff. Wenn eine VM aus historischen Gründen viele Ports offen hat, wird sie zum Risiko.
Ein fünfter Fehler ist fehlende Migrationsstrategie. Systeme bleiben dann nicht aus fachlichen Gründen auf VMs, sondern weil niemand den ersten Schritt zur Modernisierung definiert.
---
24. Übung: VM-Betriebsmodell entwerfen
Entwirf ein Betriebsmodell für eine Reporting-VM im Lab.
Beantworte:
Vorlage / Textauszug
Welchen Zweck hat die VM?
Welche Datenquellen nutzt sie?
Welche Ports müssen offen sein?
Welche Benutzer dürfen zugreifen?
Welche Logs werden gesammelt?
Welche Metriken sind kritisch?
Wie erfolgt Backup oder Wiederaufbau?
Was steht im Runbook?
Welche Teile könnten später nach OpenShift migriert werden?
---
25. Musterlösung zur Übung
Die Reporting-VM erzeugt tägliche Berichte aus Orders- und Billing-Daten. Sie liest aus PostgreSQL Orders und PostgreSQL Billing, schreibt Ergebnisdateien in Object Storage und wird über einen systemd Scheduler gestartet.
Offen sein müssen ausgehend Verbindungen zu den Datenbanken auf Port 5432 und zum Object Storage auf HTTPS. Eingehend ist nur SSH aus dem Management-Netz erlaubt. Der Betrieb greift über persönliche Konten und sudo-Regeln zu.
Logs werden im systemd Journal und zusätzlich zentral gesammelt. Kritische Metriken sind Job-Erfolg, Job-Dauer, letzter erfolgreicher Lauf, Speicherplatz, CPU, RAM und Datenbankverbindungsfehler.
Die VM selbst kann über Image-Backup gesichert werden. Wichtiger ist aber, dass Anwendungspaket, Konfiguration und Scheduler-Definition reproduzierbar sind. Reports liegen im Object Storage und sind versioniert.
Später kann die Report-Erzeugung in einen Kubernetes CronJob migriert werden, wenn Treiber, Konfiguration, Storage-Zugriff und Laufzeitverhalten containerfähig sind.
---
26. Merksätze
Vorlage / Textauszug
VMs sind weiterhin nützlich, wenn sie professionell betrieben werden.
Bare Metal ist sinnvoll für Workloads mit besonderen Performance- oder Storage-Anforderungen.
Manuelle Server sind ein Risiko, wenn sie nicht dokumentiert und automatisiert werden.
Ein Snapshot ist nicht automatisch ein gutes Backup.
Restore-Tests sind wichtiger als Backup-Versprechen.
Auch klassische Systeme brauchen Monitoring, Security, Runbooks und klare Owner.
Modernisierung beginnt oft damit, einen VM-Service beobachtbar, dokumentiert und reproduzierbar zu machen.
Kubernetes- und OpenShift-Plattform
Request-Pfad im Cluster
Kompakte Themenübersicht
1. Warum Kubernetes/OpenShift im Lab eine zentrale Rolle spielt
Kubernetes ist in diesem Lernprojekt nicht einfach ein weiterer Deployment-Ort. Es ist die standardisierte Plattform für moderne, containerisierte Anwendungen. OpenShift erweitert Kubernetes um Enterprise-Funktionen wie integrierte Routes, Security Context Constraints, Build- und Image-Funktionen, Operatoren, Monitoring-Integration und ein stärkeres Betriebsmodell.
Für das Enterprise Platform Lab bedeutet das: Neue Services werden nicht mehr einzeln auf Server kopiert. Sie werden als Container Images gebaut, versioniert, geprüft und über deklarative Manifeste ausgerollt. Eine Änderung an einer Anwendung besteht nicht nur aus Code, sondern auch aus Deployment-Konfiguration, Ressourcenlimits, Health Checks, Security-Einstellungen, Monitoring und GitOps-Zustand.
Der wichtigste Unterschied zu einer klassischen VM ist:
Vorlage / Textauszug
Auf einer VM verwaltest du meistens einen langlebigen Server.
In Kubernetes verwaltest du gewünschte Zustände.
Ein Pod darf verschwinden. Ein Node darf ausfallen. Ein neues Image darf ausgerollt werden. Die Plattform versucht, den gewünschten Zustand wiederherzustellen. Genau deshalb müssen Anwendungen für diese Welt gebaut werden: stateless wo möglich, externes Storage wo nötig, Health Checks, robuste Konfiguration, kontrollierter Shutdown und gute Beobachtbarkeit.
---
2. Kubernetes-Grundidee
Kubernetes beschreibt Anwendungen nicht als einzelne Prozesse, sondern als Ressourcen. Eine Anwendung wird in Objekte zerlegt: Namespace, Deployment, Pod, Service, ConfigMap, Secret, Route oder Ingress, PersistentVolumeClaim, NetworkPolicy und weitere Bausteine.
Ein Deployment beschreibt, wie viele Instanzen einer Anwendung laufen sollen und welches Container Image verwendet wird. Ein Pod ist die kleinste ausführbare Einheit. Ein Service gibt Pods eine stabile interne Adresse. Eine Route oder ein Ingress macht eine Anwendung erreichbar. ConfigMaps und Secrets liefern Konfiguration. Probes sagen der Plattform, ob die Anwendung bereit oder gesund ist.
Für Entwickler ist wichtig: Kubernetes startet nicht einfach nur einen Container. Kubernetes betreibt einen gewünschten Zustand.
neuer Pod wird auf einem geeigneten Node gestartet
Diese Selbstheilung funktioniert aber nur, wenn die Manifeste sauber beschrieben sind.
---
3. OpenShift-spezifische Sicht
OpenShift ist Kubernetes, aber mit zusätzlichen Enterprise-Bausteinen. Dazu gehören unter anderem:
Vorlage / Textauszug
OpenShift Routes für externen HTTP(S)-Zugriff
Security Context Constraints für Container-Rechte
integrierte OAuth-Anbindung
Operator Lifecycle Manager
integriertes Monitoring
Projekt-/Namespace-Modell
Image Streams und BuildConfig in klassischen Setups
Web Console für Betrieb und Entwicklung
Für das Lab nutzen wir OpenShift als Zielplattform für moderne Anwendungen. Dabei achten wir darauf, keine OpenShift-Funktion blind zu verwenden. Manche Ressourcen sind Kubernetes-Standard, andere sind OpenShift-spezifisch. Das ist wichtig, wenn Anwendungen später auch auf anderen Kubernetes-Distributionen laufen sollen.
Beispiel:
Vorlage / Textauszug
Kubernetes-Standard:
Deployment
Service
ConfigMap
Secret
Ingress
NetworkPolicy
PersistentVolumeClaim
OpenShift-spezifisch:
Route
SecurityContextConstraints
BuildConfig
ImageStream
Im Lab verwenden wir für externe Zugriffe bevorzugt OpenShift Routes, erklären aber den Unterschied zu Ingress.
---
4. Namespace-Strategie
Namespaces nach Umgebung
Kompakte Lernhilfe
Namespaces sind eine der wichtigsten Ordnungsstrukturen im Cluster. Sie trennen Ressourcen, Berechtigungen, Quotas, Netzwerkregeln und Verantwortlichkeiten.
Für das Lab verwenden wir keine einzige große Sammelzone. Stattdessen werden Fachbereiche und Umgebungen getrennt.
Vorlage / Textauszug
customer-dev
customer-test
customer-prod
order-dev
order-test
order-prod
billing-dev
billing-test
billing-prod
integration-dev
integration-test
integration-prod
platform-gitops
platform-monitoring
platform-logging
security-keycloak
messaging-prod
data-services
Diese Struktur verhindert nicht automatisch alle Fehler, aber sie macht Verantwortlichkeiten sichtbar. Ein Team erkennt, welche Ressourcen zu seinem Bereich gehören. Security kann Rechte gezielter vergeben. Betrieb kann Ressourcenverbrauch pro Bereich beobachten.
Ein häufiger Fehler ist, Entwicklung, Test und Produktion in denselben Namespace zu legen. Dadurch verschwimmen Grenzen. Ein Test-Deployment kann versehentlich produktive Secrets verwenden oder produktive Ressourcen blockieren.
---
5. Namespace-Definition mit Labels
Labels sind wichtig, weil viele andere Mechanismen darauf aufbauen. Monitoring, NetworkPolicies, Kostenberichte und GitOps können Labels auswerten.
Diese Labels wirken einfach, sind aber wertvoll. Eine NetworkPolicy kann auf network-zone reagieren. Ein Kostenreport kann nach owner gruppieren. Ein Audit kann zeigen, welche Namespaces produktiv sind.
---
6. Deployment für den Order Service
Ein Deployment beschreibt, wie ein Service ausgeführt wird. Es sollte nicht nur Image und Port enthalten. Für einen produktionsnahen Service gehören Ressourcenlimits, Probes, Labels und Konfigurationsquellen dazu.
Dieses Manifest zeigt mehrere wichtige Entscheidungen. Der Service läuft nicht als privilegierter Container. Er hat klare Ressourcen. Die Health Checks unterscheiden zwischen readiness und liveness. Konfiguration wird nicht fest ins Image geschrieben, sondern über ConfigMap und Secret geliefert.
---
7. Readiness und Liveness richtig verstehen
Readiness und Liveness werden häufig verwechselt.
Readiness bedeutet: Kann dieser Pod gerade Traffic annehmen?
Liveness bedeutet: Ist dieser Pod grundsätzlich noch lebendig, oder muss er neu gestartet werden?
Ein Pod kann lebendig sein, aber nicht ready. Zum Beispiel wenn die Anwendung startet, aber die Datenbankverbindung noch nicht aufgebaut ist. In diesem Fall soll Kubernetes den Pod nicht töten, sondern nur noch keinen Traffic schicken.
Ein häufiger Fehler ist, die Liveness Probe zu streng zu machen. Wenn eine Datenbank kurz langsam ist und die Liveness Probe deshalb fehlschlägt, startet Kubernetes die Anwendung ständig neu. Dadurch wird die Störung schlimmer.
Ein Deployment allein macht eine Anwendung noch nicht stabil erreichbar. Pods haben wechselnde IPs. Ein Kubernetes Service gibt ihnen eine stabile interne Adresse.
Diese Route nutzt TLS am Edge. In manchen Umgebungen ist Re-Encrypt besser, wenn die Verbindung vom Router zum Pod ebenfalls verschlüsselt bleiben soll. Diese Entscheidung hängt von Sicherheitsanforderungen und Zertifikatsmodell ab.
---
9. ConfigMap und Secret
Konfiguration und Secrets müssen getrennt werden. Eine ConfigMap enthält nicht-sensitive Einstellungen. Ein Secret enthält sensible Werte wie Passwörter, Tokens oder Zertifikatsmaterial.
In einer produktionsnahen Umgebung sollte das Secret nicht dauerhaft als Klartext in Git liegen. Besser sind External Secrets, Sealed Secrets, Vault oder ein anderes Secret-Management-Verfahren. Im Lab wird später External Secrets behandelt.
---
10. Resource Requests und Limits
Kubernetes plant Pods anhand von Requests. Limits begrenzen den maximalen Verbrauch. Ohne Requests weiß der Scheduler nicht zuverlässig, wie viel Kapazität ein Pod braucht. Ohne Limits kann ein fehlerhafter Prozess zu viel Speicher oder CPU verbrauchen.
Das bedeutet nicht, dass jeder Service genau diese Werte braucht. Werte müssen beobachtet und angepasst werden. Für Java-Anwendungen ist Speicher besonders wichtig, weil JVM Heap, Metaspace, Threads und native Speicherbereiche berücksichtigt werden müssen.
Ein häufiger Fehler ist, ein Java-Container-Limit auf 512 MiB zu setzen und der JVM gleichzeitig einen zu großen Heap zu erlauben. Dann wird der Pod vom Kernel beendet, oft als OOMKilled.
Besser ist, JVM-Parameter und Container-Limits gemeinsam zu betrachten:
Vorlage / Textauszug
Container Memory Limit: 1024 MiB
Max Heap: etwa 60-70 Prozent davon
Reserve für Metaspace, Threads, Direct Memory und Native Memory
---
11. ServiceAccount und RBAC
Jeder Service sollte mit einem eigenen ServiceAccount laufen. Dadurch kann man Berechtigungen gezielt vergeben.
Der Order Service braucht normalerweise keine Rechte, um Kubernetes-Ressourcen zu lesen oder zu ändern. Deshalb bekommt er keine breiten Cluster-Rollen.
Ein häufiger Fehler ist, Anwendungen mit zu vielen Rechten laufen zu lassen. Zum Beispiel mit Admin-Rechten im Namespace oder sogar Cluster-Rechten. Das ist gefährlich, wenn die Anwendung kompromittiert wird.
RBAC-Regel:
Vorlage / Textauszug
Ein Service bekommt nur die Rechte, die er wirklich benötigt.
Wenn er keine Kubernetes API nutzen muss, bekommt er keine zusätzlichen Kubernetes-Rechte.
---
12. SecurityContext und OpenShift SCC
Container sollten nicht als root laufen. Privilege Escalation sollte deaktiviert werden. Linux Capabilities sollten entfernt werden, wenn sie nicht gebraucht werden.
yaml
securityContext:
allowPrivilegeEscalation: falserunAsNonRoot: truecapabilities:
drop:
- ALL
OpenShift hat zusätzlich Security Context Constraints. Diese bestimmen, welche Sicherheitskontexte Pods verwenden dürfen. OpenShift ist hier oft strenger als ein Standard-Kubernetes-Cluster. Das ist gut, weil unsichere Container schneller auffallen.
Ein typischer Fehler ist ein Container Image, das erwartet, als root zu laufen oder in feste Verzeichnisse schreiben zu dürfen. In OpenShift kann das scheitern.
Besser ist:
Vorlage / Textauszug
Image läuft ohne root
Anwendung schreibt nur in erlaubte Verzeichnisse
temporäre Dateien liegen in /tmp oder gemountetem Volume
keine festen UID-Annahmen im Image
---
13. NetworkPolicy für den Order Service
Eine produktionsnahe Plattform sollte nicht erlauben, dass jeder Pod mit jedem anderen Pod spricht. NetworkPolicies begrenzen Kommunikation.
Diese Policy erlaubt nur Kafka, die externe Datenbank-IP und Keycloak. In echten Umgebungen muss man außerdem DNS-Zugriffe berücksichtigen, da Services Namen auflösen müssen.
---
14. Persistent Volumes und wann man sie vermeidet
Nicht jede Anwendung braucht persistentes Volume. Moderne Backend-Services sollten nach Möglichkeit zustandslos sein. Daten liegen in Datenbanken, Object Storage oder spezialisierten Systemen.
Persistent Volumes sind sinnvoll für:
Vorlage / Textauszug
Datenbanken im Cluster
Broker im Cluster
Stateful Anwendungen
technische Komponenten wie Registry oder Monitoring-Speicher
Für den Order Service ist ein PersistentVolume meistens nicht nötig. Der Service speichert fachliche Daten in PostgreSQL und Events in der Outbox-Tabelle. Lokale Dateien wären riskant, weil Pods verschoben oder neu gestartet werden können.
Ein typischer Fehler ist:
Vorlage / Textauszug
Upload-Datei im Pod-Dateisystem speichern
später erwarten, dass sie noch vorhanden ist
Besser:
Vorlage / Textauszug
Upload-Datei in Object Storage speichern
Metadaten in Datenbank speichern
Verarbeitung über Event oder Job auslösen
---
15. Jobs und CronJobs
Nicht jede Aufgabe ist ein dauerhaft laufender Service. Manche Aufgaben laufen einmalig oder regelmäßig. Dafür gibt es Jobs und CronJobs.
concurrencyPolicy: Forbid verhindert, dass ein neuer Lauf startet, während der vorherige noch läuft. Das ist bei Reporting wichtig, damit keine doppelten Exporte entstehen.
---
16. GitOps mit Argo CD
GitOps bedeutet: Der gewünschte Zustand der Plattform liegt in Git. Argo CD vergleicht diesen Zustand mit dem Cluster und synchronisiert Änderungen.
Der Vorteil ist Nachvollziehbarkeit. Niemand muss per Hand oc apply ausführen, ohne dass Git den Zielzustand kennt. Jede Änderung wird als Pull Request sichtbar, geprüft und versioniert.
In Produktion ist prune manchmal bewusst deaktiviert oder stark kontrolliert, damit Ressourcen nicht versehentlich gelöscht werden. Für Testumgebungen kann eine aggressivere Automatisierung sinnvoll sein.
---
17. Kustomize-Struktur
Für das Lab eignet sich Kustomize, um gemeinsame Basis-Manifeste und umgebungsspezifische Overlays zu trennen.
Der Vorteil: Die Grundstruktur bleibt gleich, aber Produktionswerte unterscheiden sich kontrolliert von Dev-Werten.
---
18. Helm oder Kustomize?
Helm und Kustomize lösen ähnliche, aber nicht identische Probleme.
Helm ist stark, wenn man parametrisierte Pakete veröffentlichen will. Viele Plattformkomponenten werden als Helm Charts bereitgestellt. Kustomize ist stark, wenn man vorhandene YAML-Manifeste über Overlays anpassen will.
Für Anwendungen im Lab nutzen wir bevorzugt Kustomize, weil es einfach nachvollziehbar ist. Für Plattformkomponenten wie Prometheus, Grafana, Loki oder externe Operatoren kann Helm sinnvoll sein.
Die Regel lautet:
Vorlage / Textauszug
Kustomize für transparente App-Manifeste.
Helm für paketierte Plattformkomponenten oder wiederverwendbare Charts.
Wichtig ist, nicht beides chaotisch zu vermischen. Ein Team sollte klar dokumentieren, welche Methode es verwendet.
---
19. Build, Image und Registry
Ein Container Image ist ein Lieferartefakt. Es muss versioniert, gescannt und nachvollziehbar sein.
Ein gutes Image hat:
Vorlage / Textauszug
eindeutigen Tag
Build-Metadaten
möglichst kleine Basis
keine unnötigen Tools
keine Secrets
nicht-root Ausführung
SBOM oder Scan-Ergebnis
Beispiel für ein Spring Boot Dockerfile:
dockerfile
FROM eclipse-temurin:21-jre-alpine
WORKDIR /app
RUN addgroup -S app && adduser -S app -G app
COPY target/order-service.jar /app/order-service.jar
USER app
EXPOSE 8080
ENTRYPOINT [class="str">"java", class="str">"-XX:MaxRAMPercentage=70", class="str">"-jar", class="str">"/app/order-service.jar"]
Dieses Image ist bewusst einfach. In einer erweiterten Version könnte man Distroless Images, Buildpacks oder mehrstufige Builds verwenden.
Diese Pipeline baut nicht nur Code. Sie testet, baut ein Image und scannt es. In einem vollständigen GitOps-Prozess würde danach ein Pull Request im Plattform-Repository den Image-Tag aktualisieren.
---
21. Observability im Cluster
Ein Service muss im Cluster beobachtbar sein. Dazu gehören Logs, Metriken und Traces.
Für Prometheus braucht man oft einen ServiceMonitor:
Wenn dieser ServiceMonitor fehlt, läuft der Service vielleicht korrekt, aber niemand sammelt seine Metriken. Dadurch fehlen Dashboards und Alerts.
Wichtige Metriken für den Order Service:
Vorlage / Textauszug
HTTP Request Rate
HTTP Error Rate
Request Duration
JVM Memory
Database Connection Pool Usage
Outbox Pending Events
Kafka Publish Failures
---
22. Alerts für den Order Service
yaml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: order-service-alerts
namespace: order-prod
spec:
groups:
- name: order-service.rules
rules:
- alert: OrderServiceHighErrorRate
expr: |
sum(rate(http_server_requests_seconds_count{namespace=class="str">"order-prod",status=~class="str">"5.."}[5m]))
/
sum(rate(http_server_requests_seconds_count{namespace=class="str">"order-prod"}[5m])) > 0.05for: 10m
labels:
severity: warning
service: order-service
annotations:
summary: class="str">"Order Service has high HTTP 5xx error rate"
description: class="str">"More than 5 percent of requests failed for10 minutes."
- alert: OrderOutboxBacklogGrowing
expr: order_outbox_pending_events > 1000for: 15m
labels:
severity: critical
service: order-service
annotations:
summary: class="str">"Order outbox backlog is growing"
description: class="str">"Pending outbox events exceed threshold. Billing may not receive new orders."
Diese Alerts verbinden technische Metriken mit fachlichen Risiken. Ein wachsender Outbox-Rückstand bedeutet nicht nur ein technisches Problem. Es bedeutet, dass Folgeprozesse wie Billing verzögert werden.
---
23. Rollout-Strategien
Kubernetes Deployments unterstützen Rolling Updates. Dabei werden alte Pods schrittweise durch neue ersetzt. Das funktioniert gut, wenn die Anwendung rückwärtskompatibel ist.
Ein Problem entsteht, wenn neue Anwendungsversion und Datenbankschema nicht zusammenpassen. Deshalb müssen Datenbankmigrationen vorsichtig geplant werden.
Eine robuste Regel lautet:
Vorlage / Textauszug
Datenbankänderungen müssen mindestens eine Version lang rückwärtskompatibel sein.
Beispiel:
Vorlage / Textauszug
Gut:
neue Spalte hinzufügen
Anwendung schreibt optional in neue Spalte
alte Version funktioniert weiterhin
Riskant:
Spalte löschen
bestehende Anwendung erwartet diese Spalte noch
Für kritische Systeme können Blue/Green oder Canary Deployments sinnvoll sein. Im Lab beginnen wir mit Rolling Updates und erklären später erweiterte Strategien.
---
24. PodDisruptionBudget
Ein PodDisruptionBudget verhindert, dass bei geplanten Wartungen zu viele Pods gleichzeitig verschwinden.
Bei zwei Replicas stellt minAvailable: 1 sicher, dass mindestens ein Pod verfügbar bleiben soll. Das hilft bei Node-Wartungen, ersetzt aber keine echte Hochverfügbarkeitsplanung.
---
25. Typische Fehler in Kubernetes/OpenShift
Ein häufiger Fehler ist, nur ein Deployment zu erstellen und alles andere zu vergessen. Ohne Service, Route, Probes, Limits, SecurityContext und Monitoring ist der Service nicht produktionsnah.
Ein zweiter Fehler ist, Secrets direkt ins Image oder in Git zu schreiben. Das macht Rotation schwierig und erhöht das Risiko bei Leaks.
Ein dritter Fehler ist, alle Workloads mit Admin-Rechten laufen zu lassen. Das widerspricht Least Privilege.
Ein vierter Fehler ist fehlende NetworkPolicy. Dann kann eine kompromittierte Anwendung möglicherweise zu vielen internen Zielen sprechen.
Ein fünfter Fehler ist falsche Liveness Probe. Zu aggressive Liveness Checks erzeugen Neustart-Schleifen und verschlimmern Störungen.
Ein sechster Fehler ist fehlende Ressourcenplanung. Ohne Requests und Limits kann der Cluster Pods schlecht planen und bei Last instabil werden.
Ein siebter Fehler ist blinde Helm-Nutzung. Wenn niemand versteht, welche Ressourcen ein Chart erzeugt, wird Betrieb schwierig.
---
26. Runbook: Pod startet nicht
Vorlage / Textauszug
Runbook: Order Service Pod startet nicht
Symptom
Der Pod im Namespace `order-prod` ist im Status `CrashLoopBackOff`, `ImagePullBackOff`, `Pending` oder `CreateContainerConfigError`.
Erste Prüfung
oc get pods -n order-prod -l app.kubernetes.io/name=order-service
oc describe pod -n order-prod -l app.kubernetes.io/name=order-service
Anwendung beendet sich wegen fehlerhafter Konfiguration
SecurityContext passt nicht zu OpenShift SCC
ResourceQuota verhindert Scheduling
Node-Kapazität reicht nicht
Readiness schlägt fehl wegen Datenbank oder Broker
Prüfung ImagePullBackOff
oc get events -n order-prod --sort-by=.metadata.creationTimestamp
oc get secret -n order-prod
Vorlage / Textauszug
Prüfung fehlende Konfiguration
oc get configmap order-service-config -n order-prod -o yaml
oc get secret order-service-secret -n order-prod -o yaml
Vorlage / Textauszug
Eskalation
Registry-Problem: Plattformteam
fehlende App-Konfiguration: Team Order
Cluster-Kapazität: Plattformbetrieb
SecurityContext/SCC: Security/Plattformteam
Dieses Runbook ist ein Beispiel dafür, wie Kubernetes-Betrieb konkret beschrieben wird. Es verbindet Status, Events, Logs, Konfiguration und Verantwortlichkeiten.
---
27. Übung: Order Service produktionsnah machen
Erstelle eine produktionsnahe Ressourcenliste für den Order Service.
Sie soll enthalten:
Vorlage / Textauszug
Namespace
ServiceAccount
Deployment
Service
Route
ConfigMap
Secret-Konzept
NetworkPolicy
ServiceMonitor
PrometheusRule
PodDisruptionBudget
Argo CD Application
Beschreibe für jede Ressource, warum sie gebraucht wird.
---
28. Musterlösung zur Übung
Eine mögliche Antwort:
Vorlage / Textauszug
Der Namespace `order-prod` trennt die produktive Order-Domäne von anderen Umgebungen.
Der ServiceAccount `order-service` verhindert, dass der Pod mit Default-Rechten läuft.
Das Deployment beschreibt Image, Replicas, Probes, Ressourcen und SecurityContext.
Der Service gibt den Pods eine stabile interne Adresse.
Die Route macht die API über den OpenShift Router erreichbar.
Die ConfigMap enthält nicht-sensitive Einstellungen wie Profil, Batch-Größe und Broker-Adresse.
Secrets werden nicht direkt im Git gespeichert, sondern später über External Secrets aus Vault oder einem Cloud Secret Manager synchronisiert.
Die NetworkPolicy erlaubt nur notwendige Ziele: PostgreSQL, Kafka, Keycloak und DNS.
Der ServiceMonitor sorgt dafür, dass Prometheus Metriken sammelt.
Die PrometheusRule definiert fachlich relevante Alerts, zum Beispiel hohe Fehlerrate und wachsenden Outbox-Rückstand.
Das PodDisruptionBudget schützt vor zu vielen gleichzeitigen Pod-Unterbrechungen.
Die Argo CD Application sorgt dafür, dass der gewünschte Zustand aus Git in den Cluster synchronisiert wird.
---
29. Merksätze
Vorlage / Textauszug
Kubernetes betreibt gewünschten Zustand, keine einzelnen Server.
OpenShift ergänzt Kubernetes um wichtige Enterprise-Funktionen.
Ein Deployment allein ist keine produktionsnahe Anwendung.
Readiness und Liveness dürfen nicht verwechselt werden.
Secrets gehören nicht ins Image und nicht ungeschützt ins Git.
NetworkPolicies sind ein konkreter Schritt zu Zero Trust.
GitOps macht Cluster-Zustand nachvollziehbar.
Monitoring ist Teil des Deployments, nicht ein späterer Zusatz.
Teil C: Identity, Security, Governance und Plattformregeln
Teil C: Identity, Security, Governance und Plattformregeln
Konsolidiert aus Rohmaterial: Teil 6.
Identity, Security und Governance
OIDC- und Rollenfluss
Kompakte Themenübersicht
1. Warum Identity und Security nicht nachträglich angeklebt werden dürfen
In einer modernen Enterprise-Plattform ist Security kein späteres Zusatzkapitel. Sie bestimmt, wie Benutzer auf Anwendungen zugreifen, wie Services miteinander sprechen, wie Secrets geschützt werden, wie Änderungen genehmigt werden und wie ein Audit später nachvollziehen kann, was passiert ist.
Wenn Security erst am Ende eingebaut wird, entstehen typische Probleme:
Vorlage / Textauszug
Der Service funktioniert, aber niemand weiß, welche Rollen erlaubt sind.
Das Frontend ruft APIs direkt auf, aber Token werden unsauber gespeichert.
Ein interner Admin-Endpunkt ist versehentlich öffentlich erreichbar.
Secrets liegen in Klartext in Git.
Ein ServiceAccount hat Cluster-Admin-Rechte, obwohl er nur eine ConfigMap lesen müsste.
Logs enthalten sensible Daten.
Audit-Nachweise fehlen, obwohl die Anwendung produktiv läuft.
Identity und Security müssen deshalb von Anfang an mitgedacht werden. In diesem Lab bedeutet das: Jede Anwendung bekommt eine klare Authentifizierungsstrategie, ein Rollenmodell, technische Zugriffskontrollen, Secret-Management, Audit-Logging und dokumentierte Governance-Regeln.
Der wichtigste Grundsatz lautet:
Vorlage / Textauszug
Security ist nicht nur ein Firewall-Thema.
Security entsteht aus Identität, Rollen, Netzwerken, Secrets, Code, Deployment, Betrieb und Nachweisbarkeit.
---
2. Identity als zentrales Plattformthema
Identity beantwortet die Frage: Wer oder was greift auf ein System zu?
Dabei gibt es zwei Arten von Identitäten:
Vorlage / Textauszug
Menschliche Identitäten:
Kunden
interne Mitarbeiter
Administratoren
Entwickler
externe Partner
Technische Identitäten:
ServiceAccounts
CI/CD Runner
GitOps Controller
Batchjobs
API Clients
Monitoring-Komponenten
Ein häufiger Fehler ist, nur menschliche Benutzer zu betrachten. In einer Enterprise-Plattform sind technische Identitäten mindestens genauso wichtig. Ein Billing Service, der Events konsumiert, braucht eine technische Identität. Ein Argo CD Controller, der Deployments ausführt, braucht Rechte. Ein CI Runner, der Container Images baut, braucht Zugriff auf Registry und Quellcode.
Das Ziel ist nicht, allen Identitäten möglichst viele Rechte zu geben. Das Ziel ist, jeder Identität genau die Rechte zu geben, die sie für ihre Aufgabe braucht.
Vorlage / Textauszug
Least Privilege:
Eine Identität bekommt nur die Rechte, die sie wirklich benötigt.
---
3. Keycloak im Zielbild
Im Lab verwenden wir Keycloak als Identity Provider. Keycloak übernimmt Login, Token-Ausstellung, OIDC-Flows, Rollen und die Anbindung an ein bestehendes LDAP oder Active Directory.
Die Zielarchitektur sieht so aus:
mermaid
flowchart LR
User[Kunde oder Mitarbeiter] --> Portal[Customer Portal / Admin Portal]
Portal --> Keycloak[Keycloak]
Keycloak --> LDAP[LDAP / Active Directory]
Portal --> API[Backend API]
API --> TokenCheck[Token Validierung]
TokenCheck --> Roles[Rollen und Claims]
Keycloak ist dabei nicht nur ein Login-Bildschirm. Keycloak ist ein zentrales Sicherheitssystem. Es entscheidet, welche Clients existieren, welche Redirect-URIs erlaubt sind, welche Rollen vergeben werden und welche Token-Informationen an Anwendungen weitergegeben werden.
Für das Lab gibt es mehrere Clients:
Vorlage / Textauszug
customer-portal
admin-portal
order-service
billing-service
reporting-service
integration-api
Das Customer Portal verwendet einen Browser-basierten OIDC-Flow. Das Admin Portal benötigt strengere Rollen. Service-zu-Service-Kommunikation kann über Client Credentials oder interne Plattformmechanismen abgesichert werden.
---
4. Unterschied zwischen Authentifizierung und Autorisierung
Authentifizierung beantwortet:
Vorlage / Textauszug
Wer bist du?
Autorisierung beantwortet:
Vorlage / Textauszug
Was darfst du tun?
Ein Benutzer kann korrekt angemeldet sein und trotzdem nicht berechtigt sein, eine bestimmte Aktion auszuführen.
Beispiel:
Vorlage / Textauszug
Mitarbeiter Max ist angemeldet.
Max darf Bestellungen lesen.
Max darf keine Rechnung stornieren.
Max darf keine Benutzerrollen ändern.
Im Code muss dieser Unterschied sichtbar sein. Ein API-Endpunkt darf nicht nur prüfen, ob ein Token vorhanden ist. Er muss prüfen, ob die passende Rolle oder Berechtigung vorhanden ist.
---
5. Rollenmodell für das Lab
Für das Lab definieren wir fachliche Rollen:
Vorlage / Textauszug
CUSTOMER
SUPPORT_AGENT
ORDER_MANAGER
BILLING_SPECIALIST
REPORTING_VIEWER
SECURITY_AUDITOR
PLATFORM_OPERATOR
DEPLOYMENT_MANAGER
Diese Rollen dürfen nicht zufällig wachsen. Jede Rolle braucht eine Bedeutung.
Beispiele:
Vorlage / Textauszug
CUSTOMER:
Darf eigene Bestellungen sehen und neue Bestellungen anlegen.
SUPPORT_AGENT:
Darf Kundenbestellungen lesen, aber keine Rechnungen stornieren.
ORDER_MANAGER:
Darf Bestellungen prüfen, Status ändern und Eskalationen auslösen.
BILLING_SPECIALIST:
Darf Rechnungen prüfen, Zahlungsstatus korrigieren und Rechnungsläufe starten.
SECURITY_AUDITOR:
Darf Audit-Informationen lesen, aber keine fachlichen Daten ändern.
PLATFORM_OPERATOR:
Darf Betriebsinformationen sehen und Deployments beobachten.
DEPLOYMENT_MANAGER:
Darf Releases in definierte Umgebungen freigeben.
Wichtig ist: Rollen sind fachliche Begriffe. Kubernetes RBAC ist ein technischer Mechanismus. Beides darf nicht verwechselt werden.
---
6. Keycloak Realm-Konzept
Ein Realm in Keycloak ist ein abgegrenzter Sicherheitsbereich. Für das Lab verwenden wir einen Realm:
Vorlage / Textauszug
alpine-enterprise
Darin liegen Clients, Rollen, Gruppen und Benutzerzuordnungen.
In produktionsnahen Umgebungen muss man entscheiden, ob Entwicklung, Test und Produktion getrennte Realms oder getrennte Keycloak-Instanzen verwenden. Für ein Lab reicht oft ein Realm mit klaren Umgebungsclients. Für echte Produktion ist stärkere Trennung sinnvoll.
---
7. Beispiel: Keycloak Client-Konfiguration als JSON
Diese Konfiguration zeigt mehrere wichtige Punkte. Das Admin Portal ist ein Browser-Client. Es nutzt den Standard Flow und PKCE. Direct Access Grants sind deaktiviert, weil Passwörter nicht direkt an die Anwendung gegeben werden sollen. Redirect-URIs sind explizit eingeschränkt.
Ein häufiger Fehler wäre:
Vorlage / Textauszug
redirectUris: [class="str">"*"]
Das ist bequem, aber gefährlich. Es öffnet die Tür für Redirect-Missbrauch.
---
8. OIDC-Token und Claims
OIDC-Tokenfluss
Kompakte Lernhilfe
Ein OIDC-Token enthält Claims. Claims sind Aussagen über Benutzer oder technische Clients.
Eine Anwendung darf Claims nicht blind vertrauen, wenn Token-Signatur, Issuer und Audience nicht geprüft wurden. Ein Token ist nur gültig, wenn es von der richtigen Quelle kommt, korrekt signiert ist, nicht abgelaufen ist und für den erwarteten Client oder Service bestimmt ist.
---
9. Spring Security im Order Service
Der Order Service soll Token validieren und Rollen auswerten.
Dieser Code ist klein, aber wichtig. Ohne solche Übersetzung sieht Spring die Keycloak-Rollen oft nicht in der erwarteten Form.
Ein typischer Fehler ist, Rollen im Token zu haben, aber im Code hasRole("ORDER_MANAGER") zu verwenden, ohne die Rollen vorher als ROLE_ORDER_MANAGER bereitzustellen.
---
11. Method Security im Use Case
Security sollte nicht nur im Controller stehen. Kritische Aktionen sollten auch an der Anwendungsschicht abgesichert werden.
Diese YAML-Datei hat nichts mit der fachlichen Rolle ORDER_MANAGER zu tun. Sie beschreibt, was der Pod im Cluster darf. Eine fachliche Rolle beschreibt, was ein Benutzer in der Anwendung darf.
Beide Ebenen sind nötig.
---
13. ServiceAccount-Fehler, die man vermeiden muss
Ein sehr gefährlicher Fehler ist, Anwendungen mit zu mächtigen ServiceAccounts laufen zu lassen.
Diese Einstellungen reduzieren Angriffsmöglichkeiten. Nicht jede Anwendung funktioniert sofort mit read-only Root Filesystem. Dann muss man bewusst temporäre Verzeichnisse konfigurieren, statt die Sicherheitsregel einfach zu entfernen.
---
18. OpenShift SCC
OpenShift verwendet Security Context Constraints. SCCs steuern, welche Sicherheitskontexte Pods verwenden dürfen.
Ein häufiger Anfängerfehler ist, bei Problemen sofort eine privilegierte SCC zu vergeben.
Das löst kurzfristig Startprobleme, öffnet aber ein großes Sicherheitsloch.
Besser ist, die Ursache zu verstehen:
Vorlage / Textauszug
Braucht der Container wirklich root?
Schreibt er in verbotene Pfade?
Braucht er Linux Capabilities?
Sind Dateirechte im Image falsch?
Muss ein EmptyDir für temporäre Dateien definiert werden?
Security-Härtung bedeutet oft, das Image und die Anwendung sauberer zu bauen, nicht die Plattformregeln abzuschalten.
---
19. Network Security und Zero Trust
Zero Trust bedeutet nicht, dass man niemandem vertraut und alles blockiert. Es bedeutet: Vertrauen wird nicht aus Netzwerkposition abgeleitet.
Früher war ein typisches Denken:
Vorlage / Textauszug
Wenn ein System im internen Netz steht, ist es vertrauenswürdig.
Modernes Denken:
Vorlage / Textauszug
Auch interne Systeme müssen authentifiziert, autorisiert, beobachtet und begrenzt werden.
Für das Lab heißt das:
Vorlage / Textauszug
Services kommunizieren nur über definierte Pfade.
NetworkPolicies begrenzen Pod-Kommunikation.
APIs prüfen Tokens.
Secrets werden zentral verwaltet.
Admin-Zugriffe laufen über kontrollierte Wege.
Audit Logs dokumentieren kritische Aktionen.
---
20. Audit Logging
Audit Logging beantwortet nicht nur die Frage, was technisch passiert ist. Es beantwortet fachliche Nachweisfragen.
Beispiele:
Vorlage / Textauszug
Wer hat eine Bestellung freigegeben?
Wer hat eine Rechnung storniert?
Wer hat eine Rolle geändert?
Welcher Service hat einen Export gestartet?
Wann wurde ein Secret rotiert?
Welcher Release wurde produktiv geschaltet?
Ein Audit-Log muss vorsichtig gestaltet werden. Es darf genug Informationen enthalten, um Vorgänge nachzuvollziehen, aber keine unnötigen sensiblen Daten speichern.
Der Code zeigt bewusst mehrere Abhängigkeiten: aktueller Benutzer, Trace-ID und Zeit. Dadurch können Audit-Einträge später mit Logs und Traces verbunden werden.
---
22. Governance: Regeln für kontrollierte Veränderung
Governance bedeutet nicht Bürokratie um der Bürokratie willen. Governance bedeutet, dass wichtige Änderungen nachvollziehbar, überprüfbar und verantwortet sind.
Im Lab betrifft Governance vor allem:
Vorlage / Textauszug
Architekturentscheidungen
Security-Regeln
Deployment-Freigaben
Produktionszugriffe
Secret Rotation
Netzwerkfreigaben
Rollenänderungen
Backup- und Restore-Tests
Eine gute Governance-Regel ist konkret. Eine schlechte Regel ist allgemein.
Schlecht:
Vorlage / Textauszug
Security muss beachtet werden.
Besser:
Vorlage / Textauszug
Jede produktionsnahe Anwendung muss eine NetworkPolicy, Resource Limits, Readiness Probe, dokumentierte Rollen, ein Runbook und einen ServiceMonitor besitzen.
---
23. Pull Request Regeln
Jede Änderung an produktionsnahen Artefakten läuft über Pull Request.
Ein PR muss beantworten:
Vorlage / Textauszug
Was wird geändert?
Warum wird es geändert?
Welche Umgebung ist betroffen?
Welche Risiken gibt es?
Wie wird getestet?
Wie wird zurückgerollt?
Gibt es Security-Auswirkungen?
Gibt es Betriebs-Auswirkungen?
Beispiel-Template:
Vorlage / Textauszug
Pull Request
Änderung
Beschreibe die Änderung kurz.
Grund
Warum ist die Änderung notwendig?
Betroffene Systeme
[ ] Anwendung
[ ] Infrastruktur
[ ] Security
[ ] Datenbank
[ ] Monitoring
Tests
[ ] Unit Tests
[ ] Integration Tests
[ ] Deployment in Testumgebung
[ ] Smoke Test
Rollback
Beschreibe, wie die Änderung zurückgenommen wird.
Security Review
[ ] keine neuen Secrets in Git
[ ] Rollen geprüft
[ ] Netzwerkzugriffe geprüft
[ ] Logs enthalten keine sensiblen Daten
Dieses Template verhindert nicht alle Fehler, aber es zwingt zu besseren Fragen.
---
24. Policy as Code
Policy as Code bedeutet, dass Regeln maschinenlesbar beschrieben und automatisch geprüft werden.
Beispiele für Regeln:
Vorlage / Textauszug
Kein Container darf privileged laufen.
Jeder produktive Pod braucht Resource Limits.
Images dürfen nicht latest verwenden.
Secrets dürfen nicht als Klartext im Repository liegen.
Jede Route muss TLS verwenden.
Jede Anwendung braucht Labels für Owner und Environment.
Solche Regeln können mit Tools wie Kyverno, OPA Gatekeeper, Conftest oder CI-Skripten geprüft werden.
Diese Pipeline bricht bei kritischen Funden ab. In echten Unternehmen müssen Ausnahmen geregelt werden. Eine Ausnahme darf aber nicht einfach mündlich entstehen. Sie braucht Begründung, Ablaufdatum und Verantwortlichen.
Testdaten anonymisieren oder synthetisch erzeugen.
Lösch- und Aufbewahrungsfristen definieren.
Ein typischer Fehler ist, komplette Request- oder Response-Bodies zu loggen. Das hilft beim Debugging, kann aber personenbezogene oder vertrauliche Daten offenlegen.
Dieser Log hilft im Betrieb, ohne unnötige Daten offenzulegen.
---
30. Admin Portal als Security-Beispiel
Das Admin Portal ist besonders kritisch, weil interne Mitarbeiter dort Daten sehen oder Aktionen auslösen können.
Risiken:
Vorlage / Textauszug
zu breite Rollen
fehlendes Audit Logging
direkter Zugriff auf interne APIs
fehlende Session-Kontrolle
CSRF-Fehler
unsichere Redirects
zu viele Daten in Listenansichten
Gute Praxis:
Vorlage / Textauszug
starke OIDC-Konfiguration
rollenbasierte UI und API-Prüfung
Audit für kritische Aktionen
kurze Session-Laufzeiten für sensible Funktionen
keine Secrets im Frontend
Backend prüft jede Berechtigung erneut
Wichtig: Die UI darf Buttons ausblenden, aber die API muss trotzdem Berechtigungen prüfen. Frontend-Security allein ist keine Security.
---
31. Incident Response im Security-Kontext
Ein Security Incident ist ein Ereignis, das Vertraulichkeit, Integrität oder Verfügbarkeit gefährdet.
Beispiele:
Vorlage / Textauszug
Token-Leak
kompromittierter ServiceAccount
verdächtige Admin-Aktion
unerwartete Netzwerkverbindung
kritische CVE im produktiven Image
öffentlich erreichbarer interner Endpunkt
Ein Incident-Prozess braucht Phasen:
Vorlage / Textauszug
Erkennen
Bewerten
Eindämmen
Untersuchen
Beheben
Wiederherstellen
Nachbereiten
Security ist erst ernsthaft, wenn auch der Umgang mit Fehlern beschrieben ist.
---
32. Runbook: Verdacht auf Secret Leak
Vorlage / Textauszug
Runbook: Verdacht auf Secret Leak
Symptom
Ein Secret wurde versehentlich in Logs, Git, Ticket, Chat oder ein Artefakt geschrieben.
Sofortmaßnahmen
Secret als kompromittiert betrachten.
Keine Diskussion, ob es class="str">"wirklich schlimm" ist.
Zugriff auf das betroffene Artefakt einschränken.
Security-Team informieren.
Neues Secret erzeugen.
Betroffene Anwendungen kontrolliert umstellen.
Altes Secret deaktivieren.
Logs und Zugriffe prüfen.
Prüfung
Welche Systeme haben das Secret genutzt?
Seit wann war es sichtbar?
Wer konnte es sehen?
Wurde es verwendet?
Gibt es verdächtige Zugriffe?
Nachbereitung
Ursache dokumentieren
Pipeline-Regel ergänzen
Secret-Scanner aktivieren
Team informieren
ADR oder Runbook aktualisieren
Dieses Runbook ist bewusst klar. Bei Secret Leaks darf man nicht zuerst lange diskutieren. Man rotiert.
---
33. Übung: Rollen- und Rechtekonzept erstellen
Erstelle ein Rollen- und Rechtekonzept für das Admin Portal.
Es soll enthalten:
Vorlage / Textauszug
mindestens fünf Rollen
mindestens zehn Aktionen
klare Zuordnung, wer was darf
Audit-Pflicht für kritische Aktionen
technische Umsetzungsidee mit Keycloak und Spring Security
Denke dabei an:
Vorlage / Textauszug
Bestellungen lesen
Bestellungen freigeben
Bestellungen stornieren
Rechnungen lesen
Zahlungsstatus ändern
Benutzerrollen sehen
Benutzerrollen ändern
Reports exportieren
Systemstatus sehen
Konfiguration ändern
---
34. Musterlösung zur Übung
Eine mögliche Lösung:
Vorlage / Textauszug
SUPPORT_AGENT:
Bestellungen lesen
Kundenstatus sehen
keine Stornierung
keine Zahlungsänderung
ORDER_MANAGER:
Bestellungen lesen
Bestellungen freigeben
Bestellungen stornieren
Audit für Freigabe und Storno
BILLING_SPECIALIST:
Rechnungen lesen
Zahlungsstatus ändern
Rechnungslauf starten
Audit für Zahlungsänderung
REPORTING_VIEWER:
Reports lesen
Exporte anfordern
keine fachlichen Änderungen
SECURITY_AUDITOR:
Audit Logs lesen
Rollenzuordnung sehen
keine Änderungen durchführen
PLATFORM_OPERATOR:
Systemstatus sehen
Health und Metriken sehen
keine fachlichen Daten ändern
Technisch werden diese Rollen in Keycloak gepflegt. Das Admin Portal zeigt UI-Funktionen rollenabhängig an. Die Backend-APIs prüfen Rollen mit Spring Security. Kritische Aktionen schreiben Audit Events.
---
35. Merksätze
Vorlage / Textauszug
Authentifizierung sagt, wer du bist.
Autorisierung sagt, was du darfst.
Fachrollen und Kubernetes RBAC sind unterschiedliche Ebenen.
Secrets gehören nicht in Klartext nach Git.
Ein ServiceAccount sollte fast nie Cluster-Admin sein.
Audit Logging ist ein Nachweis, kein Debug-Dump.
Zero Trust bedeutet: interne Systeme werden nicht automatisch vertraut.
Governance ist gut, wenn sie konkrete Regeln überprüfbar macht.
Security muss im Code, im Manifest, in der Pipeline und im Betrieb sichtbar sein.
Teil D: Moderne Anwendungen, Datenflüsse, Messaging und Integration
Teil D: Moderne Anwendungen, Datenflüsse, Messaging und Integration
Konsolidiert aus Rohmaterial: Teil 7, Teil 8.
Moderne Anwendungen
Anwendungslandkarte kompakt
Kompakte Themenübersicht
1. Warum moderne Anwendungen anders geplant werden
Eine moderne Enterprise-Anwendung ist nicht nur eine Anwendung mit neuem Framework. Sie ist ein Baustein in einer Plattform. Sie muss fachliche Verantwortung klar schneiden, sicher deploybar sein, mit anderen Systemen über stabile Schnittstellen sprechen, beobachtbar sein und im Fehlerfall kontrolliert reagieren. Genau hier unterscheiden sich produktionsnahe Systeme von kleinen Demo-Projekten.
Im Enterprise Platform Lab betrachten wir moderne Anwendungen deshalb nicht isoliert. Ein Order Service ist nicht nur ein REST Controller mit Datenbankzugriff. Er hat Authentifizierung, fachliche Regeln, Transaktionen, Outbox Events, Metriken, Logs, Datenbankmigrationen, Kubernetes-Manifeste, CI/CD, Runbooks und Betriebsgrenzen. Ein Customer Portal ist nicht nur ein React-Frontend. Es braucht OIDC, Token Handling, Fehlerzustände, API-Verträge, Routing, Build-Prozess und sichere Konfiguration.
Die wichtigste Regel lautet:
Vorlage / Textauszug
Eine moderne Anwendung ist erst dann vollständig, wenn Code, Schnittstelle, Deployment, Security, Observability und Betrieb zusammen beschrieben sind.
In diesem Teil bauen wir das Anwendungsbild des Labs. Die Anwendungen werden nicht als künstliche Beispiele nebeneinander gestellt, sondern als zusammenhängendes System: Customer Portal, Admin Portal, Order Service, Billing Service, Reporting Service, File Processing Service und API Gateway.
---
2. Die Anwendungslandkarte
Die moderne Anwendungslandschaft des Labs besteht aus mehreren Services mit klarer Verantwortung.
Vorlage / Textauszug
Customer Portal
Kundenoberfläche
Login über Keycloak
Anzeige von Bestellungen und Rechnungen
Aufruf von Backend-APIs
Admin Portal
interne Oberfläche für Mitarbeiter
stärkere Rollenprüfung
manuelle Korrekturen
Auditpflichtige Aktionen
Order Service
Bestellungen anlegen und verwalten
fachliche Validierung
PostgreSQL für Bestelldaten
Outbox Events für nachgelagerte Prozesse
Billing Service
Rechnungsprozesse
Konsum von Order Events
eigene Datenbank für Abrechnung
idempotente Verarbeitung
Reporting Service
Auswertungen und Exporte
liest aus freigegebenen Datenquellen
läuft teilweise als CronJob, teilweise auf VM
File Processing Service
Verarbeitung von Partnerdateien
Validierung, Fehlerablage und Events
kann auf VM, Bare Metal oder OpenShift laufen
API Gateway
zentraler Eingangspunkt
Routing zu Backend-Services
TLS, Rate Limits und technische Schutzregeln
Diese Landkarte macht sichtbar, dass jede Anwendung einen eigenen Grund hat. Es gibt keine generischen Platzhalterdienste. Jeder Service erfüllt eine Aufgabe im Gesamtprozess.
---
3. Architekturprinzipien für Anwendungen
Für alle modernen Anwendungen gelten gemeinsame Architekturprinzipien.
Erstens: Jeder Service besitzt eine klare fachliche Verantwortung. Der Order Service erstellt keine Rechnungen. Der Billing Service verändert keine Bestellung. Das Customer Portal enthält keine Geschäftslogik, die eigentlich in einen Backend-Service gehört.
Zweitens: Jeder Service besitzt seine eigenen Betriebsartefakte. Dazu gehören README, Konfigurationsbeschreibung, Health Checks, Metriken, Logs und Runbook. Ein Service ohne Betriebsbeschreibung wird im Lab nicht als fertig betrachtet.
Drittens: Jeder Service kommuniziert über definierte Schnittstellen. REST APIs werden mit OpenAPI dokumentiert. Events werden mit klaren Eventnamen und Payload-Strukturen beschrieben. Datenbanktabellen anderer Services werden nicht direkt manipuliert.
Viertens: Jeder Service ist sicher konfigurierbar. Secrets liegen nicht im Code. Rollen werden nicht hart im Frontend entschieden. Sicherheitsentscheidungen müssen serverseitig überprüfbar sein.
Fünftens: Jeder Service ist ersetzbar und deploybar. Ein Deployment muss über Pipeline und GitOps reproduzierbar sein. Manuelle Änderungen in Produktion sind kein Zielzustand.
---
4. Customer Portal: Aufgabe und Grenzen
Das Customer Portal ist die Oberfläche für Kunden. Es soll einfach wirken, ist aber sicherheitstechnisch wichtig. Kunden sehen Bestellungen, Rechnungen, Profilinformationen und Statusmeldungen. Sie können neue Bestellungen auslösen oder bestehende Vorgänge einsehen.
Das Portal darf keine geheimen Zugangsdaten enthalten. Es darf keine Datenbank direkt erreichen. Es darf keine kritischen Entscheidungen allein treffen. Wenn das Frontend einen Button versteckt, ist das keine Sicherheit. Die Backend-API muss trotzdem prüfen, ob der Benutzer die Aktion ausführen darf.
Die typische Laufzeit ist OpenShift oder Cloud Hosting. Das Portal wird als statisches oder serverseitig ausgeliefertes Frontend gebaut. Der Build erzeugt ein Container Image oder statische Assets, die über einen Webserver ausgeliefert werden.
Ein typischer Ablauf:
Skizze / Textauszug
Kunde öffnet customer.alpine.example.com
↓
Portal leitet zu Keycloak weiter
↓
Kunde meldet sich an
↓
Portal erhält OIDC Token
↓
Portal ruft API Gateway auf
↓
Order Service liefert Bestellungen des Kunden
Wichtig ist: Das Portal muss Token sauber behandeln. Es darf Access Tokens nicht unnötig lange speichern. Es muss Fehler wie abgelaufene Sitzung, fehlende Berechtigung und API-Ausfall sichtbar behandeln.
---
5. Beispiel: Frontend API Client
Der API Client trennt technische Kommunikation von UI-Komponenten. Dadurch wird die Oberfläche einfacher testbar.
Dieser Code zeigt zwei wichtige Punkte. Erstens wird das Token nur für den API-Aufruf verwendet. Zweitens wird eine Correlation-ID aus der Antwort übernommen. Dadurch kann ein Fehler im Frontend später mit Backend-Logs verbunden werden.
---
6. Admin Portal: interne Oberfläche mit höherem Risiko
Das Admin Portal ist deutlich sensibler als das Customer Portal. Mitarbeiter können Bestellungen prüfen, Rechnungsstatus einsehen, Kundendaten bearbeiten oder Fehlerfälle korrigieren. Solche Aktionen müssen protokolliert werden.
Ein Admin Portal braucht daher:
Vorlage / Textauszug
starke Authentifizierung
rollenbasierte Autorisierung
serverseitige Rechteprüfung
Audit Logging für kritische Aktionen
klare Trennung zwischen Lesen und Ändern
nachvollziehbare Fehlerbehandlung
Ein typischer Fehler ist, interne Oberflächen als weniger kritisch zu betrachten, weil sie „nur intern“ erreichbar sind. Das ist gefährlich. Interne Systeme haben oft mächtige Funktionen. Deshalb brauchen sie mindestens genauso klare Sicherheitsregeln wie externe Anwendungen.
Beispiel für Rollen:
Vorlage / Textauszug
ROLE_SUPPORT_READ
darf Bestellungen suchen und lesen
ROLE_ORDER_CORRECTION
darf bestimmte Bestelldaten korrigieren
ROLE_BILLING_REVIEW
darf Rechnungsstatus prüfen
ROLE_ADMIN_AUDIT
darf Audit-Protokolle einsehen
Nicht jeder interne Benutzer ist automatisch Administrator. Das Rollenmodell muss fein genug sein, damit Aufgaben sauber getrennt werden können.
---
7. Order Service: fachlicher Kern
Der Order Service ist einer der zentralen Backend-Services. Er nimmt Bestellungen entgegen, validiert sie, speichert sie und veröffentlicht Events. Er ist bewusst nicht für Abrechnung, E-Mail-Versand oder Reporting zuständig.
Die wichtigste fachliche Verantwortung lautet:
Vorlage / Textauszug
Der Order Service ist die Quelle der Wahrheit für Bestellungen.
Das bedeutet: Andere Systeme dürfen Bestellstatus nicht heimlich in ihrer eigenen Datenhaltung ändern. Sie können Ereignisse verarbeiten, Informationen ergänzen oder eigene Sichten aufbauen, aber die fachliche Bestellentscheidung liegt beim Order Service.
Der Service nutzt eine klassische Schichtung:
Vorlage / Textauszug
api
REST Controller
Request/Response DTOs
application
Use Cases
Transaktionsgrenzen
Koordination von Domäne und Ports
domain
fachliche Objekte
Regeln
Zustände
infrastructure
Datenbank
Messaging
Security Adapter
externe Clients
Diese Struktur verhindert, dass Infrastrukturdetails die Fachlogik dominieren.
Der Controller bleibt dünn. Er kennt HTTP, Validierung und Security Annotation. Er enthält aber keine Geschäftslogik. Die eigentliche Bestellung wird im Use Case verarbeitet.
---
9. Domain-Modell für Order
Das Domain-Modell schützt Regeln vor zufälliger Verteilung im Code.
java
package com.seb4u.demo.spring.order.domain;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
publicclass Order {
privatefinal OrderId id;
privatefinal CustomerId customerId;
privatefinal List<OrderItem> items;
private OrderStatus status;
privatefinal Instant createdAt;
private Order(OrderId id, CustomerId customerId, List<OrderItem> items, OrderStatus status, Instant createdAt) {
if (items == null || items.isEmpty()) {
thrownew IllegalArgumentException(class="str">"Eine Bestellung benötigt mindestens eine Position.");
}
this.id = id;
this.customerId = customerId;
this.items = new ArrayList<>(items);
this.status = status;
this.createdAt = createdAt;
}
publicstatic Order create(CustomerId customerId, List<OrderItem> items, Instant createdAt) {
returnnew Order(new OrderId(UUID.randomUUID()), customerId, items, OrderStatus.CREATED, createdAt);
}
publicvoid confirm() {
if (status != OrderStatus.CREATED) {
thrownew IllegalStateException(class="str">"Nur neu erstellte Bestellungen können bestätigt werden.");
}
status = OrderStatus.CONFIRMED;
}
publicvoid cancel() {
if (status == OrderStatus.BILLED) {
thrownew IllegalStateException(class="str">"Eine bereits abgerechnete Bestellung kann nicht storniert werden.");
}
status = OrderStatus.CANCELLED;
}
public BigDecimal totalAmount() {
return items.stream()
.map(OrderItem::totalPrice)
.reduce(BigDecimal.ZERO, BigDecimal::add);
}
public OrderId id() {
return id;
}
public CustomerId customerId() {
return customerId;
}
public OrderStatus status() {
return status;
}
public Instant createdAt() {
return createdAt;
}
}
Dieses Modell verhindert, dass beliebige Codestellen den Status einer Bestellung ohne Regelprüfung verändern. Die Methoden confirm und cancel enthalten fachliche Regeln.
---
10. Billing Service: Eventgetriebene Verarbeitung
Billing als Eventfluss
Kompakte Lernhilfe
Der Billing Service reagiert auf Events aus dem Order Service. Er erzeugt Rechnungsentwürfe, prüft Abrechnungsregeln und speichert eigene Rechnungsdaten. Er ist bewusst nicht Teil derselben Datenbank wie der Order Service.
Das Ziel ist lose Kopplung:
Skizze / Textauszug
Order Service veröffentlicht OrderCreatedEvent
↓
Broker transportiert Event
↓
Billing Service konsumiert Event
↓
Billing Service erstellt Billing Draft
Lose Kopplung bedeutet aber nicht, dass Fehler ignoriert werden dürfen. Eventverarbeitung braucht Idempotenz. Wenn ein Event zweimal geliefert wird, darf nicht zweimal eine Rechnung erzeugt werden.
Idempotenz ist kein Luxus. Sie ist in eventgetriebenen Systemen Pflicht, weil Broker Nachrichten erneut liefern können.
---
12. Reporting Service: Lesen ohne Fachlogik zu beschädigen
Reporting ist in Enterprise-Systemen oft schwierig. Fachbereiche wollen Auswertungen, Exporte, Excel-Dateien und historische Sichten. Gleichzeitig darf Reporting nicht die produktiven Kernprozesse stören.
Der Reporting Service soll daher nicht direkt in die Transaktionslogik eingreifen. Er liest aus freigegebenen Sichten, Replikaten oder speziell vorbereiteten Reporting-Tabellen. In kleinen Umgebungen kann er direkt aus Datenbanken lesen, aber in produktionsnahen Umgebungen sollte man Belastung, Rechte und Datenqualität beachten.
Mögliche Betriebsformen:
Vorlage / Textauszug
Kubernetes CronJob
gut für regelmäßige Exporte
standardisiertes Deployment
Logs und Status im Cluster sichtbar
VM-basierter Job
gut bei alten Reporting Tools
gut bei speziellen Treibern
sinnvoll als Übergangslösung
Separater Reporting Service
gut für APIs und interaktive Dashboards
braucht klare Zugriffskontrolle
Das Lab zeigt bewusst mehrere Varianten, weil Reporting in Unternehmen selten vollständig modernisiert ist.
Der CronJob nutzt concurrencyPolicy: Forbid, damit nicht mehrere Berichte gleichzeitig laufen und dieselbe Datenbank belasten.
---
14. File Processing Service: große Dateien kontrolliert verarbeiten
Der File Processing Service verarbeitet Dateien von Partnern. Solche Dateien können CSV, XML, JSON oder proprietäre Formate enthalten. Fehlerhafte Dateien dürfen nicht stillschweigend verschwinden. Jede Datei braucht einen nachvollziehbaren Status.
Ein sauberer Ablauf:
Skizze / Textauszug
Datei kommt an
↓
Datei bekommt technische ID
↓
Checksumme wird berechnet
↓
Schema wird geprüft
↓
Fachliche Regeln werden geprüft
↓
valide Datensätze werden weitergegeben
↓
fehlerhafte Datensätze werden protokolliert
↓
Originaldatei wird archiviert
Dieser Service kann auf OpenShift laufen, wenn die Dateigrößen und Storage-Anforderungen passen. Er kann aber auch auf VM oder Bare Metal laufen, wenn sehr große Dateien, lokale Storage-Anbindungen oder Spezialsoftware benötigt werden.
Der Service löscht Dateien nicht einfach. Er verschiebt sie in definierte Zustände: verarbeitet oder abgelehnt. Das erleichtert Betrieb und Nachvollziehbarkeit.
---
16. API Gateway: Eingangspunkt und Schutzschicht
Das API Gateway ist der zentrale technische Eingang für APIs. Es ist nicht der Ort für komplette Fachlogik. Es übernimmt technische Querschnittsaufgaben.
Typische Aufgaben:
Vorlage / Textauszug
TLS-Terminierung oder Weiterleitung
Routing zu Services
Rate Limits
Header-Normalisierung
Correlation-ID setzen
technische Authentifizierungsprüfung
einfache Schutzregeln
Fachliche Autorisierung bleibt trotzdem in den Services. Das Gateway kann prüfen, ob ein Token existiert. Der Order Service muss aber weiterhin prüfen, ob die konkrete Aktion erlaubt ist.
Ein häufiger Fehler ist, das Gateway zu mächtig zu machen. Dann entsteht eine zentrale Monsterkomponente. Besser ist: Gateway für technische Querschnittslogik, Fachentscheidungen in den Services.
---
17. API-Verträge und OpenAPI
REST APIs brauchen Verträge. Ohne Vertrag weiß das Frontend nicht zuverlässig, welche Felder existieren, welche Fehler auftreten können und welche Statuscodes verwendet werden.
Ein kleiner OpenAPI-Ausschnitt für den Order Service:
yaml
openapi: 3.0.3info:
title: Order Service API
version: 1.0.0paths:
/api/orders:
post:
summary: Create a new order
operationId: createOrder
security:
- bearerAuth: []
responses:
class="str">'201':
description: Order created
content:
application/json:
schema:
$ref: class="str">'#/components/schemas/CreateOrderResponse'
class="str">'400':
description: Invalid request
class="str">'401':
description: Missing or invalid token
class="str">'403':
description: Missing permission
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
schemas:
CreateOrderResponse:
type: object
required:
- orderId
- status
properties:
orderId:
type: string
status:
type: string
OpenAPI ist nicht nur Dokumentation. Es kann auch für Tests, Client-Generierung und Review genutzt werden.
---
18. Fehlerbehandlung als Architekturthema
Fehlerbehandlung darf nicht zufällig entstehen. Moderne Anwendungen brauchen ein einheitliches Fehlermodell.
Diese Metriken sind fachlich verständlich. Sie helfen nicht nur Entwicklern, sondern auch Betrieb und Fachbereich.
---
21. Konfiguration moderner Anwendungen
Konfiguration muss zwischen Umgebungen variieren können. Eine Anwendung darf nicht für jede Umgebung neu gebaut werden, nur weil sich Datenbankhost oder Keycloak-URL ändern.
Damit ist die Anwendung nicht nur lokal lauffähig, sondern auch plattformfähig.
---
24. Tests als Teil der Architektur
Tests sind nicht nur Qualitätskontrolle. Sie dokumentieren Annahmen. Besonders wichtig sind Integrationstests mit Datenbank, Broker und Security-Kontext.
Dieser Test beweist nicht alle Fachregeln, aber er zeigt, dass der Service mit einer echten PostgreSQL-Instanz starten kann.
---
25. Typische Fehler bei modernen Anwendungen
Ein häufiger Fehler ist zu viel Logik im Controller. Dann wird der Controller schwer testbar und jede Änderung betrifft HTTP, Fachlogik und Datenbank gleichzeitig.
Ein zweiter Fehler ist direkte Kopplung zwischen Services und fremden Datenbanken. Wenn Billing direkt Order-Tabellen verändert, ist die Servicegrenze kaputt.
Ein dritter Fehler ist fehlende Idempotenz bei Events. Dadurch entstehen doppelte Rechnungen, doppelte Benachrichtigungen oder falsche Statuswechsel.
Ein vierter Fehler ist unklare Fehlerbehandlung. Wenn jeder Service andere Fehlerformate liefert, wird das Frontend kompliziert und Betrieb verliert Nachvollziehbarkeit.
Ein fünfter Fehler ist fehlende Observability. Ein Service ohne fachliche Metriken kann im Betrieb technisch gesund wirken, obwohl fachlich nichts mehr funktioniert.
Ein sechster Fehler ist Build-Time-Konfiguration. Wenn für jede Umgebung ein anderes Image gebaut wird, entstehen schwer nachvollziehbare Unterschiede.
---
26. Runbook: Outbox wächst an
Vorlage / Textauszug
Runbook: Outbox Events werden nicht veröffentlicht
Symptom
Die Metrik `outbox_unpublished_events` steigt kontinuierlich an.
Auswirkung
Nachgelagerte Systeme wie Billing oder Reporting erhalten keine neuen Events. Bestellungen werden gespeichert, aber nicht weiterverarbeitet.
nach Wiederherstellung kontrollieren, ob Outbox sinkt
Eskalation
Wenn Events fachlich fehlerhaft sind, Team Order informieren.
Wenn Broker nicht verfügbar ist, Plattformteam informieren.
Dieses Runbook ist direkt mit der Anwendung verbunden. Es ist kein separater Anhang, sondern Teil des Betriebswissens zum Order Service.
---
27. Übung: Servicegrenze prüfen
Prüfe folgende Aussage:
Vorlage / Textauszug
Der Billing Service darf direkt in der Order-Datenbank den Status einer Bestellung auf BILLED setzen, sobald eine Rechnung erzeugt wurde.
Beantworte:
Vorlage / Textauszug
Warum ist das problematisch?
Welche Alternative ist besser?
Welche Events oder APIs wären sinnvoll?
Welche Fehler könnten entstehen, wenn Billing direkt schreibt?
---
28. Musterlösung
Die Aussage ist problematisch, weil der Billing Service damit die fachliche Verantwortung des Order Service verletzt. Die Order-Datenbank gehört dem Order Service. Wenn Billing direkt hineinschreibt, entstehen versteckte Kopplung und schwer nachvollziehbare Fehler.
Besser ist ein definierter Kommunikationsweg. Der Billing Service kann ein InvoiceCreatedEvent veröffentlichen. Der Order Service kann dieses Event konsumieren und selbst entscheiden, ob der Bestellstatus auf BILLED geändert werden darf. Alternativ kann Billing eine interne API des Order Service aufrufen, sofern dieser Weg fachlich und technisch gewünscht ist.
Sinnvolle Events wären:
Vorlage / Textauszug
OrderCreatedEvent
InvoiceDraftCreatedEvent
InvoiceApprovedEvent
OrderBilledEvent
Direktes Schreiben kann zu falschen Statuswechseln, Race Conditions, fehlendem Audit Logging, unklaren Transaktionsgrenzen und beschädigter Datenhoheit führen.
---
29. Merksätze
Vorlage / Textauszug
Eine moderne Anwendung besteht nicht nur aus Code.
Servicegrenzen schützen fachliche Verantwortung.
Das Frontend trifft keine finalen Sicherheitsentscheidungen.
Ein Container Image soll unverändert durch Umgebungen laufen.
Runbooks gehören direkt zum Servicewissen.
Daten, Messaging und Integration
Outbox und Eventfluss
Kompakte Themenübersicht
1. Warum Daten und Integration der Kern eines Enterprise-Systems sind
Moderne Anwendungen bestehen nicht nur aus Benutzeroberflächen und REST-Endpunkten. Der wichtigste Teil einer Enterprise-Landschaft ist häufig der Datenfluss: Welche Daten entstehen in welchem System, wer darf sie verändern, wer darf sie lesen, welche Ereignisse werden veröffentlicht, wie werden Fehler wiederholt und wie bleibt nachvollziehbar, was passiert ist?
Im Enterprise Platform Lab sind Daten nicht an eine einzige Infrastruktur gebunden. Einige Daten liegen in PostgreSQL auf Bare Metal, andere in einer Managed Database in der Cloud, Partnerdateien liegen in Object Storage, Events laufen über Kafka oder RabbitMQ, und Anwendungen auf OpenShift konsumieren oder veröffentlichen diese Informationen. Genau dadurch entsteht ein realistisches Bild: Moderne Anwendungen arbeiten selten allein. Sie sind Teil eines Netzes aus Datenbanken, APIs, Broker-Systemen, Dateiablagen und Legacy-Schnittstellen.
Ein häufiger Fehler ist, Integration nur als technische Verbindung zu betrachten. Man sagt dann: "Service A ruft Service B auf" oder "Event X wird an Kafka gesendet". Das reicht nicht. In Enterprise-Systemen muss man zusätzlich verstehen:
Vorlage / Textauszug
Wer besitzt die Daten?
Welche Daten sind führend?
Welche Daten sind nur Kopien?
Was passiert bei Fehlern?
Wie werden Events erneut verarbeitet?
Wie verhindert man doppelte Verarbeitung?
Wie werden personenbezogene Daten geschützt?
Wie lange werden Nachrichten und Dateien aufbewahrt?
Wie kann der Betrieb einen Fehler nachvollziehen?
Datenarchitektur ist deshalb keine Nebendisziplin. Sie entscheidet, ob ein System zuverlässig, auditierbar und wartbar ist.
---
2. Datenbesitz statt gemeinsame Datenbank
In alten Enterprise-Landschaften greifen oft viele Anwendungen auf dieselbe Datenbank zu. Das ist am Anfang bequem, wird aber mit der Zeit gefährlich. Wenn mehrere Systeme dieselben Tabellen direkt verändern, ist unklar, wem die Daten wirklich gehören. Jede Änderung am Schema kann andere Anwendungen beschädigen. Fachliche Regeln sind verteilt, und niemand kann zuverlässig sagen, welcher Prozess einen Wert geändert hat.
Im Zielbild des Labs gilt daher eine klare Regel:
Vorlage / Textauszug
Ein Service besitzt seine fachlichen Daten selbst.
Andere Systeme greifen nicht direkt auf seine Tabellen zu.
Der Order Service besitzt Bestellungen. Der Billing Service besitzt Rechnungen. Der Reporting Service darf Daten lesen oder aus Replikaten verarbeiten, aber er darf nicht heimlich Bestellungen verändern. Das Admin Portal besitzt keine Kerndaten, sondern ruft fachliche APIs auf.
Diese Regel ist wichtig, weil sie fachliche Verantwortung sichtbar macht. Wenn eine Bestellung falsch ist, ist der Order Service verantwortlich. Wenn eine Rechnung falsch ist, ist der Billing Service verantwortlich. Wenn ein Report falsch aggregiert, ist der Reporting Service verantwortlich.
Datenbesitz bedeutet nicht, dass jeder Service zwingend eine eigene physische Datenbank braucht. In einem Lab kann man mehrere Schemas auf derselben PostgreSQL-Instanz verwenden. Wichtig ist die logische Grenze:
Vorlage / Textauszug
orders_schema gehört dem Order Service.
billing_schema gehört dem Billing Service.
reporting_schema gehört dem Reporting Service.
Andere Services dürfen diese Schemas nicht direkt verändern.
---
3. Datenmodell im Lab
Das Lab verwendet mehrere Datenbereiche.
Der Order Service speichert Bestellungen, Bestellpositionen und Outbox-Events. Der Billing Service speichert Rechnungsentwürfe, Rechnungen, Zahlungsstatus und Audit-Einträge. Der File Processing Service speichert Metadaten zu Partnerdateien. Der Reporting Service erzeugt eigene Auswertungsdaten, die aus Events, Datenbank-Views oder Exporten entstehen können.
Eine vereinfachte Sicht:
Vorlage / Textauszug
Order Service
orders
order_items
outbox_events
Billing Service
invoices
invoice_lines
payment_status
billing_audit_log
File Processing Service
file_batches
file_records
file_errors
Reporting Service
daily_order_summary
daily_billing_summary
partner_file_quality_summary
Diese Aufteilung verhindert, dass ein einziger Datenbankbereich zu einem unkontrollierten Sammelbecken wird.
---
4. Relationale Datenbanken
Relationale Datenbanken bleiben in modernen Enterprise-Systemen sehr wichtig. Sie sind besonders stark, wenn Daten konsistent, abfragbar und transaktional verarbeitet werden müssen. Bestellungen, Rechnungen, Kundenreferenzen, Statusänderungen und Audit-Daten sind typische Beispiele.
Im Lab verwenden wir PostgreSQL als Standarddatenbank. PostgreSQL kann lokal, auf einer VM, auf Bare Metal, in OpenShift oder als Managed Cloud Database betrieben werden. Die Architektur muss aber bewusst entscheiden, welche Variante für welchen Zweck passt.
Für produktionsnahe Kernsysteme kann Bare Metal oder eine dedizierte VM sinnvoll sein, wenn I/O-Leistung, Backup-Kontrolle oder bestehende Betriebsprozesse wichtig sind. Für Testumgebungen kann eine Managed Cloud Database praktisch sein. Für lokale Entwicklung reicht Docker Compose.
Eine wichtige Regel lautet:
Vorlage / Textauszug
Die Anwendung darf nicht wissen, ob PostgreSQL auf Bare Metal, VM oder Cloud läuft.
Sie kennt nur Host, Port, Datenbankname, Benutzer und Zertifikatskonfiguration.
Diese Entkopplung ermöglicht spätere Migrationen.
---
5. Schema-Migration mit Flyway
Datenbankschema darf nicht manuell verändert werden. Jede Änderung muss versioniert sein. Dafür verwenden wir Flyway oder Liquibase.
Eine Migration ist ein technischer Nachweis. Sie zeigt, wann und wie das Datenmodell verändert wurde.
Beispiel:
sql
CREATETABLE orders (
id UUID PRIMARYKEY,
customer_id VARCHAR(80) NOTNULL,
status VARCHAR(40) NOTNULL,
total_amount NUMERIC(12, 2) NOTNULL,
currency VARCHAR(3) NOTNULL,
created_at TIMESTAMP WITH TIME ZONE NOTNULL,
updated_at TIMESTAMP WITH TIME ZONE
);
CREATEINDEX idx_orders_customer_id ON orders(customer_id);
CREATEINDEX idx_orders_status ON orders(status);
Diese Migration enthält bereits zwei wichtige Betriebsaspekte: Abfragen nach Kunde und Status werden erwartet und deshalb indiziert. Ein Schema ist also nicht nur Datenspeicherung, sondern auch Ausdruck der erwarteten Nutzung.
---
6. Transaktionen und fachliche Konsistenz
Eine Bestellung wird nicht nur als einzelner Datensatz gespeichert. Sie enthält Positionen, Beträge, Status und möglicherweise ein fachliches Event. Diese Schritte müssen konsistent sein.
Wenn die Bestellung gespeichert wird, aber das Event nicht entsteht, kann Billing nicht reagieren. Wenn das Event entsteht, aber die Bestellung nicht gespeichert wird, verarbeitet Billing falsche Informationen.
Darum gilt:
Vorlage / Textauszug
Fachliche Zustandsänderung und Outbox-Eintrag gehören in dieselbe Transaktion.
Die Methode verwendet eine Transaktion. Dadurch werden Bestellung und Outbox-Eintrag gemeinsam bestätigt oder gemeinsam zurückgerollt.
---
7. Outbox Publisher
Outbox-Pattern
Kompakte Lernhilfe
Der Outbox Publisher liest unveröffentlichte Events und sendet sie an den Broker. Er ist bewusst von der fachlichen Transaktion getrennt. Dadurch bleibt die Bestellung schnell und konsistent, während die Veröffentlichung wiederholt werden kann.
Dieses Beispiel ist bewusst einfach. In produktionsnahen Umgebungen würde man zusätzlich Sperrmechanismen, Backoff, Dead-Letter-Handling, Metriken und Tracing ergänzen.
---
8. Messaging: Kafka oder RabbitMQ?
Messaging verbindet Systeme asynchron. Das bedeutet: Ein Service muss nicht warten, bis ein anderer Service seine Arbeit sofort erledigt. Stattdessen veröffentlicht er ein Event oder eine Nachricht.
Kafka eignet sich besonders für Event Streams, hohe Durchsätze, Wiederholbarkeit, zeitliche Entkopplung und mehrere Consumer-Gruppen. RabbitMQ eignet sich stark für klassische Work Queues, Routing, bestimmte Zustellmuster und Aufgabenverteilung.
Im Lab können beide Varianten vorkommen:
Vorlage / Textauszug
Kafka:
OrderCreatedEvent
OrderConfirmedEvent
InvoiceCreatedEvent
Reporting Streams
RabbitMQ:
File validation jobs
Retry queues
gezielte Arbeitsaufträge
klassische Command-Nachrichten
Die Entscheidung hängt nicht von Mode ab, sondern von Semantik.
Ein Event sagt:
Vorlage / Textauszug
Etwas ist passiert.
Ein Command sagt:
Vorlage / Textauszug
Bitte tue etwas.
Diese Unterscheidung ist sehr wichtig.
---
9. Event-Naming
Events sollten fachlich benannt werden. Schlechte Namen sind technisch oder unklar:
Vorlage / Textauszug
OrderMessage
DataChanged
StatusUpdate
PayloadEvent
Bessere Namen:
Vorlage / Textauszug
OrderCreated
OrderConfirmed
InvoiceDraftCreated
PaymentMarkedAsOverdue
PartnerFileRejected
Ein Event beschreibt eine fachliche Tatsache in der Vergangenheit. Deshalb wird häufig die Vergangenheitsform verwendet.
Ein Event sollte nicht lauten:
Vorlage / Textauszug
CreateInvoice
Das wäre eher ein Command.
Besser:
Vorlage / Textauszug
OrderConfirmed
Der Billing Service entscheidet dann, ob daraus eine Rechnung entsteht.
---
10. Event Payload
Ein Event sollte genug Informationen enthalten, damit Consumer sinnvoll reagieren können. Es sollte aber nicht die gesamte Datenbankstruktur eines Services exportieren.
Nicht jedes Event muss alle Details enthalten. Wenn ein Consumer mehr Informationen braucht, kann er über eine API nachladen. Das ist ein bewusstes Design.
---
11. Idempotenz
In verteilten Systemen können Nachrichten mehrfach ankommen. Das ist kein Ausnahmefall, sondern normales Verhalten. Ein Consumer muss deshalb idempotent sein.
Idempotenz bedeutet:
Vorlage / Textauszug
Dieselbe Nachricht mehrfach zu verarbeiten führt nicht zu falschen mehrfachen Ergebnissen.
Beispiel: Wenn Billing ein OrderConfirmed Event zweimal erhält, darf nicht zweimal dieselbe Rechnung erstellt werden.
Eine einfache Lösung ist eine Tabelle für verarbeitete Events:
sql
CREATETABLE processed_events (
event_id UUID PRIMARYKEY,
event_type VARCHAR(160) NOTNULL,
processed_at TIMESTAMP WITH TIME ZONE NOTNULL
);
Der Consumer prüft vor der Verarbeitung, ob event_id bereits existiert.
Ohne Idempotenz wirkt Messaging im Test oft korrekt, aber in Produktion entstehen doppelte Rechnungen, doppelte E-Mails oder doppelte Buchungen.
---
12. Dead Letter Queue
Nicht jede Nachricht kann erfolgreich verarbeitet werden. Manchmal ist das Format falsch, eine Referenz fehlt, ein externer Dienst ist nicht erreichbar oder ein fachlicher Zustand passt nicht.
Wenn ein Consumer dieselbe fehlerhafte Nachricht endlos wiederholt, blockiert er Verarbeitung. Deshalb braucht man ein Dead-Letter-Konzept.
Eine Dead Letter Queue enthält Nachrichten, die nach mehreren Versuchen nicht verarbeitet werden konnten.
Wichtig ist: Eine Dead Letter Queue ist kein Mülleimer. Sie ist ein Betriebsartefakt.
Nicht jede Integration ist Event-basiert. REST APIs bleiben wichtig, besonders wenn ein System eine direkte Antwort braucht.
Beispiel:
Vorlage / Textauszug
Customer Portal ruft Order Service auf, um aktuelle Bestellungen anzuzeigen.
Admin Portal ruft Billing Service auf, um Rechnungsstatus zu prüfen.
Reporting ruft eine Export-API auf, um Daten für einen Zeitraum zu laden.
REST eignet sich gut für synchrone Abfragen und direkte Benutzerinteraktionen. Es ist weniger gut für lange Hintergrundprozesse oder viele abhängige Zustandsänderungen.
Eine gute API definiert klare Ressourcen:
Vorlage / Textauszug
GET /orders/{orderId}
POST /orders
GET /customers/{customerId}/orders
GET /invoices/{invoiceId}
POST /invoices/{invoiceId}/mark-paid
Eine schlechte API versteckt Fachlichkeit hinter technischen Namen:
Vorlage / Textauszug
POST /process
POST /updateData
GET /getStatus
---
14. API-Verträge mit OpenAPI
OpenAPI macht REST-Schnittstellen dokumentierbar und prüfbar. In Enterprise-Projekten ist das wichtig, weil mehrere Teams dieselben Schnittstellen verwenden.
Ein kleiner Ausschnitt:
yaml
openapi: 3.0.3info:
title: Order Service API
version: 1.0.0paths:
/orders:
post:
summary: Create a new order
operationId: createOrder
requestBody:
required: truecontent:
application/json:
schema:
$ref: class="str">'#/components/schemas/CreateOrderRequest'
responses:
class="str">'201':
description: Order created
content:
application/json:
schema:
$ref: class="str">'#/components/schemas/CreateOrderResponse'
class="str">'400':
description: Invalid request
components:
schemas:
CreateOrderRequest:
type: object
required:
- customerId
- items
properties:
customerId:
type: string
items:
type: array
items:
$ref: class="str">'#/components/schemas/CreateOrderItem'
CreateOrderItem:
type: object
required:
- productId
- quantity
properties:
productId:
type: string
quantity:
type: integer
minimum: 1
OpenAPI hilft nicht nur beim Lesen. Es kann auch für Client-Generierung, Contract Tests und API Reviews genutzt werden.
---
15. Anti-Corruption Layer
Wenn moderne Services mit Legacy-Systemen sprechen, dürfen Legacy-Begriffe nicht unkontrolliert in die neue Domäne gelangen.
Ein Anti-Corruption Layer übersetzt alte Schnittstellen in moderne fachliche Modelle.
Beispiel: Ein Legacy-System liefert Statuswerte:
Vorlage / Textauszug
A
B
C
X
9
Der moderne Order Service will aber klare Status:
Vorlage / Textauszug
CREATED
CONFIRMED
CANCELLED
FAILED
Die Übersetzung gehört nicht überall verteilt in Controller, Services und Repositories. Sie gehört in eine klare Integrationsschicht.
java
package com.seb4u.demo.spring.order.integration.legacy;
import com.seb4u.demo.spring.order.domain.OrderStatus;
import org.springframework.stereotype.Component;
@Componentpublicclass LegacyOrderStatusMapper {
public OrderStatus map(String legacyStatus) {
return switch (legacyStatus) {
case class="str">"A" -> OrderStatus.CREATED;
case class="str">"B" -> OrderStatus.CONFIRMED;
case class="str">"C" -> OrderStatus.CANCELLED;
case class="str">"X", class="str">"9" -> OrderStatus.FAILED;
default -> thrownew IllegalArgumentException(class="str">"Unknown legacy status: " + legacyStatus);
};
}
}
Dieser Mapper sieht klein aus, ist aber architektonisch wichtig. Er verhindert, dass Legacy-Codes die moderne Domäne verschmutzen.
---
16. Dateibasierte Integration
Viele Enterprise-Systeme verwenden weiterhin Dateien. Das ist nicht automatisch schlecht. Dateien sind besonders nützlich, wenn Partner keine APIs anbieten, große Datenmengen übertragen werden oder rechtliche Archivierung erforderlich ist.
Ein moderner dateibasierter Ablauf sieht kontrolliert aus:
Skizze / Textauszug
Partner stellt Datei bereit
↓
Datei landet im incoming Bucket
↓
Metadaten werden gespeichert
↓
Validierung startet
↓
gültige Datensätze werden verarbeitet
↓
fehlerhafte Datensätze werden mit Gründen abgelegt
↓
Event wird veröffentlicht
↓
Reporting und Fachservices reagieren
Wichtig ist, dass Datei-Verarbeitung nicht nur ein Bash-Skript auf einem Server ist. Sie braucht Status, Wiederholbarkeit, Fehlerprotokolle und Monitoring.
---
17. File Batch Datenmodell
sql
CREATETABLE file_batches (
id UUID PRIMARYKEY,
partner_id VARCHAR(80) NOTNULL,
file_name VARCHAR(255) NOTNULL,
object_storage_key VARCHAR(500) NOTNULL,
status VARCHAR(40) NOTNULL,
received_at TIMESTAMP WITH TIME ZONE NOTNULL,
processed_at TIMESTAMP WITH TIME ZONE,
total_records INTEGER,
valid_records INTEGER,
invalid_records INTEGER,
last_error TEXT
);
CREATETABLE file_record_errors (
id UUID PRIMARYKEY,
batch_id UUID NOTNULLREFERENCES file_batches(id),
line_number INTEGER NOTNULL,
error_code VARCHAR(80) NOTNULL,
error_message TEXT NOTNULL,
raw_record TEXT
);
Dieses Modell ist betriebsfreundlich. Man sieht nicht nur, dass eine Datei fehlgeschlagen ist, sondern auch, wie viele Datensätze betroffen sind und warum.
---
18. Integration mit Object Storage
Object Storage eignet sich gut für Partnerdateien, Exporte, Reports und Archivierung. Die Anwendung speichert nicht direkt auf lokaler Platte, sondern in Buckets.
Auch hier gilt: Die Dateiablage ist Teil der Architektur. Bucket-Namen, Verschlüsselung, Versionierung, Aufbewahrung und Zugriff müssen dokumentiert werden.
---
19. Datenklassifizierung
Nicht alle Daten sind gleich sensibel. Eine Plattform muss unterscheiden können.
Beispiele:
Vorlage / Textauszug
Public: öffentliche Produktinformationen
Internal: interne Betriebsdaten
Confidential: Kundeninformationen, Rechnungen
Restricted: Zahlungsdaten, besonders schützenswerte Daten
Diese Klassifizierung beeinflusst:
Vorlage / Textauszug
Speicherort
Verschlüsselung
Zugriff
Logging
Aufbewahrung
Backup
Exportregeln
Maskierung in Testumgebungen
Ein häufiger Fehler ist, produktive Daten einfach in Testumgebungen zu kopieren. Das kann Datenschutz- und Compliance-Probleme erzeugen. Testdaten müssen anonymisiert, synthetisch erzeugt oder streng kontrolliert werden.
---
20. Logging von Datenflüssen
Datenflüsse müssen nachvollziehbar sein, aber Logs dürfen keine sensiblen Daten unkontrolliert enthalten.
Das Log ist nützlich, ohne unnötig sensible Details zu veröffentlichen.
---
21. Tracing über Systemgrenzen
In einer verteilten Architektur reicht ein einzelnes Log nicht aus. Eine Anfrage oder ein Event wandert durch mehrere Systeme. Tracing verbindet diese Schritte.
Beispiel:
Skizze / Textauszug
Customer Portal
↓ traceId=abc123
Order Service
↓
Outbox Publisher
↓
Kafka
↓
Billing Service
↓
Invoice Database
Wenn überall dieselbe Trace-ID sichtbar ist, kann der Betrieb den Ablauf nachvollziehen. Ohne Trace-ID sieht man nur isolierte Logzeilen.
Für HTTP wird Trace-Kontext oft über Header weitergegeben. Für Events muss man Trace-Informationen in Message Headers oder Payload-Metadaten übernehmen.
---
22. Reporting und Datenkopien
Reporting braucht oft andere Datenstrukturen als operative Anwendungen. Ein Order Service speichert Bestellungen transaktional. Reporting möchte aggregierte Zahlen pro Tag, Region, Produkt oder Partner sehen.
Es ist meist falsch, komplexe Reports direkt auf operativen Tabellen auszuführen. Das kann Produktivsysteme belasten und fachliche Grenzen verwischen.
Diese Tabelle gehört dem Reporting Service, nicht dem Order Service.
---
23. Change Data Capture
Change Data Capture, kurz CDC, liest Änderungen aus einer Datenbank und stellt sie anderen Systemen bereit. Werkzeuge wie Debezium können Änderungen aus PostgreSQL erfassen und als Events veröffentlichen.
CDC kann nützlich sein, wenn bestehende Systeme keine Events veröffentlichen können. Es ist aber kein Ersatz für fachliches Event-Design.
Ein technisches Datenbank-Update sagt nicht automatisch, was fachlich passiert ist.
Beispiel:
Vorlage / Textauszug
status changed from A to B
Das ist technisch.
Fachlich könnte es bedeuten:
Vorlage / Textauszug
OrderConfirmed
OrderReleasedForBilling
OrderApprovedByBackoffice
CDC ist daher besonders gut für Integration mit Legacy-Systemen, Replikation und Übergangslösungen. Für neue Services sollte man fachliche Events bewusst modellieren.
---
24. Konsistenzmodelle
Nicht alle Systeme sind sofort konsistent. Bei asynchroner Verarbeitung entsteht zeitweise Verzögerung.
Beispiel:
Vorlage / Textauszug
Kunde bestätigt Bestellung.
Order Service speichert Bestellung sofort.
Billing erstellt Rechnung einige Sekunden später.
Reporting zeigt Umsatz vielleicht erst nach einer Minute.
Das ist nicht automatisch ein Fehler. Es ist eventual consistency.
Wichtig ist, dass Benutzeroberflächen und Fachprozesse damit umgehen können. Das Portal darf nicht erwarten, dass eine Rechnung im selben Millisekunden-Moment existiert. Es kann stattdessen anzeigen:
Vorlage / Textauszug
Ihre Bestellung wurde bestätigt. Die Rechnung wird vorbereitet.
Eine gute Architektur erklärt solche Zustände fachlich.
---
25. Integrationstest mit Testcontainers
Integration muss getestet werden. Mock-Tests reichen nicht aus, wenn Datenbank, Migrationen und Messaging beteiligt sind.
Mit Testcontainers kann ein Test echte Infrastrukturkomponenten starten.
java
package com.seb4u.demo.spring.order;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
@SpringBootTest@Testcontainersclass OrderServiceIntegrationTest {
@Containerstatic PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>(class="str">"postgres:16")
.withDatabaseName(class="str">"orders")
.withUsername(class="str">"orders")
.withPassword(class="str">"orders");
@DynamicPropertySourcestaticvoid databaseProperties(DynamicPropertyRegistry registry) {
registry.add(class="str">"spring.datasource.url", postgres::getJdbcUrl);
registry.add(class="str">"spring.datasource.username", postgres::getUsername);
registry.add(class="str">"spring.datasource.password", postgres::getPassword);
}
@Testvoid contextStartsWithRealPostgres() {
// Der Test startet die Anwendung mit echter PostgreSQL-Datenbank.
// Flyway-Migrationen laufen dabei ebenfalls.
}
}
Dieser Test prüft nicht nur Java-Code. Er prüft, ob Anwendung, Konfiguration und Datenbankmigration zusammenpassen.
---
26. Runbook: Outbox wächst an
Vorlage / Textauszug
Runbook: Outbox wächst an
Symptom
Die Tabelle `outbox_events` enthält viele unveröffentlichte Events. Billing oder Reporting erhält keine neuen Ereignisse.
Publisher nach Fehlerbehebung erneut laufen lassen.
Falls Payload defekt ist, fachlich entscheiden, ob Event korrigiert, übersprungen oder manuell verarbeitet wird.
Eskalation
Messaging Team bei Broker-Problemen
Team Order bei Payload- oder Outbox-Problemen
Plattformteam bei Netzwerk- oder Secret-Problemen
---
27. Typische Fehler bei Daten und Integration
Ein häufiger Fehler ist direkter Datenbankzugriff zwischen Services. Dadurch entstehen versteckte Kopplungen und unklare Verantwortlichkeiten.
Ein zweiter Fehler ist fehlende Idempotenz. In Testumgebungen fällt das selten auf, in Produktion führt es zu doppelten Rechnungen, doppelten Benachrichtigungen oder falschen Reports.
Ein dritter Fehler ist zu große Event Payload. Wenn Events komplette Datenbankobjekte enthalten, werden sie schwer versionierbar und koppeln Consumer an interne Modelle.
Ein vierter Fehler ist fehlendes Dead-Letter-Konzept. Fehlerhafte Nachrichten werden endlos wiederholt oder verschwinden unkontrolliert.
Ein fünfter Fehler ist fehlende Datenklassifizierung. Dann landen sensible Informationen in Logs, Testdatenbanken oder ungeschützten Buckets.
Ein sechster Fehler ist ungeprüfte Datei-Verarbeitung. Partnerdateien werden verarbeitet, ohne Fehlerzeilen, Status und Wiederholbarkeit sauber zu dokumentieren.
---
28. Übung: Datenfluss für eine Bestellung modellieren
Modelliere den Datenfluss vom Erstellen einer Bestellung bis zur Rechnung.
Beantworte:
Vorlage / Textauszug
Welche Daten speichert der Order Service?
Welches Event entsteht?
Welche Daten speichert der Billing Service?
Wie wird doppelte Verarbeitung verhindert?
Was passiert, wenn der Broker nicht erreichbar ist?
Welche Logs und Metriken braucht der Betrieb?
Welche Daten dürfen nicht im Log stehen?
---
29. Musterlösung zur Übung
Eine mögliche Lösung:
Vorlage / Textauszug
Der Order Service speichert Bestellung, Bestellpositionen und den fachlichen Status. In derselben Transaktion schreibt er ein OrderConfirmed Event in die Outbox.
Der Outbox Publisher veröffentlicht das Event an Kafka. Wenn Kafka nicht erreichbar ist, bleibt das Event unveröffentlicht und wird später erneut versucht.
Der Billing Service konsumiert OrderConfirmed. Er prüft die eventId gegen eine processed_events Tabelle. Wenn das Event bereits verarbeitet wurde, beendet er die Verarbeitung ohne neue Rechnung.
Wenn das Event neu ist, erstellt Billing einen Rechnungsentwurf und markiert das Event als verarbeitet.
Der Betrieb überwacht die Anzahl unveröffentlichter Outbox Events, Consumer Lag, Dead Letter Messages, Fehlerlogs und Trace-IDs.
Logs dürfen orderId, eventId und traceId enthalten. Sie dürfen keine vollständigen Zahlungsdaten, Tokens oder sensiblen Kundendaten enthalten.
---
30. Merksätze
Vorlage / Textauszug
Datenbesitz ist wichtiger als die physische Datenbankgrenze.
Ein Event beschreibt, was passiert ist. Ein Command fordert eine Aktion an.
Outbox schützt vor auseinanderlaufender Datenbank- und Broker-Verarbeitung.
Idempotenz ist Pflicht, nicht Luxus.
Dead Letter Queues sind Betriebsartefakte, keine Müllhalden.
Dateibasierte Integration braucht Status, Fehlerprotokolle und Wiederholbarkeit.
Reporting sollte operative Systeme nicht unkontrolliert belasten.
Datenklassifizierung beeinflusst Logging, Storage, Testdaten und Zugriff.
Teil E: Observability, Betrieb, Backup, Disaster Recovery und Resilienz
Teil E: Observability, Betrieb, Backup, Disaster Recovery und Resilienz
Konsolidiert aus Rohmaterial: Teil 9, Teil 10, Teil 38.
Observability und Betrieb
Logs, Metrics und Traces
Kompakte Themenübersicht
1. Warum Observability mehr ist als Monitoring
In vielen Projekten wird Monitoring erst am Ende eingebaut. Dann läuft die Anwendung zwar technisch, aber niemand kann zuverlässig erklären, was im Fehlerfall passiert. Ein Service ohne gute Beobachtbarkeit ist im Betrieb schwer zu verantworten. Man sieht vielleicht, dass ein Pod neu gestartet wurde, aber nicht warum. Man sieht vielleicht, dass eine API langsam ist, aber nicht, ob die Ursache im Code, in der Datenbank, im Broker, im Netzwerk oder in einer externen Abhängigkeit liegt.
Observability bedeutet, dass ein System so gebaut wird, dass sein Zustand von außen verständlich wird. Es reicht nicht, nur CPU und RAM zu messen. Für ein Enterprise-System braucht man technische Signale, fachliche Signale und Betriebsnachweise.
Ein modernes System beantwortet im Betrieb Fragen wie:
Vorlage / Textauszug
Ist der Service erreichbar?
Ist der Service nur gestartet oder wirklich funktionsfähig?
Wie viele Bestellungen wurden verarbeitet?
Wie viele Events hängen in der Outbox?
Wie lange dauert eine typische Anfrage?
Welche Abhängigkeit verursacht Latenz?
Welche Fehler treten wiederholt auf?
Welche Version läuft gerade?
Welche Konfiguration ist aktiv?
Welche Änderung wurde zuletzt deployt?
Observability ist deshalb keine Zusatzfunktion. Sie ist Teil der Architektur. Wenn ein Service keine Logs, Metriken, Traces, Health Checks, Dashboards und Runbooks hat, ist er nicht produktionsnah.
---
2. Die drei klassischen Säulen
Observability wird häufig über drei Säulen beschrieben:
Vorlage / Textauszug
Logs
Metriken
Traces
Logs beschreiben Ereignisse. Sie erzählen, was passiert ist. Ein Logeintrag kann zeigen, dass eine Bestellung erstellt wurde, dass eine Validierung fehlgeschlagen ist oder dass ein Aufruf zur Datenbank nicht funktioniert hat.
Metriken beschreiben Zahlen über die Zeit. Sie zeigen zum Beispiel Anzahl von Requests, Fehlerquote, Antwortzeiten, Speicherverbrauch, CPU-Nutzung, Queue-Länge oder Anzahl unveröffentlichter Outbox-Events.
Traces verbinden einzelne Schritte einer Anfrage über mehrere Services hinweg. Ein Trace zeigt, dass ein Request vom Customer Portal über das API Gateway zum Order Service, zur Datenbank, zur Outbox und später zum Billing Service geführt hat.
Diese drei Signale ergänzen sich. Logs ohne Metriken führen zu mühsamer Suche. Metriken ohne Logs zeigen nur Symptome. Traces ohne fachliche Informationen erklären oft nicht genug. Erst zusammen entsteht ein brauchbares Betriebsbild.
---
3. Observability-Zielbild im Lab
Observability-Zielbild
Kompakte Lernhilfe
Im Enterprise Platform Lab verwenden wir folgende Zielarchitektur:
mermaid
flowchart LR
Portal[Customer Portal] --> Gateway[API Gateway]
Gateway --> Order[Order Service]
Order --> DB[(PostgreSQL)]
Order --> Outbox[Outbox]
Outbox --> Broker[Kafka / RabbitMQ]
Broker --> Billing[Billing Service]
Order --> Logs[Loki]
Billing --> Logs
Gateway --> Logs
Order --> Metrics[Prometheus]
Billing --> Metrics
DB --> Metrics
Broker --> Metrics
Order --> Traces[Tempo]
Billing --> Traces
Gateway --> Traces
Metrics --> Grafana[Grafana]
Logs --> Grafana
Traces --> Grafana
Grafana ist dabei nicht die Datenquelle selbst. Grafana visualisiert Daten aus Prometheus, Loki und Tempo. Prometheus sammelt Metriken. Loki speichert Logs. Tempo speichert Traces. In anderen Unternehmen können andere Werkzeuge genutzt werden, zum Beispiel Elastic, Splunk, Datadog, New Relic oder OpenTelemetry Collector mit verschiedenen Backends. Das Prinzip bleibt gleich.
---
4. Health Checks: gestartet ist nicht gesund
Ein Prozess kann laufen und trotzdem fachlich nicht funktionieren. Deshalb braucht ein Service Health Checks.
Spring Boot unterscheidet typischerweise zwischen Liveness und Readiness.
Liveness beantwortet: Muss der Container neu gestartet werden?
Readiness beantwortet: Darf der Service Traffic erhalten?
Ein Service kann live, aber nicht ready sein. Beispiel: Die Anwendung läuft, aber die Datenbank ist nicht erreichbar. Dann soll Kubernetes den Container nicht unbedingt sofort töten, aber der Service soll vorübergehend keinen Traffic bekommen.
Ein häufiger Fehler ist, für beide Probes denselben Endpunkt zu verwenden. Wenn die Readiness wegen einer abhängigen Datenbank fehlschlägt, ist das sinnvoll. Wenn aber die Liveness wegen einer kurzzeitig nicht erreichbaren Datenbank fehlschlägt, kann Kubernetes den Pod unnötig oft neu starten. Dadurch wird die Störung schlimmer.
---
5. Spring Boot Actuator richtig nutzen
Spring Boot Actuator liefert viele Betriebsendpunkte. Diese dürfen aber nicht unkontrolliert nach außen exponiert werden.
Für produktionsnahe Umgebungen gilt: Health, Info und Prometheus sind nützlich. Detaillierte interne Informationen sollten nicht öffentlich erreichbar sein. Debug- oder Env-Endpunkte gehören nicht offen ins Internet.
Ein sauberer Betrieb trennt zwischen internen Management-Endpunkten und externen API-Endpunkten. In OpenShift kann das über Services, Routes, NetworkPolicies und Authentifizierung geregelt werden.
---
6. Strukturierte Logs
Logs sollten maschinenlesbar sein. Freitext-Logs sind schwer zu durchsuchen. Strukturierte Logs enthalten Felder wie Zeitstempel, Level, Service, Trace-ID, Request-ID, Benutzerkontext, Fehlercode und fachlichen Bezug.
Denn er enthält Kontext, Wiederholungsversuch, Event, Service und Korrelation.
---
7. Logback-Konfiguration für JSON Logs
In einem Spring Boot Service kann JSON Logging zum Beispiel über einen JSON Encoder umgesetzt werden. Wichtig ist nicht die konkrete Library, sondern das Ergebnis: Logs sollen strukturiert und einheitlich sein.
Im Container sollten Logs nach stdout/stderr geschrieben werden. Der Container schreibt nicht selbst in lokale Dateien, die später niemand findet. Die Plattform sammelt stdout/stderr zentral ein.
---
8. Trace-ID und Correlation-ID
In verteilten Systemen ist Korrelation entscheidend. Eine Benutzeraktion löst oft mehrere technische Schritte aus. Ohne gemeinsame ID ist die Suche schwer.
Beispielablauf:
Skizze / Textauszug
Customer Portal
↓ traceId=abc123
API Gateway
↓ traceId=abc123
Order Service
↓ traceId=abc123
PostgreSQL
↓
Outbox Event
↓ traceId=abc123 im Event Header
Kafka
↓
Billing Service
Wenn die Trace-ID nur im HTTP Request existiert, aber nicht im Event Header, bricht die Kette. Deshalb muss bei Messaging darauf geachtet werden, Korrelation weiterzugeben.
Das ist kein Luxus. Ohne solche Header wird Fehleranalyse über HTTP und Messaging hinweg deutlich schwieriger.
---
9. Metriken: technische und fachliche Werte
Metriken sollten nicht nur Infrastrukturwerte zeigen. CPU, RAM und Pod-Restarts sind wichtig, aber sie erklären nicht, ob der fachliche Prozess funktioniert.
Für den Order Service brauchen wir zum Beispiel:
Vorlage / Textauszug
Technische Metriken:
HTTP Request Count
HTTP Error Rate
Request Duration
JVM Memory
CPU Usage
Database Connection Pool
Pod Restarts
Fachliche Metriken:
Anzahl erstellter Bestellungen
Anzahl abgelehnter Bestellungen
Anzahl offener Outbox Events
ältestes unveröffentlichtes Outbox Event
Anzahl fehlgeschlagener Publishing-Versuche
Anzahl doppelt erkannter Events
Fachliche Metriken sind oft wertvoller als reine Infrastrukturwerte. Wenn die CPU niedrig ist, aber keine Bestellungen mehr verarbeitet werden, ist das System trotzdem gestört.
---
10. Eigene Metriken in Spring Boot
Mit Micrometer können eigene Metriken erzeugt werden.
Ein häufiger Fehler ist, dass ServiceMonitor und Service nicht zusammenpassen. Dann läuft die Anwendung, aber Prometheus sammelt keine Metriken.
---
12. Alerting: gute und schlechte Alarme
Ein Alarm ist nur nützlich, wenn er eine klare Handlung auslöst. Schlechte Alarme erzeugen Lärm. Gute Alarme zeigen einen Zustand, der Aufmerksamkeit braucht, und verweisen auf ein Runbook.
Schlechter Alarm:
Vorlage / Textauszug
CPU über 70 Prozent.
Warum schlecht? Eine hohe CPU kann normal sein. Ohne Kontext weiß niemand, ob eine Handlung nötig ist.
Besser:
Vorlage / Textauszug
Order Service Error Rate über 5 Prozent für 10 Minuten.
Runbook: docs/runbooks/order-service-errors.md
Noch besser:
Vorlage / Textauszug
Outbox unveröffentlichte Events steigen seit 15 Minuten und ältestes Event ist älter als 10 Minuten.
Wahrscheinliche Ursache: Broker nicht erreichbar oder Publisher hängt.
Runbook: docs/runbooks/outbox-stuck.md
Alerts sollten fachlich priorisiert werden. Nicht jeder technische Ausschlag ist ein Incident.
---
13. PrometheusRule für Outbox
yaml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: order-service-alerts
namespace: order-prod
labels:
team: order
spec:
groups:
- name: order-service.rules
rules:
- alert: OrderOutboxBacklogGrowing
expr: outbox_unpublished_events{service=class="str">"order-service"} > 100for: 15m
labels:
severity: warning
team: order
annotations:
summary: class="str">"Order Service outbox backlog is growing"
description: class="str">"More than 100 unpublished outbox events for at least 15 minutes. Check broker connectivity and publisher logs."
runbook_url: class="str">"docs/runbooks/outbox-stuck.md"
- alert: OrderServiceHighErrorRate
expr: |
sum(rate(http_server_requests_seconds_count{application=class="str">"order-service",status=~class="str">"5.."}[5m]))
/
sum(rate(http_server_requests_seconds_count{application=class="str">"order-service"}[5m]))
> 0.05for: 10m
labels:
severity: critical
team: order
annotations:
summary: class="str">"Order Service has high 5xx error rate"
description: class="str">"More than 5% of requests fail with 5xx responses for10 minutes."
runbook_url: class="str">"docs/runbooks/order-service-errors.md"
Diese Regeln sind besser als reine CPU-Alarme, weil sie näher am Serviceverhalten sind.
---
14. Dashboards: vom Management bis zum Entwickler
Ein Dashboard sollte nicht nur hübsch aussehen. Es muss Entscheidungen unterstützen.
Für den Order Service brauchen unterschiedliche Zielgruppen unterschiedliche Sichten.
Eine technische Sicht zeigt:
Vorlage / Textauszug
Request Rate
Error Rate
Request Duration
Pod Restarts
CPU und Memory
Datenbankverbindungen
Broker-Verbindungsfehler
Eine fachliche Sicht zeigt:
Vorlage / Textauszug
Bestellungen pro Minute
abgelehnte Bestellungen
Outbox Backlog
Publishing-Latenz
Billing-Verarbeitungsverzug
Eine Betriebsübersicht zeigt:
Vorlage / Textauszug
aktuelle Version
letztes Deployment
aktive Alerts
SLO-Erfüllung
Top-Fehlercodes
abhängige Systeme
Dashboards sollten nicht mit zu vielen Panels überladen werden. Ein gutes Dashboard zeigt zuerst Symptome und erlaubt dann Drilldown.
---
15. SLI, SLO und SLA
Ein SLI ist ein messbarer Indikator. Ein SLO ist ein Zielwert. Ein SLA ist eine vertragliche Zusage.
Beispiel:
Vorlage / Textauszug
SLI: Anteil erfolgreicher Order API Requests
SLO: 99,5 Prozent der Requests sind innerhalb eines Monats erfolgreich
SLA: vertragliche Zusage gegenüber Kunden oder Partnern
Für interne Plattformen arbeitet man häufig zuerst mit SLOs, nicht sofort mit harten SLAs.
Mögliche SLOs im Lab:
Vorlage / Textauszug
Order API Availability: 99,5 Prozent pro Monat
Order API Latency: 95 Prozent der Requests unter 500 ms
Outbox Freshness: 99 Prozent der Events innerhalb von 2 Minuten veröffentlicht
Billing Processing Delay: 95 Prozent der Billing Events innerhalb von 5 Minuten verarbeitet
SLOs zwingen Teams, über messbare Qualität zu sprechen. Ohne SLO ist „läuft gut“ nur ein Gefühl.
---
16. Betrieb über Infrastrukturgrenzen hinweg
Das Lab ist hybrid. Deshalb müssen nicht nur Kubernetes-Services beobachtet werden. Auch VMs, Bare-Metal-Systeme und Cloud-Ressourcen gehören in das Betriebsbild.
Für OpenShift sammeln wir:
Vorlage / Textauszug
Pod Status
Deployments
Routes
ServiceMonitors
Resource Usage
Events
Container Logs
Für VMs sammeln wir:
Vorlage / Textauszug
CPU
RAM
Disk
systemd Services
Journal Logs
Patchstatus
Prozessstatus
Für Bare Metal sammeln wir zusätzlich:
Vorlage / Textauszug
Hardware Health
RAID Status
Disk I/O
Netzwerkinterfaces
Temperatur oder Hardwarealarme
Backup-Status
Für Cloud sammeln wir:
Vorlage / Textauszug
Object Storage Fehler
Bucket-Größe
API Errors
Kostenentwicklung
IAM Fehlversuche
Managed Database Metriken
Observability darf nicht an der Clustergrenze enden.
---
17. Node Exporter für VM und Bare Metal
Node Exporter kann Linux-Systemmetriken für Prometheus bereitstellen.
Dazu gehört eine Firewall-Regel. Prometheus darf den Node Exporter erreichen, aber nicht das ganze Netzwerk.
Vorlage / Textauszug
Quelle: Monitoring Zone
Ziel: VM oder Bare-Metal-Server
Port: 9100 TCP
Zweck: Node Exporter Scraping
Auch hier gilt: Observability braucht Netzwerkfreigaben und Dokumentation.
---
18. Logging für VM-Dienste
Ein File Processing Service auf einer VM schreibt möglicherweise in journald oder in lokale Dateien. Für Enterprise-Betrieb sollte er zentral angebunden werden.
Mögliche Wege:
Vorlage / Textauszug
Promtail liest journald und sendet an Loki.
Fluent Bit liest Logdateien und sendet an ein zentrales Backend.
In Produktion wird Sampling oft niedriger gesetzt. Für Lern- und Testumgebungen kann 100 Prozent Sampling hilfreich sein, damit man alle Abläufe sieht.
OpenTelemetry ersetzt nicht automatisch gutes Logging oder gute Metriken. Es ergänzt sie.
---
20. OpenTelemetry Collector
Der Collector nimmt Telemetriedaten entgegen und leitet sie weiter.
Der Vorteil: Anwendungen müssen nicht jedes Backend direkt kennen. Sie senden an den Collector. Der Betrieb kann später das Backend ändern oder zusätzliche Exporte ergänzen.
---
21. Incident Management
Ein Incident ist eine Störung mit Auswirkung. Nicht jeder Fehler ist ein Incident. Ein einzelner 400-Fehler durch falsche Benutzereingabe ist normal. Eine dauerhaft steigende 500-Fehlerquote ist ein Incident-Kandidat.
Ein Incident-Prozess klärt:
Vorlage / Textauszug
Wie wird die Störung erkannt?
Wer übernimmt die Koordination?
Welche Teams werden informiert?
Welche Systeme sind betroffen?
Wie wird der Schaden begrenzt?
Wie wird die Ursache analysiert?
Wie wird kommuniziert?
Wie wird nachbereitet?
Ohne Incident-Prozess reagieren Teams zufällig. Manche schauen Logs, andere ändern Konfiguration, jemand startet Pods neu, aber niemand koordiniert das Gesamtbild.
---
22. Runbook: Order Service hohe Fehlerquote
Vorlage / Textauszug
Runbook: Order Service hohe 5xx-Fehlerquote
Symptom
Alert `OrderServiceHighErrorRate` ist aktiv.
Sofort prüfen
oc get pods -n order-prod -l app=order-service
oc get events -n order-prod --sort-by=.lastTimestamp | tail -50
Im Build sollte die Git-Commit-ID ins Artefakt geschrieben werden. Dadurch kann Betrieb später genau erkennen, welche Version läuft.
---
24. Fehlerbudget
Ein Fehlerbudget beschreibt, wie viel Unzuverlässigkeit innerhalb eines SLO toleriert wird. Wenn ein Service ein SLO von 99,5 Prozent hat, darf er im Monat eine bestimmte Zeit oder Fehlerquote verbrauchen.
Das Fehlerbudget hilft bei Entscheidungen:
Vorlage / Textauszug
Wenn viel Budget übrig ist, können Releases schneller erfolgen.
Wenn Budget fast verbraucht ist, müssen Stabilität und Fehlerbehebung Vorrang haben.
Das ist besonders wichtig, wenn Entwicklung und Betrieb unterschiedliche Ziele haben. Entwicklung möchte Features liefern. Betrieb möchte Stabilität. Fehlerbudget verbindet beide Sichtweisen über messbare Qualität.
---
25. Capacity Management
Betrieb bedeutet nicht nur Störungen beheben. Betrieb bedeutet auch vorausplanen.
Capacity Management fragt:
Vorlage / Textauszug
Reichen CPU und Memory für den nächsten Monat?
Wächst die Datenbank schneller als erwartet?
Steigt die Outbox-Latenz bei Last?
Wann wird Storage knapp?
Wie viele Kafka Partitionen werden gebraucht?
Wie viele Pods braucht der Billing Service bei Monatsabschluss?
Für das Lab kann man Lastprofile definieren:
Vorlage / Textauszug
Normalbetrieb: 20 Bestellungen pro Minute
Kampagne: 200 Bestellungen pro Minute
Monatsabschluss: hohe Billing-Last
Partnerimport: große Datei nachts um 02:00
Diese Profile helfen, Tests und Alerts realistisch zu gestalten.
---
26. Lasttest als Betriebsartefakt
Ein Lasttest ist nicht nur Entwicklung. Er ist ein Betriebsartefakt, weil er zeigt, wie sich das System unter Druck verhält.
Logeintrag mit verarbeiteter Datensatzanzahl prüfen
Dashboard für Laufzeit und Erfolg prüfen
Batchbetrieb braucht genauso klare Runbooks wie APIs.
---
29. Postmortem statt Schuldsuche
Nach einem Incident sollte ein Postmortem erstellt werden. Das Ziel ist Lernen, nicht Schuldzuweisung.
Ein gutes Postmortem enthält:
Vorlage / Textauszug
Was ist passiert?
Wann begann die Störung?
Wie wurde sie erkannt?
Welche Kunden oder Systeme waren betroffen?
Was war die technische Ursache?
Was hat gut funktioniert?
Was hat nicht funktioniert?
Welche Maßnahmen verhindern Wiederholung?
Welche Alerts oder Runbooks müssen verbessert werden?
Wichtig ist, konkrete Verbesserungen abzuleiten. Ein Postmortem ohne Maßnahmen ist nur ein Bericht.
---
30. Beispiel-Postmortem Kurzfassung
Vorlage / Textauszug
Postmortem: Outbox Backlog im Order Service
Zusammenfassung
Am 2026-07-05 stieg der Outbox Backlog im Order Service über 45 Minuten kontinuierlich an. Bestellungen wurden gespeichert, aber Billing erhielt Events verzögert.
Auswirkung
Kunden konnten Bestellungen erstellen. Rechnungsinformationen wurden verzögert angezeigt.
Ursache
Eine neue NetworkPolicy erlaubte dem Order Service den Zugriff auf PostgreSQL, aber nicht mehr auf Kafka.
Erkennung
Der Alert `OrderOutboxBacklogGrowing` wurde nach 15 Minuten ausgelöst.
Was gut funktioniert hat
Bestellungserstellung blieb möglich.
Outbox verhinderte Datenverlust.
Alert zeigte die Ursache schnell in Richtung Event-Verarbeitung.
Was nicht gut funktioniert hat
NetworkPolicy wurde ohne Integrationstest deployt.
Runbook enthielt keinen direkten Hinweis auf NetworkPolicy-Prüfung.
Maßnahmen
Integrationstest für Kafka-Verbindung ergänzen.
NetworkPolicy Review in Pull Request Checkliste aufnehmen.
Runbook `outbox-stuck.md` erweitern.
Dashboard um Kafka-Verbindungsstatus ergänzen.
Dieses Beispiel zeigt, dass ein technischer Fehler in Netzwerkpolicy, Deploymentprozess, Testabdeckung und Runbook sichtbar wird.
---
31. Übung: Observability-Konzept für Billing Service
Erstelle ein Observability-Konzept für den Billing Service.
Es soll enthalten:
Vorlage / Textauszug
Welche Logs braucht der Service?
Welche technischen Metriken braucht er?
Welche fachlichen Metriken braucht er?
Welche Traces sind wichtig?
Welche Alerts sind sinnvoll?
Welche Dashboards braucht Betrieb?
Welche Runbooks müssen existieren?
Welche Abhängigkeiten müssen überwacht werden?
Denke daran: Billing ist eventgetrieben. Es reicht nicht, HTTP Requests zu betrachten. Der Service muss Broker, Event-Lag, Idempotenz, Datenbank und fachliche Rechnungsverarbeitung sichtbar machen.
---
32. Musterlösung zur Übung
Eine mögliche Lösung:
Vorlage / Textauszug
Der Billing Service schreibt strukturierte JSON Logs mit traceId, eventId, orderId, invoiceId, eventType und processingResult.
Technische Metriken sind JVM Memory, CPU, Pod Restarts, Datenbank Connection Pool, Kafka Consumer Lag und Fehlerquote beim Speichern von Rechnungen.
Fachliche Metriken sind erzeugte Rechnungen, abgelehnte Events, doppelt erkannte Events, fehlgeschlagene Rechnungserstellung und durchschnittliche Zeit zwischen OrderCreatedEvent und InvoiceCreated.
Traces sollen den Weg vom konsumierten Event bis zur gespeicherten Rechnung zeigen. Die traceId aus dem Event Header wird übernommen.
Sinnvolle Alerts sind Consumer Lag zu hoch, Billing Error Rate zu hoch, Datenbank nicht erreichbar, doppelte Events steigen stark und keine Events verarbeitet trotz eingehender Bestellungen.
Dashboards zeigen Event Throughput, Lag, Fehlerquote, Rechnungen pro Zeitraum, p95 Verarbeitungsdauer und aktuelle Version.
Runbooks braucht es für Broker nicht erreichbar, Consumer Lag, Datenbankfehler, fehlerhafte Event Payload und Rollback nach fehlerhaftem Deployment.
Diese Lösung zeigt den Unterschied zwischen API-Monitoring und Event-Monitoring.
---
33. Merksätze
Vorlage / Textauszug
Observability ist Teil der Architektur, nicht Nacharbeit.
Logs erzählen, was passiert ist. Metriken zeigen Trends. Traces verbinden Schritte.
Ein Service ist nicht gesund, nur weil der Prozess läuft.
Fachliche Metriken sind oft wichtiger als CPU und RAM.
Ein Alert ohne Runbook erzeugt Stress statt Betriebssicherheit.
Observability muss Cloud, OpenShift, VM und Bare Metal gemeinsam betrachten.
Postmortems dienen dem Lernen, nicht der Schuldzuweisung.
Backup, Restore und Disaster Recovery
Backup- und Restore-Kette
Kompakte Themenübersicht
1. Warum Backup nicht erst am Ende geplant wird
Backup wird in vielen Projekten zu spät betrachtet. Eine Anwendung wird entwickelt, deployt, überwacht und erst danach fragt jemand, wie die Daten wiederhergestellt werden können. In einem Enterprise-Projekt ist das falsch. Backup, Restore und Disaster Recovery gehören von Anfang an zur Architektur.
Der Grund ist einfach: Eine Plattform ist nur so belastbar wie ihre Wiederherstellung. Es reicht nicht, dass ein Service heute läuft. Entscheidend ist, ob er nach einem Fehlerzustand wieder kontrolliert in einen brauchbaren Zustand gebracht werden kann.
Fehler können sehr unterschiedlich sein:
Vorlage / Textauszug
Ein Pod stürzt ab.
Eine Datenbanktabelle wird versehentlich gelöscht.
Ein Deployment enthält einen schweren Fehler.
Ein Secret wurde falsch rotiert.
Ein Storage Volume ist beschädigt.
Ein Rechenzentrum fällt aus.
Ein Cloud-Bucket wurde falsch konfiguriert.
Ein Ransomware-Angriff verändert Daten.
Ein Batchjob verarbeitet fehlerhafte Partnerdateien.
Nicht jeder Fehler braucht dieselbe Antwort. Ein Pod-Neustart ist kein Disaster Recovery. Eine versehentlich gelöschte Datenbank ist ein Restore-Fall. Der Ausfall eines Standorts ist ein Disaster-Recovery-Fall. Eine fehlerhafte fachliche Verarbeitung kann wiederum einen fachlichen Korrekturprozess brauchen, nicht nur ein technisches Backup.
Deshalb trennt dieses Kapitel drei Begriffe:
Vorlage / Textauszug
Backup: Daten oder Konfigurationen werden regelmäßig gesichert.
Restore: eine Sicherung wird zurückgespielt.
Disaster Recovery: ein größerer Ausfall wird nach vorbereitetem Plan bewältigt.
Eine moderne Hybrid-Plattform braucht alle drei Ebenen.
---
2. RPO und RTO
RPO/RTO verstehen
Kompakte Lernhilfe
Zwei Begriffe sind für Backup und Disaster Recovery besonders wichtig.
RPO bedeutet Recovery Point Objective. Es beschreibt, wie viel Datenverlust maximal akzeptiert wird.
RTO bedeutet Recovery Time Objective. Es beschreibt, wie lange die Wiederherstellung maximal dauern darf.
Beispiel:
Vorlage / Textauszug
RPO: 15 Minuten
RTO: 2 Stunden
Das bedeutet: Im Fehlerfall darf das Unternehmen höchstens Daten aus den letzten 15 Minuten verlieren, und der Dienst soll innerhalb von zwei Stunden wieder nutzbar sein.
Diese Werte sind keine technischen Spielereien. Sie sind Geschäftsentscheidungen. Ein Customer Portal darf vielleicht 30 Minuten ausfallen. Eine Zahlungsabrechnung darf eventuell länger pausieren, darf aber keine Daten verlieren. Ein Reporting-System kann vielleicht einen Tag später wiederhergestellt werden. Ein Identity-System wie Keycloak ist kritischer, weil ohne Login viele andere Systeme nicht nutzbar sind.
Für das Lab definieren wir beispielhaft:
Vorlage / Textauszug
Customer Portal:
RPO: nicht relevant für statisches Frontend
RTO: 1 Stunde
Order Service Datenbank:
RPO: 15 Minuten
RTO: 2 Stunden
Billing Service Datenbank:
RPO: 15 Minuten
RTO: 4 Stunden
Reporting Daten:
RPO: 24 Stunden
RTO: 24 Stunden
Keycloak:
RPO: 1 Stunde
RTO: 2 Stunden
Object Storage Partnerdateien:
RPO: 0 bis 1 Stunde je nach Versionierung
RTO: 4 Stunden
Diese Werte sind nur Beispiele. Wichtig ist die Denkweise: Nicht alle Systeme bekommen automatisch dieselben Ziele.
---
3. Was überhaupt gesichert werden muss
Backup bedeutet nicht nur Datenbankdump. In einer Hybrid-Plattform gibt es viele sicherungswürdige Artefakte.
Gesichert werden müssen unter anderem:
Vorlage / Textauszug
Datenbanken
Object Storage Buckets
Persistent Volumes
Git-Repositories
Kubernetes/OpenShift Manifeste
Secrets oder Secret-Referenzen
Keycloak Realms und Clients
CI/CD-Konfigurationen
Argo-CD-Anwendungen
VM-Konfigurationen
Bare-Metal-Konfigurationen
Zertifikate und CA-Informationen
Runbooks und ADRs
Monitoring Dashboards
Alerting-Regeln
Dabei ist wichtig: Nicht alles wird gleich gesichert. Git-Repositories enthalten deklarative Plattformdefinitionen. Sie werden über Git selbst gesichert. Datenbanken brauchen konsistente Datenbanksicherungen. Object Storage braucht Versionierung, Replikation oder Snapshots. Kubernetes-Secrets dürfen nicht einfach unverschlüsselt exportiert werden.
Ein häufiger Fehler ist, nur die Datenbank zu sichern und die Plattformdefinitionen zu vergessen. Dann hat man zwar Daten, aber keine saubere Möglichkeit, die Umgebung wieder aufzubauen.
Ein anderer Fehler ist, nur Kubernetes-Ressourcen zu exportieren und zu glauben, damit sei die Anwendung vollständig gesichert. Persistent Volumes, externe Datenbanken und Cloud-Ressourcen fehlen dann oft.
---
4. Backup-Strategie für PostgreSQL
PostgreSQL ist im Lab zentral. Order Service und Billing Service verwenden eigene Datenbanken. Reporting kann Daten aus beiden Bereichen lesen oder eigene Kopien verwenden.
Für produktionsnahe PostgreSQL-Systeme reicht ein gelegentlicher Dump nicht aus. Eine bessere Strategie kombiniert:
Vorlage / Textauszug
regelmäßige Full Backups
WAL-Archivierung
Restore-Tests
Monitoring der Backup-Jobs
getrennte Backup-Aufbewahrung
Dokumentation der Wiederherstellung
WAL steht für Write-Ahead Log. Über WAL-Archivierung kann PostgreSQL Änderungen zwischen Full Backups nachvollziehen. Dadurch wird Point-in-Time-Recovery möglich.
Point-in-Time-Recovery bedeutet: Die Datenbank kann auf einen bestimmten Zeitpunkt zurückgesetzt werden, zum Beispiel kurz vor einer fehlerhaften Migration.
Ein einfaches Backup-Konzept für Orders könnte so aussehen:
Vorlage / Textauszug
Täglich 02:00: Full Backup
Fortlaufend: WAL-Archivierung alle 5 Minuten oder kontinuierlich
Aufbewahrung: 14 Tage tägliche Backups, 3 Monate Wochenbackups
Restore-Test: monatlich in isolierter Umgebung
Monitoring: Alert bei fehlgeschlagenem Backup
Wichtig: Ein Backup, das nie zurückgespielt wurde, ist nur eine Hoffnung.
---
5. Beispiel: PostgreSQL Backup-Skript
Für ein Lab kann ein einfaches Skript genutzt werden. In Produktion würde man häufig spezialisierte Werkzeuge verwenden, aber das Prinzip bleibt gleich.
Dieses Skript erzeugt einen komprimierten Dump im Custom-Format und zusätzlich eine Prüfsumme. Die Prüfsumme hilft zu erkennen, ob die Datei später beschädigt wurde.
Für Enterprise-Betrieb fehlen hier noch Dinge wie Secret Handling, zentrale Logs, Aufbewahrungsregeln, Upload in ein Backup-Repository und Monitoring. Trotzdem zeigt das Beispiel die Grundlage.
---
6. Restore ist wichtiger als Backup
Viele Teams können ein Backup erzeugen. Weniger Teams können zuverlässig wiederherstellen.
Restore muss geübt werden. Ein Restore-Test beantwortet Fragen wie:
Vorlage / Textauszug
Ist die Backup-Datei lesbar?
Ist die PostgreSQL-Version kompatibel?
Sind Rollen und Berechtigungen vorhanden?
Sind Extensions installiert?
Sind Secrets verfügbar?
Wie lange dauert der Restore?
Welche Anwendung muss gestoppt werden?
Wie wird geprüft, ob die Daten korrekt sind?
Ein Restore-Test sollte nicht auf Produktion durchgeführt werden. Er läuft in einer isolierten Umgebung, zum Beispiel in einem Test-Namespace oder auf einer separaten VM.
---
7. Beispiel: PostgreSQL Restore in Testumgebung
bash
#!/usr/bin/env bash
set -euo pipefail
BACKUP_FILE=class="str">"$1"
TARGET_DB=class="str">"orders_restore_test"
if [[ ! -f class="str">"${BACKUP_FILE}" ]]; then
echo class="str">"Backup file not found: ${BACKUP_FILE}" >&2
exit 1
fi
createdb class="str">"${TARGET_DB}" || true
pg_restore \
--clean \
--if-exists \
--no-owner \
--dbname=class="str">"${TARGET_DB}" \
class="str">"${BACKUP_FILE}"
psql class="str">"${TARGET_DB}" -c class="str">"SELECT count(*) AS orders_count FROM orders;"
psql class="str">"${TARGET_DB}" -c class="str">"SELECT count(*) AS outbox_count FROM outbox_events;"
Nach dem Restore reicht es nicht, dass der Befehl erfolgreich war. Es müssen fachliche Prüfungen erfolgen. Zum Beispiel: Anzahl der Bestellungen, Statusverteilung, offene Outbox Events und Datenkonsistenz zwischen Orders und Order Items.
---
8. Persistent Volumes in OpenShift
OpenShift-Anwendungen können Persistent Volumes verwenden. Dabei muss man verstehen, was gesichert wird.
Ein Deployment selbst ist deklarativ und liegt idealerweise in Git. Ein Persistent Volume enthält Laufzeitdaten. Wenn diese Daten wichtig sind, braucht das Volume eine Backup-Strategie.
Beispiele für persistente Daten im Cluster:
Vorlage / Textauszug
hochgeladene Dateien
temporäre Verarbeitungsstände
lokale Datenbanken in Lab-Umgebungen
Queue-Daten bei bestimmten Broker-Setups
Konfigurationsdaten einzelner Plattformdienste
In produktionsnahen Architekturen sollte man kritisch prüfen, ob wichtige Daten wirklich nur in einem Kubernetes-Volume liegen sollen. Häufig ist eine externe Datenbank oder Object Storage besser geeignet.
Wenn Persistent Volumes verwendet werden, muss klar sein:
Vorlage / Textauszug
Welcher StorageClass gehört das Volume an?
Gibt es Snapshots?
Wie lange werden Snapshots gehalten?
Kann ein Snapshot in einem anderen Namespace wiederhergestellt werden?
Ist das Volume ReadWriteOnce oder ReadWriteMany?
Was passiert bei Node-Ausfall?
---
9. VolumeSnapshot Beispiel
Wenn der Cluster VolumeSnapshots unterstützt, kann ein Snapshot so aussehen:
Ein Snapshot ist aber kein vollständiges Backup-Konzept. Er liegt oft im selben Storage-System. Wenn dieses Storage-System ausfällt, ist auch der Snapshot betroffen. Für Disaster Recovery braucht man zusätzliche Kopien oder Replikation in eine andere Zone oder einen anderen Standort.
---
10. Object Storage und Versionierung
Object Storage eignet sich sehr gut für Partnerdateien, Exporte, Reports und Backup-Artefakte. Im Lab kann Object Storage durch Cloud-S3 oder MinIO bereitgestellt werden.
Für wichtige Buckets sollten folgende Funktionen geprüft werden:
Vorlage / Textauszug
Versionierung
Server-side Encryption
Lifecycle-Regeln
Object Lock oder Retention
Zugriffsprotokollierung
Replikation
separate technische Benutzer
Versionierung schützt vor versehentlichem Überschreiben. Lifecycle-Regeln verschieben alte Objekte in günstigere Speicherklassen oder löschen temporäre Dateien nach definierter Zeit. Object Lock kann vor absichtlichem oder versehentlichem Löschen schützen, ist aber organisatorisch sorgfältig zu planen.
Beispiel für Bucket-Regeln:
Vorlage / Textauszug
incoming-partner-files:
Versionierung: aktiv
Retention: 30 Tage
Lifecycle: nach 90 Tagen archivieren
Zugriff: nur File Processing und Integration Team
Logging: aktiv
processed-partner-files:
Versionierung: aktiv
Retention: 180 Tage
Lifecycle: nach 365 Tagen löschen oder archivieren
Zugriff: Reporting und File Processing
backup-artifacts:
Versionierung: aktiv
Object Lock: aktiv
Retention: 90 Tage unveränderbar
Zugriff: Backup-System, kein normaler App-Zugriff
---
11. Beispiel: MinIO Client für Backup-Kopie
bash
#!/usr/bin/env bash
set -euo pipefail
BACKUP_FILE=class="str">"$1"
BUCKET=class="str">"backup-artifacts/postgresql/orders"
ALIAS=class="str">"labminio"
if [[ ! -f class="str">"${BACKUP_FILE}" ]]; then
echo class="str">"Backup file not found: ${BACKUP_FILE}" >&2
exit 1
fi
mc cp class="str">"${BACKUP_FILE}" class="str">"${ALIAS}/${BUCKET}/"
mc cp class="str">"${BACKUP_FILE}.sha256" class="str">"${ALIAS}/${BUCKET}/"
mc ls class="str">"${ALIAS}/${BUCKET}/"
Die Kopie in Object Storage ist nützlich, weil sie Backup-Dateien von der Datenbankmaschine trennt. Wenn die Datenbankmaschine verloren geht, liegt das Backup nicht nur lokal auf demselben System.
---
12. Keycloak Backup
Keycloak ist kritisch, weil viele Anwendungen von Login und Token-Ausstellung abhängen. Ohne Keycloak funktionieren Customer Portal, Admin Portal und API-Zugriffe nicht korrekt.
Bei Keycloak müssen zwei Dinge betrachtet werden:
Vorlage / Textauszug
Keycloak-Datenbank
Realm-Konfiguration
Wenn Keycloak eine PostgreSQL-Datenbank verwendet, wird diese wie andere PostgreSQL-Datenbanken gesichert. Zusätzlich kann die Realm-Konfiguration exportiert werden, damit Clients, Rollen, Gruppen und Mappings nachvollziehbar bleiben.
Ein Realm-Export ist kein Ersatz für ein konsistentes Datenbankbackup, aber ein wichtiger zusätzlicher Nachweis.
In einem GitOps-orientierten Projekt sollten Keycloak-Clients und Rollen möglichst deklarativ beschrieben werden. Dann ist ein Realm nicht nur ein Zustand in einer Oberfläche, sondern Teil der Plattformdefinition.
---
13. Git als Wiederherstellungsquelle
Git ist nicht nur für Anwendungscode wichtig. Git enthält im Zielbild auch:
Vorlage / Textauszug
Kubernetes-Manifeste
Helm-Werte
Kustomize-Overlays
Argo-CD-Anwendungen
ADRs
Runbooks
CI/CD-Pipelines
Dokumentation
Security Policies
Wenn ein Cluster neu aufgebaut werden muss, ist Git die wichtigste Quelle für den gewünschten Zustand.
Aber Git allein reicht nicht. Git enthält nicht automatisch Datenbanken, Object Storage Inhalte oder dynamische Secrets. Deshalb muss klar getrennt werden:
Vorlage / Textauszug
Git stellt Struktur und gewünschte Konfiguration wieder her.
Backups stellen Daten wieder her.
Secret Management stellt sensible Werte kontrolliert wieder bereit.
Ein Disaster-Recovery-Plan muss alle drei Ebenen verbinden.
---
14. Argo CD und GitOps Recovery
Mit Argo CD kann ein Cluster nach einem Ausfall teilweise wieder aufgebaut werden, wenn die Plattformdefinitionen in Git liegen.
Ablauf:
Vorlage / Textauszug
Neuer Cluster oder neuer Namespace wird bereitgestellt.
Argo CD wird installiert.
Argo-CD-Applications werden aus Git geladen.
Namespaces, Deployments, Services, Routes und Policies werden synchronisiert.
Secrets werden über External Secrets oder Vault eingebunden.
Daten werden aus Backups wiederhergestellt.
Anwendungen werden schrittweise aktiviert.
Das ist wesentlich kontrollierter als manuelle Wiederherstellung per Copy-and-Paste.
Für Recovery ist wichtig, prune vorsichtig zu verwenden. In einer Störung will man nicht versehentlich Ressourcen löschen, die noch analysiert werden müssen.
---
15. Disaster-Recovery-Szenarien
DR-Wiederanlauf kompakt
Kompakte Lernhilfe
Disaster Recovery beginnt mit Szenarien. Ohne Szenarien bleibt DR abstrakt.
Für das Lab definieren wir fünf Szenarien.
Szenario 1: Einzelner Pod fällt aus
Das ist kein DR-Fall. Kubernetes oder OpenShift startet den Pod neu. Wichtig sind Liveness, Readiness und ausreichende Replikas.
Szenario 2: Namespace wurde fehlerhaft verändert
Hier helfen GitOps, Rollback und gezielte Wiederherstellung von Ressourcen. Daten müssen meist nicht aus Backup wiederhergestellt werden.
Szenario 3: Datenbank wurde beschädigt
Das ist ein Restore-Fall. Man benötigt Datenbankbackup, WAL-Archivierung, Restore-Prozess und fachliche Validierung.
Szenario 4: OpenShift Cluster ist verloren
Das ist ein großer Plattform-Recovery-Fall. Man braucht Cluster-Bootstrap, GitOps-Konfiguration, Secret-Wiederherstellung, Storage-Strategie und Datenbank-/Object-Storage-Zugriff.
Szenario 5: Standort oder Cloud-Region fällt aus
Das ist Disaster Recovery im engeren Sinn. Man braucht alternative Infrastruktur, replizierte Daten, DNS-Umschaltung, klare Prioritäten und Kommunikationsplan.
---
16. Priorisierung im Wiederanlauf
Nach einem größeren Ausfall darf nicht alles gleichzeitig gestartet werden. Es braucht eine Reihenfolge.
Kernservices starten: Order Service, Billing Service
Portale starten: Customer Portal, Admin Portal
Reporting und File Processing aktivieren
fachliche Validierung durchführen
externe Kommunikation freigeben
Diese Reihenfolge ist wichtig. Ein Customer Portal ohne Identity und APIs bringt wenig. Ein Billing Service ohne Datenbank und Broker kann nicht korrekt arbeiten. Monitoring sollte früh verfügbar sein, damit der Wiederanlauf beobachtet werden kann.
---
17. Beispiel: DR-Runbook für Order Platform
Vorlage / Textauszug
Runbook: Disaster Recovery für Order Platform
Ziel
Wiederherstellung der Order Platform nach schwerem Plattformausfall.
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: backup-alerts
namespace: platform-monitoring
spec:
groups:
- name: backup.rules
rules:
- alert: BackupMissing
expr: time() - backup_last_success_timestamp{system=class="str">"orders-db"} > 90000for: 15m
labels:
severity: critical
annotations:
summary: class="str">"No recent backup for orders-db"
description: class="str">"The last successful backup for orders-db is older than 25 hours."
Dieser Alert ist konkreter als ein allgemeiner Systemalarm. Er beantwortet direkt: Welches Backup fehlt?
---
19. Restore-Validierung
Nach einem Restore braucht man technische und fachliche Prüfungen.
Technische Prüfungen:
Vorlage / Textauszug
Datenbank startet
Schemas vorhanden
Tabellen vorhanden
Indizes vorhanden
Migrationstabelle konsistent
Anwendung verbindet sich erfolgreich
Health Checks grün
Fachliche Prüfungen:
Vorlage / Textauszug
Bestellungen haben plausible Statuswerte
keine Order Items ohne Order
keine negativen Rechnungsbeträge
Outbox Events sind nicht doppelt veröffentlicht
Billing-Status passt zu Order-Status
Reporting kann Daten lesen
Beispiel-SQL:
sql
SELECT status, count(*)
FROM orders
GROUP BY status
ORDER BY status;
SELECT count(*) AS orphan_items
FROM order_items oi
LEFT JOIN orders o ON o.id = oi.order_id
WHERE o.id IS NULL;
SELECT count(*) AS unpublished_outbox_events
FROM outbox_events
WHERE published_at IS NULL;
Diese Prüfungen zeigen, ob die Datenbank nicht nur technisch, sondern auch fachlich brauchbar ist.
---
20. Backup und Security
Backups enthalten oft sensible Daten. Deshalb müssen sie geschützt werden.
Security-Anforderungen:
Vorlage / Textauszug
Backups verschlüsseln
Zugriff stark beschränken
Backup-Zugriffe protokollieren
Backup-Repository vom normalen App-Netz trennen
Secrets nicht unkontrolliert exportieren
Restore nur in genehmigten Umgebungen erlauben
Testdaten anonymisieren, wenn nötig
Ein gefährlicher Fehler ist, Produktionsbackups unverschlüsselt in Testumgebungen zu kopieren. Dadurch entstehen Datenschutz- und Sicherheitsprobleme.
Für das Lab gilt: Restore-Tests dürfen fachlich realistisch sein, aber sensible Daten müssen geschützt oder anonymisiert werden.
---
21. Fachliche Wiederherstellung statt nur technischer Restore
Nicht jeder Fehler lässt sich mit einem technischen Restore lösen.
Beispiel: Ein fehlerhafter Billing-Job hat falsche Rechnungsentwürfe erzeugt. Ein kompletter Datenbank-Restore würde vielleicht auch gültige Bestellungen und andere Änderungen zurückdrehen. Das kann schlimmer sein als der ursprüngliche Fehler.
In solchen Fällen braucht man fachliche Korrekturprozesse:
Vorlage / Textauszug
fehlerhafte Datensätze identifizieren
Korrekturstatus setzen
Gutschriften oder Storno erzeugen
Events zur Korrektur veröffentlichen
Audit Trail erhalten
Kundenkommunikation vorbereiten
Deshalb müssen Anwendungen so gebaut werden, dass sie Korrekturen erlauben. Audit Logging, Statusmodelle und Idempotenz sind dafür wichtig.
---
22. Beispiel: Korrekturjob für fehlerhafte Rechnungen
Dieses Beispiel zeigt: Fachliche Fehler werden nicht immer durch Restore gelöst. Manchmal ist eine kontrollierte Korrektur besser.
---
23. DR-Test als Übung
Ein Disaster-Recovery-Plan ist nur glaubwürdig, wenn er getestet wird. Ein Test muss nicht immer den ganzen Standortausfall simulieren. Es kann auch ein Teiltest sein.
Beispiele:
Vorlage / Textauszug
Restore einer PostgreSQL-Datenbank in Testumgebung
Wiederaufbau eines Namespace aus GitOps
Wiederherstellung eines Keycloak-Realm-Exports
Restore eines Object-Storage-Objekts aus Versionierung
Umschaltung einer Test-DNS-Zone
Start eines Services mit neu erzeugten Secrets
Nach jedem Test wird dokumentiert:
Vorlage / Textauszug
Was wurde getestet?
Wie lange hat es gedauert?
Welche Probleme traten auf?
Wurde RTO eingehalten?
Wurde RPO eingehalten?
Welche Runbook-Schritte waren unklar?
Welche Automatisierung fehlt?
---
24. Übung: Backup-Konzept für das Lab erstellen
Erstelle ein Backup- und Restore-Konzept für folgende Komponenten:
Vorlage / Textauszug
Order Service Datenbank
Billing Service Datenbank
Keycloak
Object Storage für Partnerdateien
GitOps Repository
OpenShift Manifeste
Reporting Exportdaten
Beschreibe je Komponente:
Vorlage / Textauszug
Was wird gesichert?
Wie oft wird gesichert?
Wo wird es gespeichert?
Wie wird Restore getestet?
Welches RPO gilt?
Welches RTO gilt?
Welche Security-Regeln gelten?
---
25. Musterlösung zur Übung
Eine mögliche Lösung:
Vorlage / Textauszug
Order Service Datenbank:
Tägliches Full Backup und kontinuierliche WAL-Archivierung. Speicherung im getrennten Backup-Repository und zusätzlich in Object Storage mit Versionierung. RPO 15 Minuten, RTO 2 Stunden. Monatlicher Restore-Test.
Billing Service Datenbank:
Tägliches Full Backup und WAL-Archivierung. RPO 15 Minuten, RTO 4 Stunden. Vor Restore wird geprüft, ob fachliche Korrektur statt vollständigem Restore sinnvoller ist.
Keycloak:
PostgreSQL-Backup plus regelmäßiger Realm-Export. RPO 1 Stunde, RTO 2 Stunden. Restore-Test prüft Login, Token-Ausstellung und Client-Konfiguration.
Object Storage Partnerdateien:
Versionierung, Lifecycle-Regeln und Replikation. RPO abhängig von Replikation, Ziel maximal 1 Stunde. Restore-Test über Wiederherstellung einer gelöschten Testdatei.
GitOps Repository:
Git-Server-Backup und Spiegelung in zweites Repository. RPO 1 Stunde, RTO 4 Stunden. Restore-Test durch Klonen und Argo-CD-Synchronisation in Testcluster.
OpenShift Manifeste:
Primär in Git gesichert. Clusterzustand wird nicht als alleinige Wahrheit betrachtet. Restore erfolgt über GitOps.
Reporting Exportdaten:
Ablage in Object Storage mit Lifecycle. RPO 24 Stunden, RTO 24 Stunden. Kritische Reports können neu erzeugt werden, wenn Quelldaten vorhanden sind.
Diese Lösung zeigt, dass Backup nicht überall gleich ist. Jede Komponente bekommt eine passende Strategie.
---
26. Merksätze
Vorlage / Textauszug
Ein Backup ist wertlos, wenn niemand den Restore beherrscht.
Git stellt gewünschte Konfiguration wieder her, aber keine Daten.
Object Storage Versionierung schützt vor versehentlichem Überschreiben, ersetzt aber kein vollständiges DR-Konzept.
Nicht jeder fachliche Fehler sollte mit Datenbank-Restore gelöst werden.
Disaster Recovery ist ein geübter Ablauf, kein Dokument für den Notfallordner.
Resilienz, Lasttests und Produktionsreife
Resilienzpfad unter Last
Kompakte Themenübersicht
1. Warum Produktionsreife mehr ist als ein erfolgreicher Test
Ein Service ist nicht produktionsreif, nur weil er lokal startet, einen Controller-Test besteht und in OpenShift ein grünes Pod-Symbol zeigt. Produktionsreife beginnt dort, wo das System unter Last, bei Störungen, bei langsamen Abhängigkeiten und bei unvollständigen Daten trotzdem kontrolliert reagiert. In einem Hybrid-Enterprise-Lab ist diese Frage besonders wichtig, weil moderne Services auf OpenShift mit Datenbanken auf Bare Metal, Messaging-Systemen, VM-basierten Reporting-Prozessen, Cloud-Object-Storage und Identity-Komponenten zusammenspielen.
Produktionsreife bedeutet deshalb nicht Perfektion. Produktionsreife bedeutet, dass bekannte Fehlerbilder erwartet, begrenzt, überwacht und geübt werden. Ein Order Service darf ausfallen können, ohne dass Billing dauerhaft inkonsistent wird. Eine Datenbank darf kurzzeitig langsam sein, ohne dass alle Web-Threads blockieren. Ein Broker darf Events verzögert ausliefern, ohne dass Bestellungen doppelt fakturiert werden. Ein Cloud-Bucket darf höhere Latenz zeigen, ohne dass der File Processing Worker endlos unkontrolliert neue Prozesse startet.
Im Lab wird Produktionsreife über konkrete Nachweise sichtbar gemacht. Dazu gehören Lasttests, Timeout-Strategien, Retry-Regeln, Circuit Breaker, Rate Limits, Backpressure, Health Checks, Dashboards, Alerts, Runbooks und Go-Live-Checklisten. Diese Artefakte sind kein Zusatz am Ende. Sie gehören direkt in den Entwicklungs- und Plattformprozess.
Resilienz bedeutet, dass ein System bei Problemen nicht unkontrolliert zusammenbricht. Das heißt aber nicht, dass jeder Service alle Fehler selbst verstecken soll. Ein resilienter Service unterscheidet zwischen kurzfristigen technischen Fehlern, dauerhaften fachlichen Fehlern und gefährlichen Zuständen, bei denen ein schneller Abbruch besser ist als endloses Weiterprobieren.
Ein Beispiel: Wenn der Billing Service ein Event empfängt und die Billing-Datenbank für wenige Sekunden nicht erreichbar ist, kann ein Retry sinnvoll sein. Wenn das Event aber fachlich ungültig ist, weil eine Pflichtinformation fehlt, darf kein endloser Retry erfolgen. Das Event muss in eine Dead Letter Queue oder in einen manuellen Klärungsprozess. Wenn die Datenbank seit zehn Minuten nicht erreichbar ist, helfen schnelle Wiederholungen ebenfalls nicht. Dann muss das System die Last reduzieren, Alarme auslösen und den Betrieb informieren.
In der Architektur werden deshalb folgende Regeln festgelegt:
Vorlage / Textauszug
Kurzfristiger technischer Fehler: begrenzter Retry mit Wartezeit.
Fachlicher Fehler: kein technischer Retry, sondern fachliche Fehlerablage.
Längerer Ausfall: Circuit Breaker öffnet, Alerts werden ausgelöst.
Überlast: Rate Limit oder Backpressure schützt nachgelagerte Systeme.
Diese Regeln verhindern, dass ein kleiner Fehler zum Plattformproblem wird.
3. Timeout-Strategie für synchrone APIs
Timeout-Kette
Kompakte Lernhilfe
Synchronous APIs sind angenehm, weil der Aufrufer sofort eine Antwort bekommt. Sie sind aber gefährlich, wenn Timeouts nicht sauber definiert sind. Ohne Timeout kann ein Thread lange blockieren. Viele blockierte Threads führen zu erschöpften Connection Pools, langsamen Pods, fehlgeschlagenen Readiness Probes und letztlich zu Kaskadeneffekten.
Für das Lab gilt: Jeder externe HTTP-Aufruf braucht einen klaren Timeout. Dazu gehören Verbindungsaufbau, Antwortzeit und Gesamtzeit. Der Timeout muss kürzer sein als die Zeit, nach der der Aufrufer selbst abbrechen würde. Sonst wartet die obere Schicht länger als sinnvoll und blockiert Ressourcen.
Beispiel für einen Spring Boot HTTP Client mit klaren Timeouts:
Dieser Code zeigt nicht nur Technik. Er zeigt eine Betriebsentscheidung: Der Order Service wartet nicht endlos auf die Customer API. Wenn die Abhängigkeit zu langsam ist, wird der Fehler sichtbar und kontrollierbar.
4. Retry ist kein Allheilmittel
Retries werden oft falsch eingesetzt. Ein Retry kann einen kurzen Netzwerkfehler überbrücken. Er kann aber auch eine Störung verschlimmern. Wenn ein abhängiges System bereits überlastet ist und alle Clients sofort wiederholen, steigt die Last weiter. Dann entsteht ein Retry Storm.
Ein sinnvoller Retry hat deshalb Begrenzungen:
Vorlage / Textauszug
maximale Anzahl an Versuchen
Wartezeit zwischen Versuchen
exponentieller Backoff
Jitter gegen gleichzeitige Wiederholung
keine Wiederholung bei fachlichen Fehlern
Metriken pro Retry-Grund
Beispiel mit Resilience4j:
java
package com.seb4u.demo.spring.order.infrastructure.billing;
import io.github.resilience4j.retry.annotation.Retry;
import org.springframework.stereotype.Component;
@Componentpublicclass BillingReadinessClient {
privatefinal BillingApi billingApi;
public BillingReadinessClient(BillingApi billingApi) {
this.billingApi = billingApi;
}
@Retry(name = class="str">"billing-readiness", fallbackMethod = class="str">"fallback")
public BillingReadiness checkReadiness() {
return billingApi.readiness();
}
public BillingReadiness fallback(Exception ex) {
returnnew BillingReadiness(false, class="str">"Billing API not reachable: " + ex.getClass().getSimpleName());
}
}
Der wichtigste Punkt ist ignore-exceptions. Fachliche Fehler dürfen nicht wie technische Störungen behandelt werden.
5. Circuit Breaker gegen Kaskadeneffekte
Ein Circuit Breaker schützt ein System davor, eine kaputte Abhängigkeit immer wieder anzusprechen. Er funktioniert ähnlich wie ein Sicherungsautomat. Wenn zu viele Fehler auftreten, öffnet er. Dann werden weitere Aufrufe schnell abgewiesen oder über einen Fallback beantwortet. Nach einer Wartezeit prüft er vorsichtig, ob die Abhängigkeit wieder verfügbar ist.
Im Lab ist das besonders relevant für synchrone Abhängigkeiten wie Customer API, Payment Provider, externe Partner-API oder interne Legacy-VM-Dienste.
Ein Circuit Breaker darf aber nicht missverstanden werden. Er repariert die Abhängigkeit nicht. Er begrenzt Schaden. Deshalb muss jeder geöffnete Circuit Breaker in Monitoring und Alerting sichtbar sein.
6. Bulkheads: Fehlerbereiche trennen
Bulkhead bedeutet Schottwand. In Schiffen verhindern Schottwände, dass ein Leck das ganze Schiff flutet. In Software bedeutet Bulkhead: Ein langsamer Bereich soll nicht alle Ressourcen verbrauchen.
Beispiel: Der Order Service ruft eine interne Customer API, eine Promotion API und eine externe Partner API auf. Wenn alle Aufrufe denselben Threadpool verwenden, kann eine langsame Partner API alle Threads blockieren. Dann funktionieren auch interne Aufrufe nicht mehr.
Damit wird die externe Partner API begrenzt. Sie kann langsamer werden, ohne den gesamten Service zu blockieren.
7. Backpressure bei asynchroner Verarbeitung
Asynchrone Verarbeitung verschiebt Arbeit in Queues, Topics oder Outbox-Tabellen. Das macht Systeme entkoppelter, aber nicht automatisch stabil. Wenn Producer schneller schreiben als Consumer verarbeiten, wächst ein Backlog. Das ist nicht sofort ein Fehler. Es wird aber gefährlich, wenn Backlog, Speicherverbrauch, Latenz und Fehlerraten unkontrolliert steigen.
Backpressure bedeutet: Das System erkennt Überlast und reduziert den Zufluss oder verlangsamt Verarbeitung kontrolliert.
Im Lab betrifft das besonders:
Vorlage / Textauszug
Outbox Events im Order Service
Kafka Topics für Billing
Dead Letter Queues
File Processing Worker
Reporting Jobs
Object Storage Uploads
Ein Outbox Publisher darf nicht unbegrenzt viele Events gleichzeitig senden. Er braucht Batch-Größe, Polling-Intervall, Retry-Regeln und Metriken.
Die Metriken sind hier genauso wichtig wie das Publishing selbst. Ohne Metriken erkennt niemand, ob die Outbox gesund ist.
8. Rate Limiting am API Gateway
Rate Limiting begrenzt Anfragen. Es schützt nicht nur vor Angriffen, sondern auch vor Fehlkonfigurationen und fehlerhaften Clients. Ein Partner, der versehentlich eine Schleife baut, darf nicht die gesamte Plattform überlasten.
Im Zielbild kann Rate Limiting an mehreren Stellen erfolgen:
Vorlage / Textauszug
Web Application Firewall
API Gateway
OpenShift Route / Ingress Layer
Anwendung selbst
externe Partner-Schnittstelle
Ein fachliches Beispiel:
Skizze / Textauszug
Customer Portal:
normale Benutzer: 100 Requests pro Minute
Admin Portal: strengere Regeln je Rolle
Partner Upload API: größere Dateien, aber begrenzte Parallelität
Reporting Export API: wenige parallele Exporte pro Benutzer
Rate Limits müssen dokumentiert werden. Sonst wirken sie später wie zufällige Fehler.
9. Lasttest-Strategie
Lasttests sollen nicht beweisen, dass ein System unendlich viel Last trägt. Sie sollen zeigen, wo Grenzen liegen und wie sich das System vor der Grenze verhält.
Das Lab nutzt mehrere Testarten:
Skizze / Textauszug
Smoke Load Test:
kleine Last, schnelle Prüfung nach Deployment.
Baseline Load Test:
typische Tageslast.
Stress Test:
Last wird erhöht, bis Sättigung sichtbar wird.
Spike Test:
plötzliche Lastspitze.
Soak Test:
längere Laufzeit, um Speicherlecks und Backlog zu erkennen.
Failure Load Test:
Last bei gestörter Abhängigkeit.
Ein guter Lasttest betrachtet nicht nur Antwortzeiten. Er betrachtet auch CPU, RAM, Datenbankverbindungen, Broker-Lag, Outbox-Länge, Garbage Collection, Fehlerquote und Autoscaling-Verhalten.
Dieser Test ist bewusst nicht nur ein curl in Schleife. Er setzt Korrelation, prüft Antwortform und definiert Schwellenwerte.
11. Lasttest-Auswertung
Nach einem Lasttest reicht es nicht zu sagen: „Der Test war grün.“ Man muss erklären, was beobachtet wurde.
Ein sinnvoller Bericht enthält:
Vorlage / Textauszug
Testziel
Umgebung
Version der Anwendung
Testdaten
Lastprofil
p50/p95/p99 Antwortzeiten
Fehlerquote
CPU/RAM der Pods
Datenbankverbindungen
Broker Lag
Outbox Backlog
relevante Logs
auffällige Traces
Entscheidung: bestanden, bedingt bestanden oder nicht bestanden
Beispielauswertung:
Vorlage / Textauszug
Lasttest-Bericht: Order Service Baseline
Ziel
Prüfung, ob der Order Service 50 gleichzeitige Benutzer bei typischer Warenkorbgröße stabil verarbeitet.
Ergebnis
Der Test wurde technisch bestanden. p95 lag bei 420 ms, p99 bei 870 ms. Die Fehlerquote lag bei 0,3 Prozent. Die Fehler entstanden ausschließlich durch absichtlich ungültige Testdaten.
Auffälligkeiten
Während der Last stieg die Outbox-Länge kurzfristig auf 1.800 Events, wurde aber innerhalb von vier Minuten wieder abgebaut. Kafka zeigte keinen kritischen Lag. PostgreSQL erreichte maximal 68 Prozent CPU.
Entscheidung
Baseline bestanden. Für Go-Live muss zusätzlich ein Spike Test mit 200 gleichzeitigen Benutzern durchgeführt werden.
12. Autoscaling und seine Grenzen
Horizontal Pod Autoscaling kann helfen, wenn ein Service mehr Last bekommt. Es löst aber nicht jedes Problem. Wenn die Datenbank der Engpass ist, erzeugen mehr Pods mehr Datenbankverbindungen und verschlimmern das Problem. Wenn Kafka Consumer falsch partitioniert sind, bringen zusätzliche Pods eventuell keine höhere Verarbeitung. Wenn eine externe API langsam ist, erzeugen zusätzliche Pods mehr gleichzeitige externe Aufrufe.
Ein HPA muss deshalb mit Ressourcen, Connection Pools und abhängigen Systemen abgestimmt werden.
Dieses Beispiel zeigt ein Prinzip. In der Realität braucht custom metrics sorgfältige Einrichtung. Wichtig ist: Autoscaling darf nicht blind konfiguriert werden.
13. Connection Pools richtig begrenzen
Ein typischer Fehler ist ein zu großer Connection Pool. Wenn acht Pods jeweils 50 Datenbankverbindungen öffnen, entstehen 400 mögliche Verbindungen. Die Datenbank kann dadurch überlastet werden.
Für das Lab wird die maximale Verbindungszahl pro Umgebung geplant:
Diese Zahlen müssen zur Datenbank passen. Sie sind keine Dekoration.
14. Readiness ist kein allgemeiner Gesundheitstest
Readiness beantwortet die Frage: Soll dieser Pod Traffic erhalten? Liveness beantwortet die Frage: Muss dieser Pod neu gestartet werden? Diese Unterscheidung ist wichtig.
Ein häufiger Fehler ist, in der Liveness Probe externe Abhängigkeiten zu prüfen. Wenn die Datenbank kurz ausfällt, starten dann alle Pods neu. Das verschlimmert die Lage.
Besser:
Skizze / Textauszug
Liveness:
prüft, ob die Anwendung selbst noch lebt.
Readiness:
prüft, ob die Anwendung Traffic sicher verarbeiten kann.
Startup Probe:
schützt langsame Startphasen.
concurrencyPolicy: Forbid ist hier wichtig. Es verhindert, dass ein verspäteter Job parallel mit dem nächsten Lauf kollidiert.
16. Chaos-Übungen im kleinen Rahmen
Chaos Engineering bedeutet nicht, zufällig Produktion kaputt zu machen. Im Lab bedeutet es kontrollierte Störungsübungen.
Beispiele:
Vorlage / Textauszug
Billing-Datenbank für zwei Minuten nicht erreichbar
Kafka Consumer gestoppt
falsches Secret in Testumgebung
künstliche Latenz zur Partner API
Pod wird während Verarbeitung beendet
Object Storage liefert temporär Fehler
Jede Übung braucht Hypothese, Durchführung, Beobachtung und Ergebnis.
Vorlage / Textauszug
Chaos-Übung: Kafka Consumer gestoppt
Hypothese
Wenn der Billing Consumer zehn Minuten gestoppt wird, wächst der Kafka Lag, aber der Order Service bleibt verfügbar. Nach Start des Consumers wird der Lag innerhalb von 20 Minuten abgebaut.
Durchführung
Billing Deployment in Test auf 0 Replicas skalieren. Währenddessen 5.000 Bestellungen erzeugen. Danach Deployment wieder auf 3 Replicas skalieren.
Erwartete Beobachtung
Order Service liefert weiterhin 201. Kafka Lag steigt sichtbar. Billing-Dashboard zeigt verzögerte Verarbeitung. Alert wird nach fünf Minuten ausgelöst.
Ergebnis
Bestanden, wenn keine Events verloren gehen und keine Rechnung doppelt erzeugt wird.
17. Go-Live-Readiness-Check
Vor einem produktionsnahen Release braucht das Team eine klare Abnahme. Diese Abnahme darf nicht nur aus „Tests grün“ bestehen.
Go-Live-Checkliste:
Vorlage / Textauszug
Fachlich:
Kernprozess getestet
Fehlerfälle getestet
fachliche Korrekturen beschrieben
Datenmigration geprüft
Technisch:
CI Pipeline grün
Image signiert oder nachvollziehbar gebaut
Manifeste geprüft
Resource Limits gesetzt
Probes gesetzt
NetworkPolicies gesetzt
Security:
Rollen geprüft
Secrets nicht im Repository
Token-Konfiguration geprüft
Audit Logging aktiv
Betrieb:
Dashboard vorhanden
Alerts vorhanden
Runbook vorhanden
Backup/Restore geprüft
Rollback beschrieben
Last und Resilienz:
Baseline Load Test bestanden
Timeout-Strategie dokumentiert
Retry-Regeln dokumentiert
Circuit Breaker sichtbar
Outbox/DLQ überwacht
18. Produktionsreife im Quality Gate
Das Quality Gate im Pull Request prüft nicht alles automatisch. Aber es kann verhindern, dass wichtige Artefakte fehlen.
Beispiel einer Repository-Prüfung:
bash
#!/usr/bin/env bash
set -euo pipefail
required_files=(
class="str">"README.md"
class="str">"docs/adr/ADR-001-service-boundary.md"
class="str">"docs/runbooks/order-service.md"
class="str">"deploy/overlays/prod/kustomization.yaml"
class="str">"deploy/base/deployment.yaml"
class="str">"deploy/base/service.yaml"
class="str">"deploy/base/networkpolicy.yaml"
class="str">"observability/prometheus-rule.yaml"
)
for file in class="str">"${required_files[@]}"; do
if [[ ! -f class="str">"$file" ]]; then
echo class="str">"Missing required file: $file"
exit 1
fi
done
echo class="str">"Operational readiness files are present."
Diese Prüfung ersetzt keinen Review, aber sie setzt eine Mindestgrenze.
19. Runbook: Lastspitze im Customer Portal
Vorlage / Textauszug
Runbook: Lastspitze im Customer Portal
Symptom
Benutzer melden langsame Seitenladezeiten. Grafana zeigt erhöhte p95-Latenz im Customer Portal und im Order Service.
Sofort prüfen
Ist nur das Frontend betroffen oder auch APIs?
Steigt die Fehlerrate?
Sind Pods CPU- oder Memory-limitiert?
Gibt es Datenbank-Wartezeiten?
Gibt es Broker-Lag oder Outbox-Backlog?
Kommandos
oc get hpa -n portal-prod
oc get pods -n portal-prod
oc top pods -n portal-prod
oc get pods -n order-prod
oc top pods -n order-prod
Vorlage / Textauszug
Entscheidungen
Wenn nur Frontend-CPU hoch ist: HPA und CDN/Cache prüfen.
Wenn Order API langsam ist: Traces und Datenbank prüfen.
Wenn Datenbank an Grenze ist: keine blinde Pod-Erhöhung.
Wenn externe Partner API langsam ist: Circuit Breaker Status prüfen.
Eskalation
Bei Fehlerquote über 5 Prozent länger als 10 Minuten: Incident Lead aktivieren.
20. Typische Fehler bei Resilienz
Ein häufiger Fehler ist blindes Retry. Dadurch wird aus einer kurzen Störung ein Lastproblem. Ein zweiter Fehler ist fehlender Timeout. Dadurch werden Threads blockiert und Pods wirken zufällig langsam. Ein dritter Fehler ist falsche Liveness-Konfiguration. Dadurch starten Pods wegen externer Probleme neu. Ein vierter Fehler ist Autoscaling ohne Blick auf Datenbank und Broker. Ein fünfter Fehler ist fehlende Lasttest-Auswertung. Ein sechster Fehler ist ein Runbook, das nur sagt „Logs prüfen“, aber keine Entscheidungen beschreibt.
Produktionsreife entsteht nicht durch ein einzelnes Tool. Sie entsteht durch konsequente Grenzen, Messbarkeit, Übung und klare Zuständigkeiten.
21. Übung
Erstelle für den Order Service eine Produktionsreife-Abnahme. Sie soll folgende Punkte enthalten:
Vorlage / Textauszug
drei Timeouts
zwei Retry-Regeln
einen Circuit Breaker
eine Backpressure-Regel
drei Metriken
zwei Alerts
einen Lasttest
ein Runbook-Symptom
eine Go-Live-Entscheidung
22. Musterlösung
Vorlage / Textauszug
Timeouts:
Verbindung zur Customer API: 1,5 Sekunden
Antwortzeit Customer API: 3 Sekunden
Datenbankverbindung aus Pool: 2 Sekunden
Retry-Regeln:
Customer API technische Timeouts maximal 3 Versuche mit Backoff
Outbox Publishing maximal 5 Versuche, danach Fehlerstatus und Alert
Circuit Breaker:
Partner API öffnet bei 50 Prozent Fehlern in 50 Aufrufen
Backpressure:
Outbox Publisher verarbeitet maximal 100 Events pro Batch
Metriken:
outbox_events_unpublished
http_server_requests_seconds p95/p99
database_connection_pool_active
Alerts:
Outbox älter als 10 Minuten
p95 Order API über 800 ms für 5 Minuten
Lasttest:
k6 Baseline mit 50 gleichzeitigen Benutzern und p95 unter 600 ms
Runbook-Symptom:
Customer Portal langsam, Order API p95 steigt, Outbox bleibt normal
Go-Live-Entscheidung:
Freigabe nur, wenn Baseline Load Test bestanden, Alerts aktiv und Runbook reviewed sind.
23. Merksätze
Vorlage / Textauszug
Resilienz bedeutet nicht, jeden Fehler zu verstecken.
Timeouts schützen Ressourcen.
Retries brauchen Grenzen.
Circuit Breaker begrenzen Kaskadeneffekte.
Backpressure ist Pflicht bei asynchroner Verarbeitung.
Autoscaling ohne Kapazitätsplanung kann Schaden vergrößern.
Produktionsreife muss gemessen, dokumentiert und geübt werden.
Teil F: DevOps, GitOps, Release Management und AI-Unterstützung
Teil F: DevOps, GitOps, Release Management und AI-Unterstützung
Konsolidiert aus Rohmaterial: Teil 11, Teil 12.
DevOps, GitOps und Release Management
Release-Fluss kompakt
Kompakte Themenübersicht
1. Warum DevOps in diesem Lab mehr ist als eine Pipeline
DevOps wird in vielen Projekten auf CI/CD reduziert. Das ist zu wenig. Eine Pipeline kann Code bauen, Tests ausführen und ein Container Image veröffentlichen. Aber eine Enterprise-Plattform braucht mehr: klare Verantwortlichkeiten, nachvollziehbare Änderungen, reproduzierbare Umgebungen, sichere Freigaben, kontrollierte Releases, Rollback-Wege und eine Verbindung zwischen Entwicklung, Betrieb, Security und Architektur.
In diesem Lab bedeutet DevOps nicht, dass jeder alles darf. DevOps bedeutet, dass Teams so arbeiten, dass Änderungen schnell, sicher und nachvollziehbar in produktionsnahe Umgebungen gelangen. Dazu gehören Git-Strategie, Pull Requests, automatisierte Checks, Artefaktversionierung, Container Registry, GitOps, Release Notes, Environment Promotion, Change-Nachweise und Runbooks.
Ein moderner Service ist erst dann wirklich lieferbar, wenn folgende Fragen beantwortet sind:
Vorlage / Textauszug
Wer hat die Änderung gemacht?
Welche Tests wurden ausgeführt?
Welche Artefakte wurden gebaut?
Welche Image-Version wurde deployt?
Welche Konfiguration wurde verwendet?
Welche Umgebung ist betroffen?
Wie kann die Änderung zurückgenommen werden?
Welche fachliche Auswirkung hat die Änderung?
Das Ziel dieses Kapitels ist, aus einzelnen Build-Schritten einen belastbaren Enterprise-Lieferprozess zu machen.
---
2. Git als zentrale Wahrheit
Git ist im Lab nicht nur ein Ort für Quellcode. Git wird zur zentralen Wahrheit für Anwendungen, Infrastruktur, Plattformkonfiguration und Dokumentation.
Das bedeutet: Eine Änderung, die nicht in Git nachvollziehbar ist, gilt nicht als sauber umgesetzt. Das betrifft Java-Code genauso wie OpenShift-Manifeste, Terraform-Dateien, Ansible-Playbooks, ADRs, Runbooks und Dashboards.
Eine gute Git-Struktur macht sichtbar, welche Verantwortung ein Bereich hat. Der Order Service liegt unter apps/order-service. Die OpenShift-Manifeste liegen unter platform/openshift oder platform/kustomize. ADRs liegen unter docs/adr. Runbooks liegen unter docs/runbooks.
Dadurch kann ein Reviewer erkennen, ob eine Änderung vollständig ist. Wenn ein Entwickler eine neue Datenbankverbindung einführt, sollte nicht nur Java-Code geändert werden. Wahrscheinlich braucht es auch eine ConfigMap, ein Secret, eine NetworkPolicy, eine README-Ergänzung und vielleicht ein Runbook.
---
3. Branching-Modell für das Lab
Für das Lab verwenden wir ein einfaches, aber enterprise-taugliches Modell.
Vorlage / Textauszug
main
feature/order-outbox
feature/billing-consumer
fix/order-db-timeout
release/2026.07
hotfix/prod-token-validation
main enthält den integrierten Stand. Feature-Branches dienen der Entwicklung einzelner Änderungen. Release-Branches können genutzt werden, wenn ein stabiler Release-Kandidat vorbereitet wird. Hotfix-Branches sind für dringende Produktionskorrekturen gedacht.
Wichtig ist: Das Branching-Modell darf nicht komplizierter sein als nötig. Viele alte Enterprise-Projekte leiden unter schwer verständlichen Branching-Regeln. Dann wissen Teams nicht mehr, wohin eine Änderung gemerged werden soll. Für dieses Lab gilt daher:
Vorlage / Textauszug
Feature klein halten.
Pull Request früh öffnen.
Automatische Checks verpflichtend machen.
Release-Zustand taggen.
Produktionsänderungen nie direkt im Cluster klicken.
---
4. Pull Request als Qualitätsgrenze
Ein Pull Request ist mehr als eine Bitte um Code Review. Er ist eine Qualitätsgrenze. Hier wird geprüft, ob eine Änderung fachlich, technisch, sicherheitsbezogen und betrieblich vollständig ist.
Ein Pull Request für den Order Service sollte zum Beispiel enthalten:
Vorlage / Textauszug
fachliche Beschreibung der Änderung
Link zum Ticket oder zur Story
betroffene API-Endpunkte
Datenbankmigration, falls nötig
Tests
Auswirkungen auf Konfiguration
Auswirkungen auf Security
Auswirkungen auf Monitoring
Rollback-Hinweis
Ein schwacher Pull Request sagt nur:
Vorlage / Textauszug
Added new endpoint.
Ein guter Pull Request sagt:
Vorlage / Textauszug
Dieser PR ergänzt den Endpunkt zum Stornieren einer Bestellung. Der Endpunkt ist nur für Benutzer mit der Rolle ORDER_MANAGER erlaubt. Die Änderung ergänzt einen Integrationstest mit Keycloak-Testtoken, eine Flyway-Migration für den Stornogrund, eine neue Metrik order_cancel_total und ein Runbook-Hinweis für gehäufte Stornofehler.
Dadurch wird der Review deutlich besser.
---
5. Pull-Request-Checkliste
Diese Checkliste ist kein Ersatz für Denken. Sie verhindert aber typische Lücken.
Vorlage / Textauszug
Pull Request Checkliste
Fachlichkeit
[ ] Zweck der Änderung ist beschrieben
[ ] betroffene Use Cases sind genannt
[ ] fachliche Fehlerfälle sind berücksichtigt
Code
[ ] Unit Tests vorhanden
[ ] Integrationstests vorhanden, wenn Infrastruktur beteiligt ist
[ ] keine Secrets im Code
[ ] keine harten Umgebungswerte
Daten
[ ] Migration vorhanden, falls Schema geändert wird
[ ] Rollback- oder Korrekturstrategie beschrieben
[ ] Datenklassifizierung geprüft
Security
[ ] Rollen/Berechtigungen geprüft
[ ] Token-/OIDC-Auswirkung geprüft
[ ] NetworkPolicy-Auswirkung geprüft
Betrieb
[ ] Logs sinnvoll
[ ] Metriken ergänzt, falls nötig
[ ] Alert oder Dashboard angepasst, falls nötig
[ ] Runbook angepasst, falls nötig
Deployment
[ ] Manifest/Kustomize/Helm angepasst
[ ] Ressourcenlimits geprüft
[ ] Readiness/Liveness nicht gebrochen
[ ] Rollback-Hinweis vorhanden
Diese Checkliste wird direkt in das Repository gelegt, zum Beispiel unter .github/pull_request_template.md oder .gitruntime-lab/merge_request_templates/default.md.
---
6. CI: Continuous Integration
Continuous Integration bedeutet, dass Änderungen regelmäßig integriert und automatisch geprüft werden. Für Java-Services im Lab umfasst CI typischerweise:
Vorlage / Textauszug
Checkout
Java Setup
Dependency Cache
Build
Unit Tests
Integration Tests
Static Analysis
Container Build
Image Scan
Push zur Registry
CI beantwortet die Frage: Ist dieser Code technisch und qualitativ in einem Zustand, der als Artefakt gebaut werden kann?
CI deployt nicht automatisch nach Produktion. Das ist eine bewusste Trennung. Deployment erfolgt später kontrolliert über GitOps.
Dieses Beispiel zeigt mehrere wichtige Punkte. Die Pipeline reagiert nur auf relevante Pfade. Java 21 wird festgelegt. Tests laufen vor dem Image-Build. Das Image bekommt den Git SHA als Version. Security Scans können den Build stoppen.
In einem echten Projekt würde zusätzlich Login zur Registry, SBOM-Erzeugung und Signierung ergänzt.
---
8. Artefaktversionierung
Ein häufiger Fehler ist die Nutzung von latest als produktive Image-Version. Das ist gefährlich, weil später nicht mehr klar ist, welcher Code tatsächlich läuft.
Diese Labels helfen später bei Audits und Incident-Analysen.
---
9. Container Build: sauber statt zufällig
Ein Dockerfile für Enterprise-Services sollte klein, reproduzierbar und sicher sein.
dockerfile
FROM eclipse-temurin:21-jre-alpine
RUN addgroup -S app && adduser -S app -G app
WORKDIR /app
COPY target/order-service.jar /app/order-service.jar
USER app
EXPOSE 8080
ENTRYPOINT [class="str">"java", class="str">"-XX:MaxRAMPercentage=75", class="str">"-jar", class="str">"/app/order-service.jar"]
Dieses Dockerfile ist bewusst schlicht. Es nutzt ein JRE-Image statt eines kompletten JDK-Images, legt einen nicht-root Benutzer an und startet die Anwendung ohne Shell-Tricks.
In OpenShift ist zusätzlich wichtig, dass Container nicht auf feste User-IDs angewiesen sind. OpenShift vergibt häufig dynamische UIDs. Deshalb muss das Image so gebaut sein, dass es nicht zwingend einen bestimmten Linux-Benutzer erwartet, wenn die Plattform andere Security-Kontexte erzwingt.
---
10. GitOps-Grundidee
GitOps-Releasefluss
Kompakte Lernhilfe
GitOps bedeutet: Der gewünschte Zustand der Plattform liegt in Git. Ein GitOps-Controller wie Argo CD vergleicht diesen Zustand mit dem tatsächlichen Zustand im Cluster und synchronisiert Abweichungen.
Nicht der Entwickler klickt direkt im Cluster herum. Stattdessen ändert er Git. Argo CD bringt den Cluster in den gewünschten Zustand.
Der Vorteil ist Nachvollziehbarkeit. Jede Deployment-Änderung hat einen Commit. Jede Änderung kann reviewed werden. Rollbacks erfolgen über Git-Zustände.
Der Nachteil ist: Teams müssen sauber zwischen Build und Deployment unterscheiden. Die CI-Pipeline baut ein Image. GitOps deployt dieses Image.
---
11. Trennung von App-Repo und GitOps-Repo
In vielen Enterprise-Projekten ist es sinnvoll, Quellcode und Deployment-Zustand zu trennen.
Beispiel:
Vorlage / Textauszug
app repository:
apps/order-service
platform repository:
platform-gitops/environments/dev/order-service
platform-gitops/environments/test/order-service
platform-gitops/environments/prod/order-service
Das App-Repo enthält Code, Tests und Dockerfile. Das GitOps-Repo enthält Manifest-Versionen für Umgebungen.
Der Vorteil: Produktionsdeployment kann stärker geschützt werden. Ein Entwickler kann ein Image bauen, aber nicht automatisch Produktion ändern. Die Änderung im GitOps-Repo braucht einen eigenen Review.
---
12. Kustomize für Umgebungstrennung
Kustomize eignet sich gut, um gemeinsame Basis-Manifeste und umgebungsspezifische Anpassungen zu trennen.
Hier wird das Image für Produktion festgelegt. Genau diese Datei ist später Gegenstand eines Reviews. Ein Release nach Produktion ist dadurch nicht unsichtbar, sondern ein Git-Commit.
Diese Application beschreibt, wo Argo CD den gewünschten Zustand findet und wohin er deployt wird.
Für Produktion wird prune: false in manchen Organisationen bewusst gewählt, damit Ressourcen nicht automatisch gelöscht werden. Andere Organisationen erlauben prune, wenn Review und Schutzmechanismen stark genug sind. Das ist eine Governance-Entscheidung.
---
15. Environment Promotion
Environment Promotion bedeutet: Eine Änderung wandert kontrolliert von Dev nach Test und dann nach Prod.
Skizze / Textauszug
Dev
↓
automatische Tests
↓
Test
↓
fachliche Abnahme
↓
Staging
↓
Release-Freigabe
↓
Prod
Die schlechte Variante ist, dieselbe Änderung manuell in jeder Umgebung anders einzutragen. Dann weiß niemand, ob Test wirklich wie Prod ist.
Die bessere Variante ist, dass dasselbe Image durch die Umgebungen wandert. Nicht jedes Mal wird neu gebaut. Ein Image, das in Test geprüft wurde, wird später in Prod verwendet.
Skizze / Textauszug
Build einmal
↓
Image versionieren
↓
Dev deployen
↓
Test deployen
↓
Prod deployen
Dadurch wird verhindert, dass in Produktion ein anderes Artefakt landet als getestet wurde.
---
16. Release Notes
Release Notes sind nicht nur für Endbenutzer wichtig. Sie helfen Betrieb, Support und Security.
Gute Release Notes enthalten:
Vorlage / Textauszug
Version
Datum
betroffene Services
neue Funktionen
geänderte APIs
Datenbankmigrationen
Security-Auswirkungen
Betriebsänderungen
bekannte Risiken
Rollback-Hinweis
Beispiel:
Vorlage / Textauszug
Release 2026.07.0
Betroffene Services
order-service 1.4.0
billing-service 1.2.3
Änderungen
Order Service unterstützt Stornierung von Bestellungen.
Billing Service ignoriert stornierte Bestellungen bei Rechnungserstellung.
Datenbank
Neue Spalte orders.cancel_reason.
Neue Tabelle order_status_history.
Security
Neuer Scope order:cancel erforderlich.
Betrieb
Neue Metrik order_cancel_total.
Dashboard Order Overview erweitert.
Rollback
Rollback der Anwendung ist möglich. Datenbankmigration ist vorwärtskompatibel, Spalten bleiben bestehen.
Das ist deutlich hilfreicher als eine automatische Commit-Liste.
---
17. Rollback und Rollforward
Rollback bedeutet, auf einen vorherigen Stand zurückzugehen. Rollforward bedeutet, mit einer neuen Korrektur weiterzugehen.
In Enterprise-Systemen ist Rollback nicht immer einfach. Besonders Datenbankänderungen können problematisch sein. Wenn eine Migration Daten löscht oder Spalten umbenennt, kann ein alter Service möglicherweise nicht mehr starten.
Alte Spalten erst entfernen, wenn kein Service sie braucht.
Feature Flags für riskante Funktionen verwenden.
Rollback-Hinweis im Pull Request verlangen.
Ein Rollback ohne Datenstrategie ist kein echter Rollback.
---
18. Blue-Green und Canary Releases
Nicht jedes Release muss sofort 100 Prozent des Traffics erhalten.
Bei Blue-Green gibt es zwei Umgebungen oder zwei Versionen. Eine Version ist aktiv, die andere wird vorbereitet. Nach Prüfung wird Traffic umgeschaltet.
Bei Canary erhält eine neue Version zunächst nur einen kleinen Teil des Traffics. Wenn Metriken stabil bleiben, wird der Anteil erhöht.
In OpenShift können solche Strategien über Routes, Service Mesh oder progressive Delivery-Werkzeuge umgesetzt werden. Für das Lab reicht zunächst das Verständnis:
Vorlage / Textauszug
Rolling Update: Standard, einfach, meist ausreichend.
Blue-Green: nützlich bei schnellen Umschaltungen.
Canary: nützlich bei risikoreichen Änderungen.
Für den Order Service kann ein Rolling Update genügen. Für ein Customer Portal mit vielen Nutzern kann Canary sinnvoll sein.
---
19. Feature Flags
Feature Flags erlauben, eine Funktion im Code zu haben, aber kontrolliert zu aktivieren.
Feature Flags sind hilfreich, aber gefährlich, wenn sie nicht gepflegt werden. Alte Flags müssen entfernt werden. Sonst entsteht versteckte Komplexität.
---
20. Jenkinsfile als Enterprise-Alternative
Viele Unternehmen nutzen weiterhin Jenkins. Auch das ist realistisch. Ein gutes Lab sollte nicht nur GitHub Actions kennen.
Die genaue Version muss im echten Projekt gepflegt werden. Wichtig ist die Regel: Kritische Abhängigkeiten dürfen nicht unbemerkt in Produktion gelangen.
---
23. Secrets in CI/CD
Secrets sind in Pipelines besonders gefährlich. Ein falsch gesetztes echo kann ein Token in Logs schreiben. Ein zu breit berechtigter Registry-Token kann Images überschreiben. Ein Cloud-Key in einer Pipeline kann Infrastruktur kompromittieren.
Regeln für das Lab:
Vorlage / Textauszug
Secrets nie im Repository speichern.
Secrets nie in Klartext in Pipeline-Dateien schreiben.
Secrets mit minimalen Rechten ausstellen.
Secrets regelmäßig rotieren.
Pipeline-Logs auf versehentliche Ausgabe prüfen.
Produktions-Secrets getrennt von Dev-Secrets halten.
In GitOps wird zusätzlich beachtet: Kubernetes Secrets sollten nicht unverschlüsselt im GitOps-Repo liegen. Dafür nutzt man zum Beispiel External Secrets, Sealed Secrets oder SOPS.
---
24. Change Management ohne Schwerfälligkeit
Enterprise bedeutet nicht, jede Änderung durch wochenlange Gremien zu schicken. Aber produktionsrelevante Änderungen brauchen Nachvollziehbarkeit.
Ein schlanker Change-Prozess kann so aussehen:
Vorlage / Textauszug
Pull Request beschreibt Änderung.
CI prüft Build, Tests und Scans.
Reviewer prüft Code, Betrieb und Security.
GitOps-PR aktualisiert Image-Version.
Release Notes werden ergänzt.
Argo CD synchronisiert Zielumgebung.
Monitoring wird nach Deployment beobachtet.
Damit ist die Änderung kontrolliert, aber nicht unnötig blockiert.
---
25. Release-Freigabe für Produktion
Für Produktion sollten zusätzliche Bedingungen gelten.
Vorlage / Textauszug
Alle Tests grün.
Image Scan ohne kritische Funde.
Datenbankmigration geprüft.
Rollback- oder Rollforward-Strategie beschrieben.
Runbook aktuell.
Monitoring nach Deployment definiert.
Fachliche Freigabe vorhanden, wenn notwendig.
Die Freigabe kann über einen Pull Request im GitOps-Repo erfolgen. Dieser PR ändert zum Beispiel nur die Image-Version von 1.3.2 auf 1.4.0. Trotzdem ist er wichtig, weil er Produktion verändert.
Dieser kleine Diff ist fachlich groß. Er bedeutet: In Produktion soll eine neue Version laufen. Deshalb gehört in den PR-Text eine Release-Zusammenfassung.
Vorlage / Textauszug
Production Release: order-service 1.4.0
Zweck
Aktiviert Stornierung von Bestellungen für interne Mitarbeiter.
Checks
CI grün
Integrationstests grün
Image Scan ohne HIGH/CRITICAL
Staging 24 Stunden stabil
Beobachtung nach Deployment
order_cancel_total
http_server_requests_seconds
outbox_unpublished_events
error_rate
Rollback
Image-Tag zurück auf 1.3.2 setzen. Datenbankmigration ist vorwärtskompatibel.
---
27. Betrieb nach dem Deployment
Ein Deployment ist nicht fertig, wenn Argo CD grün zeigt. Danach beginnt die Beobachtung.
Nach einem Release prüft das Team:
Vorlage / Textauszug
Sind Pods ready?
Steigt die Fehlerrate?
Steigt die Latenz?
Wachsen Queues oder Outbox?
Gibt es neue Logfehler?
Funktionieren fachliche Kernprozesse?
Für den Order Service könnten konkrete Checks sein:
bash
oc get pods -n order-prod -l app=order-service
oc rollout status deployment/order-service -n order-prod
oc logs -n order-prod deployment/order-service --tail=100
Zusätzlich prüft man Grafana-Dashboards und Prometheus Alerts.
---
28. Runbook: Fehlgeschlagenes Deployment
Vorlage / Textauszug
Runbook: Deployment order-service fehlgeschlagen
Symptom
Argo CD zeigt OutOfSync oder Degraded. Pods starten nicht oder Readiness schlägt fehl.
Sofortprüfung
argocd app get order-service-prod
oc get pods -n order-prod -l app=order-service
oc describe pod -n order-prod -l app=order-service
Wenn die Ursache schnell korrigierbar ist, GitOps-Repo korrigieren und Argo CD erneut synchronisieren.
Wenn Produktion beeinträchtigt ist, Image-Version im GitOps-Repo auf vorherigen stabilen Stand zurücksetzen.
Nacharbeit
Incident dokumentieren
fehlenden Pipeline-Check ergänzen
Runbook aktualisieren
Dieses Runbook verbindet GitOps, OpenShift und Anwendung. Es verhindert hektisches Klicken im Cluster.
---
29. Typische Fehler im DevOps-Bereich
Ein häufiger Fehler ist, CI/CD als reine Tool-Frage zu behandeln. Dann wird viel über Jenkins, GitHub Actions oder GitLab CI diskutiert, aber wenig über Release-Qualität.
Ein zweiter Fehler ist, Deployment und Build zu vermischen. Wenn eine Pipeline direkt in Produktion deployt, ohne GitOps-Zustand, fehlt später oft die saubere Nachvollziehbarkeit.
Ein dritter Fehler ist latest als Image-Tag. Damit wird Auditing unnötig schwer.
Ein vierter Fehler sind fehlende Rollback-Strategien. Besonders Datenbankänderungen werden unterschätzt.
Ein fünfter Fehler ist, Security Scans nur einzuführen, aber nie zu pflegen. Wenn Scans ständig ignoriert werden, verlieren sie ihren Wert.
Ein sechster Fehler ist, Pipeline-Secrets zu breit zu berechtigen. Ein CI-Token sollte nicht mehr dürfen als nötig.
---
30. Übung: Release-Prozess für Billing Service entwerfen
Entwirf einen Release-Prozess für den Billing Service.
Beschreibe:
Vorlage / Textauszug
Welche Branches verwendet werden.
Welche CI-Schritte laufen.
Wie das Container Image versioniert wird.
Wie Dev, Test und Prod aktualisiert werden.
Welche Checks vor Produktion Pflicht sind.
Welche Monitoring-Werte nach Deployment geprüft werden.
Wie ein Rollback funktioniert.
Erstelle zusätzlich einen kurzen Pull-Request-Text für die Produktionsfreigabe.
---
31. Musterlösung zur Übung
Vorlage / Textauszug
Der Billing Service wird über Feature-Branches entwickelt. Jeder Feature-Branch öffnet einen Pull Request gegen main. Die CI führt Maven Verify, Unit Tests, Integrationstests mit Testcontainers, Dependency Scan, Container Build und Image Scan aus.
Bei Merge nach main wird ein Image mit Git SHA und semantischer Version gebaut. Das Image wird in die Registry gepusht.
Dev wird automatisch über GitOps aktualisiert. Test wird über einen Pull Request im GitOps-Repo auf dieselbe Image-Version gehoben. Produktion wird erst nach fachlicher Abnahme und stabiler Testphase aktualisiert.
Vor Produktion müssen CI, Image Scan, Datenbankmigration, Runbook, Release Notes und Monitoring-Checks abgeschlossen sein.
Nach Deployment werden Fehlerrate, Latenz, Consumer Lag, Dead Letter Queue, Rechnungsfehler und Datenbankverbindungen geprüft.
Rollback erfolgt über Änderung des Image-Tags im GitOps-Repo auf die vorherige stabile Version. Datenbankmigrationen werden vorwärtskompatibel gebaut, damit der alte Service weiterhin mit dem Schema arbeiten kann.
Beispiel für den Produktions-PR:
Vorlage / Textauszug
Production Release: billing-service 1.2.3
Zweck
Verbessert Verarbeitung von OrderCreatedEvents und ergänzt idempotente Rechnungsprüfung.
Nachweise
CI grün
Integrationstests mit Kafka und PostgreSQL grün
Image Scan ohne kritische Findings
Staging seit 24 Stunden stabil
Runbook aktualisiert
Monitoring nach Deployment
billing_event_processing_total
billing_event_failed_total
kafka_consumer_lag
dead_letter_queue_size
http_server_requests_seconds
Rollback
Image-Tag zurück auf 1.2.2 setzen. Migration ist vorwärtskompatibel.
---
32. Merksätze
Vorlage / Textauszug
DevOps ist ein Betriebsmodell, nicht nur eine Pipeline.
Git ist die zentrale Wahrheit für Code, Infrastruktur und Dokumentation.
CI baut und prüft Artefakte. GitOps deployt gewünschte Zustände.
Ein Image muss eindeutig versioniert sein. latest ist kein Release-Konzept.
Ein Pull Request ist eine Qualitätsgrenze.
Ein Deployment ist erst abgeschlossen, wenn es beobachtet wurde.
Rollback ohne Datenstrategie ist gefährlich.
Release Management verbindet Entwicklung, Betrieb, Security und Fachlichkeit.
Codex und Claude Code im Enterprise-Projekt
1. Warum AI-Werkzeuge im Enterprise-Projekt anders geführt werden müssen
Codex und Claude Code können in einem Enterprise-Projekt sehr hilfreich sein, aber sie ersetzen keine Architekturverantwortung. Sie sind Werkzeuge, die Code erklären, Varianten erzeugen, Refactorings vorbereiten, Tests schreiben, Buildfehler analysieren und Dokumentation strukturieren können. Sie wissen aber nicht automatisch, welche Sicherheitsregeln, Betriebsprozesse, Compliance-Vorgaben, Namenskonventionen und Plattformstandards im Unternehmen gelten.
Der wichtigste Unterschied zu einer kleinen Demo ist der Kontext. In einem einfachen Projekt reicht oft ein Prompt wie: „Erstelle mir einen Spring Boot Service.“ In einem Enterprise-Projekt ist das zu ungenau. Ein Service muss zur Zielarchitektur passen, die Paketstruktur einhalten, Authentifizierung berücksichtigen, Metriken liefern, Fehler sauber behandeln, Deployment-Artefakte mitbringen und in GitOps integrierbar sein.
AI-Werkzeuge müssen deshalb wie ein sehr schneller Junior- bis Mid-Level-Mitarbeiter behandelt werden: nützlich, produktiv, aber kontrollbedürftig. Sie brauchen klare Aufgaben, klare Grenzen, konkrete Dateien, Qualitätsregeln und Review.
Vorlage / Textauszug
AI im Enterprise-Projekt ist kein Autopilot.
AI ist ein Beschleuniger für klar geführte Arbeit.
Wenn die Vorgaben schlecht sind, erzeugt das Werkzeug oft scheinbar professionelle Ergebnisse, die später teuer werden: falsche Paketstruktur, fehlende Tests, unsichere Defaults, zu große Klassen, unklare Transaktionen, generische Dokumentation oder Deployment-YAML ohne echte Betriebsreife.
---
2. Rolle von Codex im Lab
Codex eignet sich besonders für Arbeit direkt am Code. Im Lab kann Codex genutzt werden, um konkrete Dateien zu erstellen oder zu ändern, Tests zu ergänzen, Buildfehler zu analysieren und Refactorings Schritt für Schritt vorzubereiten.
Typische Aufgaben für Codex:
Vorlage / Textauszug
Java-Klassen erstellen
Spring Boot Controller ergänzen
Tests schreiben
Maven-Fehler analysieren
DTOs und Mapper erzeugen
kleine Refactorings durchführen
Dockerfile prüfen
YAML-Manifeste syntaktisch korrigieren
Repository-Struktur aufräumen
README aus tatsächlichem Projektstand aktualisieren
Codex sollte jedoch nicht ohne Kontrolle ganze Architekturen entscheiden. Die Entscheidung, ob ein Service Spring Boot, Quarkus oder Micronaut nutzt, ob Kafka oder RabbitMQ verwendet wird, ob ein Workload auf VM oder OpenShift läuft und wie Datenbesitz geschnitten wird, bleibt eine Architekturentscheidung.
Codex ist stark, wenn die Aufgabe nah an konkreten Dateien liegt:
Vorlage / Textauszug
Ändere diese Klasse.
Ergänze diesen Test.
Passe diese Pipeline an.
Erkläre diesen Buildfehler.
Füge diese Validierung ein.
Codex ist schwächer, wenn die Aufgabe zu offen ist:
Vorlage / Textauszug
Baue mir eine komplette Enterprise-Plattform.
Mach alles sicher.
Mach es production-ready.
Solche Prompts sind zu breit. Sie erzeugen oft generische Ergebnisse.
---
3. Rolle von Claude Code im Lab
Claude Code eignet sich besonders für größere Codebasis-Navigation, Architekturverständnis, mehrstufige Änderungen und erklärende Aufgaben. Es kann hilfreich sein, wenn mehrere Dateien zusammen betrachtet werden müssen oder wenn ein Refactoring über mehrere Module vorbereitet wird.
Typische Aufgaben für Claude Code:
Vorlage / Textauszug
vorhandene Projektstruktur analysieren
Architekturprobleme in mehreren Modulen erkennen
Refactoring-Plan schreiben
große Pull Requests vorbereiten
technische Schulden dokumentieren
Modulgrenzen erklären
ADRs aus Codeänderungen ableiten
Migrationspfade beschreiben
Testszenarien aus Use Cases ableiten
Claude Code kann besonders nützlich sein, wenn nicht nur eine Datei geändert wird, sondern ein Zusammenhang verstanden werden muss. Beispiel: Der Order Service speichert Bestellungen, schreibt Outbox Events, ein Publisher liest diese Events und ein Billing Consumer verarbeitet sie. Wenn eine Änderung am Event Payload nötig ist, betrifft das mehrere Stellen. Hier hilft ein Werkzeug, das die Zusammenhänge systematisch betrachten kann.
Trotzdem gilt auch hier: Claude Code entscheidet nicht selbst, welche Fachlogik richtig ist. Die fachliche Wahrheit kommt aus Anforderungen, ADRs, Tests und Reviews.
---
4. Gemeinsames Arbeitsmodell
Im Lab verwenden wir Codex und Claude Code nicht konkurrierend, sondern ergänzend.
Skizze / Textauszug
Architekturfrage
↓
Claude Code oder ChatGPT für Analyse, Struktur, ADR und Plan
↓
Codex für konkrete Codeänderung
↓
Tests und Build lokal/CI ausführen
↓
Review durch Mensch
↓
GitOps-Deployment
↓
Monitoring und Betrieb prüfen
Das Ziel ist nicht, möglichst viel automatisch zu erzeugen. Das Ziel ist, Arbeitsschritte nachvollziehbar zu machen.
Ein gutes Arbeitsmodell sieht so aus:
Vorlage / Textauszug
Mensch beschreibt Ziel und Grenzen.
AI schlägt Plan vor.
Mensch prüft Plan.
AI ändert kleine, kontrollierbare Einheiten.
Tests laufen.
Mensch reviewed.
Dokumentation wird aktualisiert.
Änderung wird gemergt.
Ein schlechtes Arbeitsmodell sieht so aus:
Vorlage / Textauszug
AI soll alles bauen.
Ergebnis wird nicht geprüft.
Fehler fallen erst beim Deployment auf.
Dokumentation passt nicht zum Code.
Betrieb findet keine Ursache.
---
5. Prompt-Regeln für Enterprise-Code
Ein guter Prompt beschreibt nicht nur das gewünschte Ergebnis, sondern auch den Kontext und die Qualitätsgrenzen.
Schlechter Prompt:
Vorlage / Textauszug
Erstelle einen Order Service.
Besserer Prompt:
Vorlage / Textauszug
Erstelle im bestehenden Maven-Modul order-service einen Spring Boot REST Controller für das Anlegen einer Bestellung.
Rahmen:
Java 21
Package: com.seb4u.demo.spring.order
Controller liegt in api
Use Case liegt in application
Domänenobjekte liegen in domain
keine Datenbanklogik im Controller
Validierung über DTO und Anwendungsschicht
Fehler als ProblemDetail zurückgeben
Tests für gültige und ungültige Requests ergänzen
bestehende Paketstruktur nicht verändern
Dieser Prompt führt das Werkzeug. Er verhindert, dass zufällige Struktur entsteht.
---
6. Kontextdateien für AI-Arbeit
Ein Enterprise-Projekt sollte AI-Werkzeugen nicht jedes Mal neu erklärt werden. Stattdessen gibt es Kontextdateien.
Sinnvolle Dateien:
Vorlage / Textauszug
AI_PROJECT_RULES.md
ARCHITECTURE.md
CODING_STANDARDS.md
SECURITY_RULES.md
TESTING_RULES.md
DEPLOYMENT_RULES.md
OBSERVABILITY_RULES.md
Diese Dateien enthalten nicht Marketingtext, sondern konkrete Regeln.
Beispiel AI_PROJECT_RULES.md:
Vorlage / Textauszug
AI Project Rules
Sprache und Stil
Antworten, Kommentare und Dokumentation im Projekt sind auf Deutsch, außer technische Bezeichner, Code und externe API-Namen.
Java Packages
Alle Java-Packages beginnen mit:
com.seb4u.demo
Vorlage / Textauszug
Spring-Services verwenden:
com.seb4u.demo.spring.<bounded-context>
Vorlage / Textauszug
Quarkus-Services verwenden:
com.seb4u.demo.quarkus.<bounded-context>
Vorlage / Textauszug
Architektur
Controller enthalten keine Fachlogik.
Application Services koordinieren Use Cases.
Domain-Klassen enthalten fachliche Regeln.
Infrastructure-Klassen enthalten Datenbank-, Messaging- und Plattformdetails.
Tests
Neue Fachlogik braucht Unit Tests.
Neue Datenbankintegration braucht Integrationstests mit Testcontainers.
Neue REST-Endpunkte brauchen Controller- oder API-Tests.
Nicht erlaubt
Secrets in Code
direkte Datenbankzugriffe aus Controller-Klassen
generische catch(Exception)-Blöcke ohne Behandlung
neue Frameworks ohne ADR
Copy/Paste-Dokumentation ohne Bezug zum Code
Mit solchen Regeln arbeitet AI deutlich stabiler.
---
7. Beispiel: Codex-Aufgabe für einen Controller
Eine präzise Codex-Aufgabe könnte so aussehen:
Vorlage / Textauszug
Aufgabe:
Ergänze im Modul apps/order-service einen REST-Endpunkt POST /api/orders.
AI-generiertes YAML muss immer gegen Plattformregeln geprüft werden.
---
12. AI bei Dokumentation
AI kann Dokumentation schnell schreiben, aber sie neigt zu generischen Formulierungen. Genau das war im bisherigen Projekt problematisch: Absätze klangen ordentlich, waren aber wiederholt und austauschbar.
Deshalb gilt:
Vorlage / Textauszug
Dokumentation darf nicht nur erklären, was allgemein richtig ist.
Sie muss erklären, was in diesem Projekt konkret gilt.
Schlechter Dokumentationssatz:
Vorlage / Textauszug
Monitoring ist wichtig, um Systeme zu überwachen und Fehler zu erkennen.
Besser:
Vorlage / Textauszug
Der Order Service exportiert Metriken über /actuator/prometheus. Prometheus sammelt diese Metriken über einen ServiceMonitor im Namespace order-prod. Ein Alert wird ausgelöst, wenn die Fehlerrate über fünf Minuten mehr als zwei Prozent beträgt oder wenn die Outbox länger als zehn Minuten unveröffentlichte Events enthält.
Der zweite Satz ist prüfbar. Er nennt Service, Endpoint, Namespace, Metrikidee und konkretes Fehlerbild.
---
13. Qualitätsprüfung gegen AI-Fülltext
Damit kein künstlicher Inhalt entsteht, braucht das Projekt eine Prüfung gegen Wiederholungsmuster.
Nicht erlaubt:
Vorlage / Textauszug
gleiche Absätze mit ausgetauschtem Schwerpunkt
nummerierte Fülltabellen ohne echte Unterschiede
Kapitel mit fast identischem Aufbau und gleichem Text
generische Listen ohne Projektbezug
Glossar als Ersatz für Erklärung
Praxisdurchläufe als angehängte Serienblöcke
Erlaubt:
Vorlage / Textauszug
wiederkehrende Kapitelstruktur
unterschiedliche fachliche Inhalte
konkrete Beispiele
projektbezogene Codeblöcke
echte Runbooks
spezifische Fehlerbilder
klare Akzeptanzkriterien
Eine technische Prüfung kann einfache Muster finden.
Beispiel:
bash
#!/usr/bin/env bash
set -euo pipefail
TARGET_DIR=class="str">"docs"
for pattern in \
class="str">"integrierte Vertiefung" \
class="str">"Praxisdurchlauf" \
class="str">"Entscheidung 2" \
class="str">"Risiko 2" \
class="str">"Warum das im Lab wichtig ist"; do
if grep -R class="str">"$pattern" class="str">"$TARGET_DIR"; then
echo class="str">"Unzulässiges Muster gefunden: $pattern"
exit 1
fi
done
echo class="str">"Keine bekannten Füllmuster gefunden."
Diese Prüfung ersetzt kein Review, aber sie verhindert bekannte Fehler.
---
14. AI und Security-Grenzen
AI darf keine echten Secrets, Tokens, Passwörter oder internen Zugangsdaten verarbeiten. Für das Lab werden immer Platzhalter verwendet.
AI darf beim Schreiben helfen, aber echte Werte gehören nicht in Prompts.
---
15. AI im Pull-Request-Prozess
AI kann Pull Requests vorbereiten und Reviews unterstützen.
Ein sinnvoller PR-Prozess:
Vorlage / Textauszug
Entwickler erstellt Aufgabe mit Akzeptanzkriterien.
AI unterstützt bei Code oder Tests.
Entwickler prüft lokal.
CI führt Build, Tests und Scans aus.
AI kann eine PR-Zusammenfassung vorschlagen.
Menschliche Reviewer prüfen Architektur, Fachlichkeit und Sicherheit.
Merge erfolgt erst nach grünen Checks.
AI-Zusammenfassung für PRs sollte konkret sein:
Vorlage / Textauszug
Änderung
Dieser Pull Request ergänzt den Endpunkt POST /api/orders im Order Service.
Technische Änderungen
CreateOrderRequest ergänzt
OrderController ergänzt
Bean Validation aktiviert
Controller-Test für HTTP 201 und HTTP 400 ergänzt
Nicht enthalten
keine Änderung am Billing Service
keine Änderung am Event Payload
keine neue Datenbankmigration
Nachweise
mvn test erfolgreich
Controller-Test deckt gültige und ungültige Requests ab
Das ist besser als eine generische Zusammenfassung wie „This PR improves order handling“.
---
16. AI bei Fehlersuche
AI kann Logs und Fehlermeldungen erklären, wenn man ihr ausreichend Kontext gibt. Wichtig ist, keine sensiblen Daten zu kopieren.
Guter Prompt:
Vorlage / Textauszug
Analysiere diesen Buildfehler.
Kontext:
Modul: order-service
Java 21
Maven Multi Module Projekt
Fehler tritt seit Änderung an OrderControllerTest auf
relevante pom.xml und Fehlermeldung folgen
Bitte:
Ursache erklären
wahrscheinlichste Datei nennen
minimalen Fix vorschlagen
keine komplette Projektstruktur neu erfinden
Bei Kubernetes-Fehlern:
Vorlage / Textauszug
Analysiere diesen OpenShift-Fehler.
Kontext:
Namespace: order-prod
Deployment: order-service
Pod startet, wird aber nicht ready
Readiness Endpoint /actuator/health/readiness
Logs und oc describe Ausschnitt folgen
Bitte:
mögliche Ursachen priorisieren
Prüfkommandos nennen
keine Secrets ausgeben
So wird AI Teil der Fehlersuche, aber nicht Ersatz für Betriebswissen.
---
17. AI und Refactoring alter Enterprise-Anwendungen
Bei Legacy-Code darf AI nicht einfach modernisieren, ohne Verhalten zu sichern. Zuerst braucht es Charakterisierungstests.
Sicheres Vorgehen:
Vorlage / Textauszug
bestehendes Verhalten beschreiben
Tests für aktuelles Verhalten ergänzen
kleine Extraktionen durchführen
nach jedem Schritt Tests ausführen
Fachlogik nicht gleichzeitig ändern
technische Verbesserung und fachliche Änderung trennen
Prompt:
Vorlage / Textauszug
Analysiere diese Legacy-Methode.
Ziel:
Noch kein Refactoring durchführen.
Bitte liefere:
Verantwortlichkeiten der Methode
Seiteneffekte
externe Abhängigkeiten
mögliche Testfälle
sichere Extraktionsschritte
Risiken bei Änderung
Erst danach wird geändert.
---
18. AI bei Migration von VM nach OpenShift
Eine Migration ist mehr als Container bauen.
AI kann helfen, eine Migrationscheckliste zu erstellen:
Vorlage / Textauszug
Welche Ports nutzt die Anwendung?
Welche Dateien schreibt sie lokal?
Welche Umgebungsvariablen braucht sie?
Welche Secrets verwendet sie?
Welche CronJobs oder Scheduler gibt es?
Welche Logs werden geschrieben?
Welche Health Checks existieren?
Welche Datenbankverbindungen gibt es?
Welche Firewall-Regeln werden benötigt?
Welche Betriebsprozesse ändern sich?
Prompt:
Vorlage / Textauszug
Erstelle einen Migrationsplan für reporting-service von VM nach OpenShift.
Kontext:
Anwendung läuft aktuell als systemd-Service
schreibt Reports nach /data/reports
liest PostgreSQL Orders und Billing
läuft täglich nachts
benötigt 2 GB RAM
Logs liegen aktuell unter /var/log/reporting-service
Ziel:
Containerisierung prüfen
Alternative als Kubernetes CronJob bewerten
Storage-Optionen vergleichen
Risiken nennen
schrittweisen Plan erstellen
Das Ergebnis muss danach mit Betrieb, Security und Fachbereich geprüft werden.
---
19. AI und Lernprojekt-Dokumentation
Für dieses Lernprojekt ist wichtig: AI darf beim Schreiben helfen, aber der Inhalt muss wie ein echtes Fachbuch aufgebaut sein.
Regel:
Vorlage / Textauszug
Ein Abschnitt ist nur gültig, wenn er fachlich etwas Eigenes erklärt.
Beispiel Security:
Vorlage / Textauszug
RBAC erklärt Rollen und Rechte.
Hardening erklärt Angriffsfläche und sichere Laufzeit.
Audit erklärt Nachvollziehbarkeit.
Incident Response erklärt Reaktion auf Störungen.
Zero Trust erklärt Misstrauen als Standardprinzip.
Diese Themen dürfen nicht denselben Absatz mit ausgetauschtem Begriff bekommen. Jedes Thema braucht eigene Beispiele, eigene Fehlerbilder und eigene Artefakte.
---
20. AI-Runbook: Falsch generierter Inhalt
Wenn AI wieder künstliche Wiederholungen erzeugt, wird nicht weiter darauf aufgebaut.
Vorlage / Textauszug
Runbook: AI hat Fülltext erzeugt
Symptom
Mehrere Absätze sind fast identisch und unterscheiden sich nur durch einzelne Begriffe.
Sofortmaßnahme
Nicht reparieren durch Suchen/Ersetzen.
Nicht erweitern.
Abschnitt verwerfen.
Analyse
Prüfen:
War der Prompt zu generisch?
Wurde Umfang statt Qualität gefordert?
Wurden konkrete Kapitelziele genannt?
Gab es Akzeptanzkriterien?
Gab es Beispiele für unerlaubte Muster?
Korrektur
Kapitel neu schreiben mit:
eigenem Ziel
eigenem Szenario
eigenem Code
eigenem Fehlerbild
eigener Übung
eigener Musterlösung
Nachweis
Vor Aufnahme ins ZIP prüfen:
keine bekannten Füllmuster
keine Copy/Paste-Absätze
mindestens ein konkreter Projektbezug
Dieses Runbook ist bewusst Teil des Lernprojekts. Es schützt die Qualität.
---
21. Übung: AI-Aufgabe richtig formulieren
Formuliere einen guten Prompt für Codex oder Claude Code.
Aufgabe:
Vorlage / Textauszug
Der Billing Service soll ein Event OrderCreated konsumieren und daraus einen Rechnungsentwurf erzeugen.
Der Prompt soll enthalten:
Vorlage / Textauszug
Projektkontext
Technologie
Paketstruktur
gewünschte Dateien
fachliche Regeln
Fehlerbehandlung
Tests
Akzeptanzkriterien
Grenzen, was nicht geändert werden darf
---
22. Musterlösung zur Übung
Vorlage / Textauszug
Aufgabe für Codex:
Ergänze im Modul apps/billing-service einen Kafka Consumer für das Event OrderCreated.
Kontext:
Java 21
Spring Boot
Package: com.seb4u.demo.spring.billing
Billing Service erzeugt Rechnungsentwürfe, aber versendet keine Rechnungen
Event kommt vom Order Service
Event enthält orderId, customerId, totalAmount und createdAt
Gewünschte Struktur:
api bleibt unverändert
Consumer liegt in infrastructure.messaging
Application Use Case liegt in application
Domänenobjekt InvoiceDraft liegt in domain
Repository Interface liegt in domain
Fachliche Regeln:
Für jedes OrderCreated Event wird maximal ein InvoiceDraft erzeugt
Verarbeitung muss idempotent sein
doppelte Events dürfen keine doppelte Rechnung erzeugen
bei fachlich ungültigem Event wird ein Fehler geloggt und das Event nicht verarbeitet
Fehlerbehandlung:
technische Fehler sollen Retry ermöglichen
dauerhaft ungültige Events sollen später in eine Dead Letter Queue gehen
keine Secrets oder personenbezogenen Daten loggen
Tests:
Unit Test für Use Case
Test für doppelte Event-Verarbeitung
Test für ungültiges Event
Integrationstest für Consumer kann als TODO dokumentiert werden, falls Testcontainer-Setup fehlt
Nicht ändern:
keine Änderung am Order Service
keine Änderung am Event-Namen
keine Änderung an bestehenden Datenbanktabellen ohne Migration
Akzeptanzkriterien:
mvn test erfolgreich
neuer Use Case ist getestet
Consumer delegiert an Anwendungsschicht
keine Fachlogik im Consumer
Das ist ein brauchbarer Enterprise-Prompt. Er führt das Werkzeug, ohne die Kontrolle abzugeben.
---
23. Merksätze
Vorlage / Textauszug
AI ersetzt keine Architekturverantwortung.
Codex ist stark bei konkreten Codeänderungen.
Claude Code ist stark bei Analyse, Refactoring-Planung und größeren Zusammenhängen.
Je konkreter Kontext, Grenzen und Akzeptanzkriterien sind, desto besser wird das Ergebnis.
AI-generierte Dokumentation muss projektbezogen, prüfbar und nicht generisch sein.
Secrets gehören niemals in Prompts.
Jede AI-Änderung braucht Tests, Review und Nachweis.
Wenn AI Fülltext erzeugt, wird der Abschnitt verworfen und neu geschrieben.
Teil G: Komplettes Beispielprojekt und große Codebasis
Teil G: Komplettes Beispielprojekt und große Codebasis
Konsolidiert aus Rohmaterial: Teil 13, Teil 36.
Komplettes Beispielprojekt
Order-to-Billing-End-to-End
Kompakte Themenübersicht
1. Ziel dieses Teils
In den bisherigen Teilen wurden Zielbild, Infrastruktur, Cloud, VM/Bare Metal, OpenShift, Security, moderne Anwendungen, Datenintegration, Observability, Backup, DevOps und AI-Unterstützung getrennt erklärt. In diesem Teil werden diese Bausteine zu einem zusammenhängenden Beispielprojekt verbunden.
Das Ziel ist nicht, eine winzige Demo mit einem Controller und einer Datenbank zu bauen. Das Ziel ist ein realistisches Enterprise-Skelett, das zeigt, wie mehrere Anwendungen, Plattformdefinitionen, Infrastrukturartefakte, Dokumentation und Betriebsunterlagen zusammengehören.
Das Beispielprojekt heißt:
Vorlage / Textauszug
modern-hybrid-enterprise-platform-lab
Es bildet eine hybride Plattform für die Alpine Retail & Services Group ab. Neue Anwendungen laufen auf OpenShift. Datenbanken, File-Verarbeitung und bestimmte Spezialprozesse können auf VM oder Bare Metal bleiben. Cloud-Dienste werden gezielt für Object Storage, Testumgebungen oder externe Integrationen verwendet.
Der wichtigste Gedanke dieses Teils lautet:
Vorlage / Textauszug
Ein Enterprise-Projekt besteht nicht aus einer Anwendung.
Es besteht aus Code, Infrastruktur, Security, Deployment, Betrieb, Dokumentation, Tests und Entscheidungen.
---
2. Gesamtstruktur des Repositories
Das Repository wird bewusst so aufgebaut, dass Verantwortungen sichtbar bleiben. Anwendungen liegen nicht neben zufälligen Skripten. Plattformdefinitionen werden nicht in App-Ordnern versteckt. Betriebsdokumentation liegt nicht irgendwo in einem Wiki, das niemand versioniert.
Diese Struktur ist absichtlich umfangreich. Sie zwingt dazu, jede Verantwortung an einen klaren Ort zu legen.
---
3. Fachlicher Ablauf des Beispielprojekts
Das Beispielprojekt bildet einen typischen Bestell- und Abrechnungsprozess ab.
Ein Kunde meldet sich im Customer Portal an. Die Anmeldung erfolgt über Keycloak. Das Portal ruft den Order Service auf. Der Order Service prüft die Bestellung, speichert sie in PostgreSQL und schreibt ein fachliches Event in eine Outbox-Tabelle. Ein Outbox Publisher veröffentlicht dieses Event an Kafka oder RabbitMQ. Der Billing Service konsumiert das Event und erzeugt eine Rechnung.
Parallel dazu können Partnerunternehmen Dateien liefern. Diese Dateien landen in Object Storage oder auf einem kontrollierten Übergabeverzeichnis. Der File Processing Service validiert die Dateien, schreibt Fehlerberichte und erzeugt Events für gültige Datensätze.
Das Reporting liest nicht direkt unkontrolliert aus allen Produktivtabellen. Stattdessen erhält es freigegebene Datenkopien, Exporte oder spezielle Reporting-Views. Dadurch wird verhindert, dass operative Systeme durch schwere Reports blockiert werden.
Der Ablauf sieht logisch so aus:
Skizze / Textauszug
Kunde
↓
Customer Portal
↓
Order Service
↓
PostgreSQL Orders
↓
Outbox Event
↓
Kafka oder RabbitMQ
↓
Billing Service
↓
PostgreSQL Billing
↓
Rechnung / Audit / Reporting
Der wichtigste technische Punkt ist die Trennung von fachlichen Verantwortungen. Der Order Service erstellt keine Rechnung. Der Billing Service nimmt keine Bestellung entgegen. Das Customer Portal greift nicht direkt auf Datenbanken zu. Reporting wird nicht zum versteckten Integrationsmonster.
---
4. Lokale Entwicklungsumgebung
Für die lokale Entwicklung wird nicht sofort ein vollständiger OpenShift Cluster benötigt. Entwickler sollen Order Service, Billing Service, PostgreSQL, Keycloak und Broker lokal starten können. Dafür gibt es ein Docker-Compose-Lab.
Diese Umgebung ist nicht Produktion. Sie ist eine kontrollierte Lern- und Entwicklungsumgebung. Sie zeigt Abhängigkeiten, ohne dass sofort alle Enterprise-Sicherheitsmechanismen aktiv sein müssen.
---
5. Order Service als Kernbeispiel
Der Order Service ist das zentrale Backend-Beispiel. Er nimmt Bestellungen entgegen, validiert Eingaben, speichert Daten und erzeugt Events.
Der Controller bleibt dünn. Er kennt HTTP, Validierung und Security-Annotation. Er entscheidet aber nicht selbst, wie eine Bestellung fachlich erzeugt wird.
Dieser Adapter schützt die fachliche Logik vor technischen Details. Wenn später ein anderer Persistenzmechanismus genutzt wird, muss nicht die gesamte Anwendungslogik umgebaut werden.
---
9. Outbox-Tabelle und Publisher
Der Outbox Publisher veröffentlicht Events nicht direkt aus der Transaktion heraus. Er speichert zuerst Events in der Datenbank. Danach verarbeitet ein separater Scheduler unveröffentlichte Events.
Der Vorteil ist nicht nur technische Zuverlässigkeit. Der Vorteil ist auch Betriebssichtbarkeit. Wenn Events hängen bleiben, kann man sie in der Outbox-Tabelle sehen.
---
10. Billing Service als Event Consumer
Der Billing Service reagiert auf OrderCreatedEvent. Er erstellt eine Rechnung, aber er verändert keine Bestellung. Damit bleibt die fachliche Verantwortung getrennt.
Idempotenz ist ein typisches Enterprise-Thema. Ohne Idempotenz werden Wiederholungen gefährlich. Mit Idempotenz werden Wiederholungen kontrollierbar.
---
12. Frontend: Customer Portal
Das Customer Portal ist eine moderne Webanwendung. Es zeigt Bestellungen an und ermöglicht das Erstellen neuer Bestellungen. Es speichert keine Secrets und ruft keine Datenbank direkt auf.
Dieses Deployment zeigt wichtige Betriebs- und Security-Entscheidungen: mehrere Replikate, Probes, Resource Limits und eingeschränkter SecurityContext.
Diese Pipeline ist eine Qualitätsgrenze. Code wird nicht einfach gebaut und deployt. Er wird getestet, gebaut und gescannt.
---
18. Testcontainers Integrationstest
java
package com.seb4u.demo.spring.order;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.testcontainers.service.connection.ServiceConnection;
import org.testcontainers.containers.PostgreSQLContainer;
import org.testcontainers.junit.jupiter.Container;
import org.testcontainers.junit.jupiter.Testcontainers;
@SpringBootTest@Testcontainersclass OrderServiceIntegrationTest {
@Container@ServiceConnectionstatic PostgreSQLContainer<?> postgres = new PostgreSQLContainer<>(class="str">"postgres:16")
.withDatabaseName(class="str">"orders")
.withUsername(class="str">"orders_user")
.withPassword(class="str">"orders_pw");
@Testvoid contextStartsWithRealPostgres() {
// Der Test prüft, dass Anwendung, Migrationen und Datenbankverbindung zusammen starten.
}
}
Testcontainers verhindert, dass Integrationstests nur gegen Mocks laufen. Dadurch werden Datenbankmigrationen und echte Verbindungsdetails früher sichtbar.
---
19. Observability im Beispielprojekt
Jeder produktionsnahe Service braucht Logs, Metriken und Health Checks.
Die Health-Endpunkte bleiben erreichbar, damit Kubernetes Probes funktionieren. Der Prometheus-Endpunkt wird eingeschränkt. Fachliche APIs verlangen Authentifizierung.
---
22. File Processing als hybrider Workload
Der File Processing Service ist bewusst nicht automatisch ein OpenShift-Service. Er kann auf VM oder Bare Metal laufen, wenn die Dateien sehr groß sind oder bestehende Storage-Prozesse genutzt werden.
Dieser Ausschnitt zeigt, dass Cloud-Ressourcen nicht nur erstellt, sondern auch klassifiziert, verschlüsselt und versioniert werden.
---
24. Reporting Service
Reporting ist ein häufiger Architektur-Stolperstein. Wenn Reports direkt auf operative Tabellen zugreifen, können sie Bestellprozesse verlangsamen. Deshalb muss Reporting bewusst entkoppelt werden.
Mögliche Strategien:
Vorlage / Textauszug
Reporting liest aus freigegebenen Views.
Reporting nutzt replizierte Daten.
Reporting erhält Events und baut eigene Projektionen.
Reporting läuft zeitgesteuert außerhalb der Hauptlastzeiten.
Reporting wird für große Auswertungen auf VM oder Bare Metal betrieben.
Ein Kubernetes CronJob für einen kleineren Report:
Für große Reports kann eine VM sinnvoller sein. Wichtig ist die fachliche Begründung.
---
25. ADR: Outbox für Domain Events
Vorlage / Textauszug
ADR 0003: Outbox Pattern für Domain Events
Status
Akzeptiert
Kontext
Der Order Service speichert Bestellungen in PostgreSQL und muss Billing über neue Bestellungen informieren. Eine direkte Veröffentlichung an den Broker innerhalb derselben fachlichen Aktion kann inkonsistent werden, wenn Datenbank oder Broker unterschiedlich reagieren.
Entscheidung
Der Order Service verwendet das Outbox Pattern. Fachliche Events werden in derselben Transaktion wie die Bestellung in einer Outbox-Tabelle gespeichert. Ein separater Publisher veröffentlicht unveröffentlichte Events an den Broker.
Konsequenzen
Der Service benötigt eine Outbox-Tabelle, einen Publisher, Monitoring für unveröffentlichte Events und ein Runbook für Backlogs. Billing Consumer müssen idempotent sein.
Dieser ADR ist kurz, aber wichtig. Er erklärt nicht nur die Lösung, sondern auch die Konsequenzen für Betrieb und Entwicklung.
---
26. End-to-End Testidee
Ein End-to-End-Test für das Lab prüft nicht jedes Detail, sondern den wichtigsten fachlichen Fluss.
Dieser Test zeigt die Verbindung zwischen Identity, API, Anwendung, Datenbank und Messaging.
---
27. Typische Fehler im Gesamtprojekt
Ein häufiger Fehler ist, alle Artefakte nach Technologie statt nach Verantwortung zu sortieren. Dann liegen wichtige Plattformdefinitionen verstreut, und niemand weiß, welcher Service welche Ressourcen braucht.
Ein zweiter Fehler ist fehlende Trennung zwischen App-Repository und GitOps-Repository. Wenn Anwendungscode automatisch direkt Cluster-Manifeste verändert, entstehen unkontrollierte Deployments.
Ein dritter Fehler ist, Security nur im Code zu betrachten. In Wahrheit entsteht Security auch durch NetworkPolicies, RBAC, Secrets, Image Scans, Audit Logs und Betriebsprozesse.
Ein vierter Fehler ist, VM- und Bare-Metal-Systeme als Sonderfälle ohne Automatisierung zu behandeln. Auch diese Systeme brauchen Baselines, Monitoring, Backups und Runbooks.
Ein fünfter Fehler ist, End-to-End-Abläufe nicht zu testen. Einzelne Services können funktionieren, während der Gesamtprozess trotzdem scheitert.
Erstelle aus diesem Beispiel eine kleinere Variante mit nur drei Anwendungen:
Vorlage / Textauszug
Customer Portal
Order Service
Billing Service
Lege fest:
Vorlage / Textauszug
welche Repositories oder Ordner du brauchst
welche Datenbanken existieren
welcher Broker verwendet wird
welche OpenShift Namespaces entstehen
welche Secrets benötigt werden
welche CI-Schritte verpflichtend sind
welches Runbook zuerst geschrieben wird
Die Übung ist bestanden, wenn du nicht nur Code nennst, sondern auch Betrieb, Security und Deployment berücksichtigst.
---
29. Musterlösung zur Übung
Eine mögliche Lösung:
Vorlage / Textauszug
Repository-Struktur:
apps/customer-portal
apps/order-service
apps/billing-service
platform/kustomize
platform/argocd
docs/adr
docs/runbooks
Datenbanken:
PostgreSQL orders
PostgreSQL billing
Broker:
RabbitMQ für lokalen Einstieg oder Kafka für größere Event-Streams
Namespaces:
customer-prod
order-prod
billing-prod
messaging-prod
platform-monitoring
Secrets:
order-db-secret
billing-db-secret
broker-credentials
keycloak-client-secret
CI-Schritte:
Build
Unit Tests
Integration Tests
Container Build
Image Scan
Manifest Linting
Erstes Runbook:
Outbox Backlog im Order Service
Diese Musterlösung ist bewusst klein, aber vollständig gedacht. Sie betrachtet Anwendungen nicht isoliert, sondern als Teil einer Plattform.
---
30. Merksätze
Vorlage / Textauszug
Ein gutes Enterprise-Repository zeigt Verantwortung, nicht nur Dateien.
Ein moderner Service besteht aus Code, Tests, Deployment, Security, Observability und Runbook.
GitOps macht den Zielzustand sichtbar.
Outbox schützt vor inkonsistenter Kommunikation zwischen Datenbank und Broker.
Idempotenz ist Pflicht, wenn Nachrichten wiederholt verarbeitet werden können.
VMs und Bare Metal sind nicht automatisch Legacy, wenn sie bewusst betrieben werden.
Cloud-Ressourcen brauchen dieselbe Disziplin wie Anwendungscode: Versionierung, Review, Security und Dokumentation.
Große Code- und Konfigurationsbeispiele
Ziel dieses Schritts
Dieser Schritt ergänzt keine allgemeinen Erklärungen, sondern konkrete technische Artefakte. Das Projekt soll dadurch näher an ein echtes Enterprise-Repository heranrücken. Der Schwerpunkt liegt auf zusammenhängendem Code: Ein Order Flow wird über REST, Use Case, Domäne, Persistenz, Outbox, Messaging, Billing Consumer, Tests, OpenShift Deployment, GitOps, Terraform/OpenTofu und Ansible beschrieben.
Die Beispiele sind bewusst nicht nur kleine Schnipsel. Sie zeigen, wie verschiedene Schichten zusammenspielen. Genau dadurch wird die spätere HTML größer, aber nicht künstlich. Der Umfang entsteht durch technische Substanz.
1. Order Service: REST Controller
Der Controller bleibt dünn. Er nimmt HTTP entgegen, validiert einfache Request-Struktur und übergibt die Arbeit an den Use Case. Fachlogik gehört nicht in den Controller.
Wichtig ist die klare Grenze: Der Controller weiß nichts über JPA, Outbox, Kafka oder Datenbanktransaktionen. Er übersetzt nur HTTP in einen Anwendungsbefehl.
2. Use Case mit Transaktionsgrenze
Die Transaktion liegt im Anwendungsservice. Dadurch werden Bestellung und Outbox-Event gemeinsam gespeichert. Wenn einer der beiden Schritte fehlschlägt, wird alles zurückgerollt.
Diese Struktur erlaubt später Integrationstests mit Testcontainers. Die fachliche Logik bleibt testbar, obwohl Persistenz und Outbox real angebunden werden können.
3. Domänenmodell für Order
Die Domäne schützt fachliche Regeln. Eine Bestellung ohne Positionen darf nicht entstehen. Negative Mengen oder negative Preise sind ebenfalls unzulässig.
java
package com.seb4u.demo.spring.order.domain;
import java.math.BigDecimal;
import java.time.Instant;
import java.util.List;
import java.util.Objects;
import java.util.UUID;
publicclass Order {
privatefinal UUID id;
privatefinal CustomerId customerId;
privatefinal List<OrderItem> items;
privatefinal Instant createdAt;
private OrderStatus status;
private Order(UUID id, CustomerId customerId, List<OrderItem> items, OrderStatus status, Instant createdAt) {
this.id = Objects.requireNonNull(id);
this.customerId = Objects.requireNonNull(customerId);
this.items = List.copyOf(validateItems(items));
this.status = Objects.requireNonNull(status);
this.createdAt = Objects.requireNonNull(createdAt);
}
publicstatic Order create(UUID id, CustomerId customerId, List<OrderItem> items, Instant createdAt) {
returnnew Order(id, customerId, items, OrderStatus.CREATED, createdAt);
}
public Money total() {
BigDecimal sum = items.stream()
.map(item -> item.unitPrice().amount().multiply(BigDecimal.valueOf(item.quantity())))
.reduce(BigDecimal.ZERO, BigDecimal::add);
returnnew Money(sum, class="str">"EUR");
}
publicvoid markSubmitted() {
if (status != OrderStatus.CREATED) {
thrownew IllegalStateException(class="str">"Only CREATED orders can be submitted");
}
this.status = OrderStatus.SUBMITTED;
}
privatestatic List<OrderItem> validateItems(List<OrderItem> items) {
if (items == null || items.isEmpty()) {
thrownew IllegalArgumentException(class="str">"Order must contain at least one item");
}
return items;
}
public UUID id() { return id; }
public CustomerId customerId() { return customerId; }
public List<OrderItem> items() { return items; }
public OrderStatus status() { return status; }
public Instant createdAt() { return createdAt; }
}
4. JPA-Adapter als Infrastruktur
Die Domäne soll nicht von JPA-Annotationen abhängig sein. Deshalb übernimmt ein Adapter die Übersetzung zwischen Domänenobjekt und Datenbankmodell.
Der Adapter wirkt länger als ein direkt annotiertes Domänenobjekt, bringt aber saubere Grenzen. Für größere Enterprise-Systeme ist diese Trennung oft wertvoll.
5. Outbox Writer
Der Outbox Writer serialisiert fachliche Events und speichert sie in einer Tabelle. Er veröffentlicht nicht direkt an Kafka. Diese Trennung verhindert Transaktionsprobleme.
Der Publisher läuft regelmäßig. Er liest unveröffentlichte Events, sendet sie an den Broker und markiert sie danach als veröffentlicht. Fehler werden gezählt und dokumentiert.
Diese Logik ist im Enterprise-Betrieb entscheidend. Broker garantieren nicht immer exakt einmalige fachliche Verarbeitung. Die Anwendung muss Wiederholungen aushalten.
8. Datenbankmigration für Idempotenz
sql
CREATETABLE processed_events (
event_id VARCHAR(120) PRIMARYKEY,
processed_at TIMESTAMP WITH TIME ZONE NOTNULL,
handler_name VARCHAR(160) NOTNULL
);
CREATETABLE invoices (
id UUID PRIMARYKEY,
order_id UUID NOTNULL,
customer_id VARCHAR(120) NOTNULL,
amount NUMERIC(12, 2) NOTNULL,
currency VARCHAR(3) NOTNULL,
status VARCHAR(40) NOTNULL,
created_at TIMESTAMP WITH TIME ZONE NOTNULL
);
CREATE UNIQUE INDEX ux_invoices_order_id ON invoices(order_id);
Die eindeutige Einschränkung auf order_id ist eine zweite Schutzlinie. Selbst wenn Idempotenz im Consumer fehlerhaft wäre, verhindert die Datenbank doppelte Rechnungen für dieselbe Bestellung.
9. Testcontainers-End-to-End-Test
Ein guter Integrationstest startet echte Infrastruktur in Containern. Dadurch werden Datenbankmigrationen, Repository, REST API und Outbox gemeinsam geprüft.
Der Test ist noch nicht vollständig, aber er zeigt die Richtung: echte Datenbank, echter HTTP-Aufruf, echte Migrationen. In einem nächsten Schritt würde man Outbox-Einträge direkt prüfen.
Der Zugriff auf Prometheus-Metriken ist hier bewusst nicht komplett offen. In produktionsnahen Umgebungen muss entschieden werden, ob Metriken intern frei lesbar sind oder ebenfalls geschützt werden.
11. React API Client mit OIDC Token
typescript
import { UserManager } fromclass="str">"oidc-client-ts";
export type CreateOrderRequest = {
customerId: string;
items: Array<{
productId: string;
quantity: number;
unitPrice: number;
}>;
};
exportclass OrderApiClient {
constructor(
private readonly baseUrl: string,
private readonly userManager: UserManager
) {}
async createOrder(request: CreateOrderRequest): Promise<{ orderId: string; status: string }> {
const user = await this.userManager.getUser();
if (!user || user.expired) {
thrownew Error(class="str">"User is not authenticated or token is expired");
}
const response = await fetch(`${this.baseUrl}/api/orders`, {
method: class="str">"POST",
headers: {
class="str">"Content-Type": class="str">"application/json",
class="str">"Authorization": `Bearer ${user.access_token}`,
class="str">"X-Correlation-ID": crypto.randomUUID()
},
body: JSON.stringify(request)
});
if (!response.ok) {
const text = await response.text();
thrownew Error(`Order API failed with ${response.status}: ${text}`);
}
returnawait response.json();
}
}
Das Frontend enthält keine Secrets. Es nutzt Tokens des angemeldeten Benutzers und sendet eine Correlation-ID, damit Logs über Frontend und Backend verbunden werden können.
Das Image läuft nicht als Root. JVM-Speicher wird containerfreundlich begrenzt. In einem gehärteten Build kämen zusätzlich SBOM, Image-Scan und Signatur dazu.
Für Produktion ist prune: false bewusst konservativ gewählt. Automatisches Löschen von Ressourcen kann sinnvoll sein, sollte aber kontrolliert eingeführt werden.
16. PrometheusRule für Outbox Backlog
yaml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: order-service-alerts
namespace: order-prod
spec:
groups:
- name: order-service.rules
rules:
- alert: OrderOutboxBacklogHigh
expr: order_outbox_unpublished_events > 100for: 10m
labels:
severity: warning
team: order
annotations:
summary: class="str">"Order Outbox backlog is high"
description: class="str">"More than 100 unpublished events for over 10 minutes. Check broker, publisher job and database locks."
- alert: OrderServiceReadinessFailing
expr: kube_pod_container_status_ready{namespace=class="str">"order-prod",container=class="str">"order-service"} == 0for: 5m
labels:
severity: critical
team: order
annotations:
summary: class="str">"Order Service pod is not ready"
description: class="str">"At least one Order Service pod is not ready for more than five minutes."
Alerts müssen konkrete Handlungen auslösen. Ein Alert ohne Runbook ist oft nur Lärm.
17. Terraform/OpenTofu: Object Storage für Partnerdateien
hcl
variable class="str">"environment" {
type = string
description = class="str">"Environment name such as dev, test or prod"
}
resourceclass="str">"aws_s3_bucket" class="str">"partner_files" {
bucket = class="str">"alpine-partner-files-${var.environment}"
tags = {
owner = class="str">"team-integration"
environment = var.environment
data_class = class="str">"internal"
operational_use = class="str">"file-processing"
}
}
resourceclass="str">"aws_s3_bucket_versioning" class="str">"partner_files" {
bucket = aws_s3_bucket.partner_files.id
versioning_configuration {
status = class="str">"Enabled"
}
}
resourceclass="str">"aws_s3_bucket_lifecycle_configuration" class="str">"partner_files" {
bucket = aws_s3_bucket.partner_files.id
rule {
id = class="str">"expire-rejected-after-90-days"
status = class="str">"Enabled"
filter {
prefix = class="str">"rejected/"
}
expiration {
days = 90
}
}
}
Dieses Beispiel zeigt Kosten- und Betriebsdenken. Abgelehnte Dateien bleiben nicht unbegrenzt liegen.
18. Ansible: File Processing Worker als VM-Service
Diese Pipeline bricht bei kritischen Schwachstellen ab. In echten Projekten braucht es zusätzlich Ausnahmen mit Ablaufdatum, damit Sicherheitswarnungen nicht dauerhaft ignoriert werden.
21. Runbook: Outbox Backlog
Vorlage / Textauszug
Runbook: Order Outbox Backlog
Symptom
Alert `OrderOutboxBacklogHigh` ist aktiv. Die Metrik `order_outbox_unpublished_events` liegt länger als zehn Minuten über 100.
Der Order Service speichert Bestellungen in PostgreSQL und muss fachliche Events an Billing und Reporting veröffentlichen. Eine direkte Veröffentlichung an Kafka innerhalb des Use Case wäre riskant, weil Datenbanktransaktion und Broker-Veröffentlichung nicht atomar sind.
Entscheidung
Der Order Service schreibt fachliche Events in eine Outbox-Tabelle innerhalb derselben Transaktion wie die Bestellung. Ein separater Publisher veröffentlicht die Events an Kafka und markiert sie danach als veröffentlicht.
Konsequenzen
Das System wird robuster gegenüber temporären Broker-Ausfällen. Dafür entsteht ein zusätzlicher Betriebsaspekt: Die Outbox muss überwacht werden. Es braucht Metriken, Alerts und ein Runbook für Backlog-Situationen.
23. Abschluss dieses Schritts
Dieser Teil ergänzt zusammenhängende technische Substanz. Die Beispiele bilden eine Brücke zwischen Fachbuch und echtem Repository. Sie zeigen, wie Architekturentscheidungen in Code, YAML, Tests, Infrastruktur und Runbooks sichtbar werden.
Für die spätere finale HTML-Version ist dieser Schritt wichtig, weil die Datei durch echten Code wächst. Die Größe entsteht nicht durch wiederholte Absätze, sondern durch konkrete Artefakte.
Teil H: Praxisfälle, Betriebsstörungen und End-to-End-Szenarien
Teil H: Praxisfälle, Betriebsstörungen und End-to-End-Szenarien
Konsolidiert aus Rohmaterial: Teil 31, Teil 34, Teil 37.
Finaler End-to-End-Praxissprint und HTML-Masterbuild
Ziel dieses großen Schritts
Dieser Teil führt das bisherige Lernbuch aus der reinen Planung in einen zusammenhängenden Praxissprint. Der Schwerpunkt liegt nicht auf einer weiteren Theorie-Erweiterung, sondern auf einem End-to-End-Durchlauf, der alle bisherigen Themen verbindet: Fachprozess, Anwendungscode, Datenbank, Eventing, Security, OpenShift, GitOps, Observability, Backup, Runbook und Qualitätsprüfung. Dadurch entsteht ein konkreter roter Faden für die spätere HTML-Version.
Der Sprint beantwortet eine einfache, aber realistische Enterprise-Frage: Was passiert technisch und organisatorisch, wenn ein Kunde im Customer Portal eine Bestellung anlegt, diese Bestellung gespeichert wird, ein Event erzeugt wird, Billing daraus eine Rechnung vorbereitet, der Betrieb den Ablauf überwacht und ein Fehlerfall über Runbook und GitOps nachvollziehbar behandelt wird?
Wichtig ist: Dieser Schritt ist kein künstlicher Zusatzblock. Er fasst die Fachkapitel praktisch zusammen und zeigt, wie die Architektur im Alltag funktioniert.
Ausgangsszenario
Die Alpine Retail & Services Group möchte einen produktionsnahen Durchlauf für das neue hybride Plattformmodell durchführen. Der Durchlauf soll klein genug sein, um in einem Lab umgesetzt zu werden, aber vollständig genug, um typische Enterprise-Fragen zu beantworten. Deshalb wird kein isolierter Demo-Service gebaut, sondern ein zusammenhängender Ablauf.
Der fachliche Ablauf lautet:
Vorlage / Textauszug
Kunde meldet sich im Customer Portal an.
Kunde legt eine Bestellung an.
Order Service validiert die Bestellung.
Order Service speichert Bestellung und Outbox Event in PostgreSQL.
Outbox Publisher veröffentlicht OrderCreated an Kafka oder RabbitMQ.
Billing Service konsumiert das Event idempotent.
Billing Service erzeugt einen Rechnungsentwurf.
Reporting Service kann den Status auswerten.
Observability zeigt Logs, Metriken und Trace.
Runbook beschreibt Fehleranalyse bei Backlog oder fehlgeschlagenem Billing.
GitOps stellt sicher, dass Deployment und Infrastruktur nachvollziehbar bleiben.
Dieser Ablauf verbindet moderne Anwendung, Daten, Messaging, Security, Betrieb und Plattform.
Die Architektur zeigt zwei wichtige Prinzipien. Erstens: Das Portal greift nicht direkt auf Datenbanken zu. Zweitens: Billing hängt nicht synchron am Order Service, sondern verarbeitet ein fachliches Event. Dadurch bleibt der Bestellprozess stabiler, auch wenn Billing kurzzeitig nicht verfügbar ist.
Fachliche Schnittstelle des Order Service
Die REST-Schnittstelle soll bewusst klein und klar sein. Der Order Service nimmt eine Bestellung entgegen und gibt eine technische sowie fachliche Bestätigung zurück. Die API soll keine internen Datenbankdetails offenlegen.
Die API ist bewusst nicht überladen. Ein späteres Admin-Portal kann zusätzliche Endpunkte bekommen, aber das Kundenportal braucht nur einen klaren Bestell-Endpunkt.
Spring Boot Controller
Der Controller bleibt dünn. Er übersetzt HTTP in einen Use Case und kümmert sich nicht um Datenbankdetails oder Event-Veröffentlichung.
Der Controller enthält absichtlich keine Speicherung. Dadurch bleibt die Grenze zwischen Webschicht und Anwendungsschicht sichtbar.
Domänenmodell für Bestellung
Die Domäne beschreibt fachliche Regeln. Eine Bestellung ohne Positionen ist ungültig. Eine Position mit Menge null ist ebenfalls ungültig. Solche Regeln gehören nicht nur in das Frontend, sondern in die Backend-Domäne.
Ein gutes Event enthält genug Information für den Consumer, aber nicht beliebig viele interne Details. Billing muss wissen, welche Bestellung entstanden ist und welcher Betrag relevant ist. Billing muss nicht wissen, welche interne JPA-Entity verwendet wurde.
Outbox Writer
Der Outbox Writer speichert das Event in derselben Transaktion wie die Bestellung. Genau dadurch wird verhindert, dass Datenbankzustand und Eventstrom auseinanderlaufen.
Der Writer kommuniziert nicht direkt mit Kafka oder RabbitMQ. Dadurch bleibt die Transaktion kurz und kontrollierbar.
Outbox Publisher
Der Publisher läuft separat. Er liest unveröffentlichte Events und sendet sie an den Broker. Wenn der Broker nicht erreichbar ist, bleibt das Event in der Outbox und kann später erneut verarbeitet werden.
java
package com.seb4u.demo.spring.order.infrastructure.messaging;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import java.time.Instant;
import java.util.List;
import java.util.UUID;
@Componentpublicclass OutboxPublisher {
privatefinal JdbcTemplate jdbcTemplate;
privatefinal EventBrokerClient brokerClient;
privatefinal Counter publishedCounter;
privatefinal Counter failedCounter;
public OutboxPublisher(JdbcTemplate jdbcTemplate, EventBrokerClient brokerClient, MeterRegistry registry) {
this.jdbcTemplate = jdbcTemplate;
this.brokerClient = brokerClient;
this.publishedCounter = Counter.builder(class="str">"outbox_events_published_total").register(registry);
this.failedCounter = Counter.builder(class="str">"outbox_events_failed_total").register(registry);
}
@Scheduled(fixedDelayString = class="str">"${outbox.publisher.delay:5000}")
publicvoid publishBatch() {
List<OutboxRecord> records = findNextRecords();
for (OutboxRecord record : records) {
publishOne(record);
}
}
@Transactionalprotectedvoid publishOne(OutboxRecord record) {
try {
brokerClient.publish(record.eventType(), record.payload());
jdbcTemplate.update(class="str">"update outbox_events set published_at = ? where id = ?", Instant.now(), record.id());
publishedCounter.increment();
} catch (Exception ex) {
jdbcTemplate.update(class="str">"""
update outbox_events
set publish_attempts = publish_attempts + 1, last_error = ?
where id = ?
class="str">""", ex.getMessage(), record.id());
failedCounter.increment();
}
}
private List<OutboxRecord> findNextRecords() {
return jdbcTemplate.query(class="str">"""
select id, event_type, payload::text
from outbox_events
where published_at is null
order by created_at
limit 50class="str">""", (rs, rowNum) -> new OutboxRecord(
UUID.fromString(rs.getString(class="str">"id")),
rs.getString(class="str">"event_type"),
rs.getString(class="str">"payload")
));
}
}
In produktionsnahen Umgebungen würde man zusätzlich Locking oder SKIP LOCKED verwenden, wenn mehrere Publisher parallel laufen. Das Prinzip bleibt gleich: Events werden kontrolliert und wiederholbar veröffentlicht.
Billing Consumer mit Idempotenz
Ein Consumer muss damit rechnen, dass Events mehrfach ankommen. Das ist kein Sonderfall, sondern ein normales Verhalten in verteilten Systemen. Billing speichert deshalb verarbeitete Event-IDs.
Idempotenz ist hier kein Luxus. Ohne Idempotenz könnte eine Rechnung mehrfach erzeugt werden, wenn ein Event erneut zugestellt wird.
Datenbankmigration für Billing
sql
CREATETABLE invoice_drafts (
id UUID PRIMARYKEY,
order_id UUID NOTNULL,
customer_id VARCHAR(80) NOTNULL,
total_amount NUMERIC(12, 2) NOTNULL,
status VARCHAR(40) NOTNULL,
created_at TIMESTAMP WITH TIME ZONE NOTNULL
);
CREATE UNIQUE INDEX uq_invoice_drafts_order_id
ON invoice_drafts(order_id);
CREATETABLE processed_events (
event_id UUID PRIMARYKEY,
event_type VARCHAR(120) NOTNULL,
processed_at TIMESTAMP WITH TIME ZONE NOTNULL
);
CREATETABLE billing_audit_log (
id UUID PRIMARYKEY,
action VARCHAR(120) NOTNULL,
reference_id VARCHAR(120) NOTNULL,
message TEXT NOTNULL,
created_at TIMESTAMP WITH TIME ZONE NOTNULL
);
Die eindeutige Einschränkung auf order_id verhindert doppelte Rechnungsentwürfe zusätzlich auf Datenbankebene. Das ist wichtig, weil fachliche Sicherheit nicht nur im Code liegen sollte.
Security-Durchlauf
Der Kunde authentifiziert sich über Keycloak. Das Portal erhält ein Access Token. Der Order Service prüft das Token und die Rolle. Der Billing Service ist nicht direkt vom Browser erreichbar. Interne Service-zu-Service-Kommunikation wird über Netzwerkregeln, ServiceAccounts und technische Credentials abgesichert.
Die Rollen können grob so aussehen:
Vorlage / Textauszug
CUSTOMER: darf eigene Bestellung anlegen und anzeigen.
SUPPORT_AGENT: darf Bestellungen suchen und Status prüfen.
BILLING_OPERATOR: darf Rechnungsentwürfe prüfen.
PLATFORM_OPERATOR: darf Deployments und Logs einsehen.
SECURITY_AUDITOR: darf Auditnachweise lesen, aber keine Fachänderungen durchführen.
Diese Rollen dürfen nicht ungeprüft als Adminrechte im Cluster verwendet werden. Fachliche Rollen und Kubernetes-RBAC sind unterschiedliche Ebenen.
Health-Endpunkte dürfen erreichbar sein, damit OpenShift Probes funktionieren. Metriken werden restriktiver behandelt, weil sie interne Informationen enthalten können.
Kubernetes-Manifeste für den Sprint
Das Lab verwendet eine klare Trennung zwischen Anwendung und Umgebung. Die Basisdefinition beschreibt den Service allgemein. Umgebungsspezifische Werte liegen in Overlays.
Die Probes sorgen dafür, dass OpenShift den Zustand der Anwendung verstehen kann. Ressourcen verhindern, dass ein Service unbegrenzt CPU oder Speicher nutzt.
Diese Policy macht die Architekturregel technisch sichtbar: Order darf zur Datenbank, zum Broker und zur Identität. Es darf nicht beliebig zu allen anderen Services sprechen.
prune ist hier bewusst deaktiviert. In produktionsnahen Umgebungen wird automatisches Löschen oft vorsichtiger behandelt als automatisches Aktualisieren.
Observability im Sprint
Der Sprint braucht drei Arten von Beobachtbarkeit.
Erstens: Logs. Jeder Request bekommt eine Trace-ID. Fehler werden strukturiert geloggt. Fachliche IDs wie orderId oder eventId werden ergänzt, aber sensible Daten wie Tokens oder personenbezogene Details werden nicht in Logs geschrieben.
Zweitens: Metriken. Der Order Service liefert Metriken zu HTTP-Anfragen, Datenbankverbindungen, Outbox-Backlog und Fehlern bei Event-Veröffentlichung.
Drittens: Traces. Ein Trace verbindet Portal, Order Service, Outbox Publisher und Billing. Dadurch kann man erkennen, wo ein Ablauf langsam oder fehlerhaft wird.
PrometheusRule für Outbox Backlog
yaml
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: order-service-alerts
namespace: order-prod
spec:
groups:
- name: order-service.rules
rules:
- alert: OrderOutboxBacklogGrowing
expr: order_outbox_unpublished_events > 100for: 10m
labels:
severity: warning
team: order
annotations:
summary: class="str">"Order outbox backlog grows"
description: class="str">"More than 100 unpublished outbox events exist for longer than 10 minutes."
- alert: OrderServiceHighErrorRate
expr: rate(http_server_requests_seconds_count{status=~class="str">"5.."}[5m]) > 1for: 5m
labels:
severity: critical
team: order
annotations:
summary: class="str">"Order service returns many server errors"
description: class="str">"The Order Service has an elevated 5xx error rate."
Alerts sind nur nützlich, wenn sie mit Runbooks verbunden sind. Sonst erzeugen sie Lärm statt Hilfe.
Runbook: Outbox Backlog wächst
Vorlage / Textauszug
Runbook: Order Outbox Backlog wächst
Symptom
Der Alert `OrderOutboxBacklogGrowing` ist aktiv. Die Anzahl unveröffentlichter Events steigt seit mindestens 10 Minuten.
Sofortprüfung
oc get pods -n order-prod -l app.kubernetes.io/name=order-service
Publisher läuft nicht oder ist falsch konfiguriert.
Entscheidung
Wenn Broker nicht erreichbar ist, kein manueller Datenbankeingriff.
Wenn Payload inkompatibel ist, fehlerhafte Events sichern und fachlich bewerten.
Wenn nur Publisher-Konfiguration fehlerhaft ist, GitOps-Konfiguration korrigieren und ausrollen.
Dieses Runbook verbindet Alert, Anwendung, Datenbank und Plattform. Genau das ist der Zweck eines produktionsnahen Betriebsdokuments.
Testcontainers-End-to-End-Test
Der End-to-End-Test startet PostgreSQL und einen Broker. Er prüft nicht jedes Detail, aber den wichtigsten Pfad: Bestellung anlegen, Outbox Event speichern, Event verarbeiten.
Die Pipeline baut nicht nur Java. Sie prüft auch, ob die Kubernetes-Manifeste renderbar sind. Dadurch werden YAML-Fehler früher sichtbar.
Pull-Request-Abnahme für diesen Sprint
Ein Pull Request für den End-to-End-Sprint ist nur fertig, wenn mehrere Perspektiven erfüllt sind.
Vorlage / Textauszug
Code: Controller, Use Case, Domäne, Persistenz und Outbox sind getestet.
Datenbank: Migrationen sind vorhanden und rückwärtskompatibel bewertet.
Security: Endpunkte sind geschützt und Rollen dokumentiert.
OpenShift: Deployment, Service, Route, ConfigMap, Secret-Referenz und NetworkPolicy existieren.
GitOps: Argo CD Application zeigt auf ein nachvollziehbares Overlay.
Observability: Logs, Metriken und Alerts sind vorhanden.
Runbook: mindestens ein realer Fehlerfall ist beschrieben.
Dokumentation: README und ADR wurden aktualisiert.
Diese Liste verhindert, dass ein Feature nur aus Anwendungscode besteht.
ADR: Outbox statt synchronem Billing-Aufruf
Vorlage / Textauszug
ADR: Order Service verwendet Outbox statt synchronem Billing-Aufruf
Status
Akzeptiert
Kontext
Beim Anlegen einer Bestellung muss Billing über neue Bestellungen informiert werden. Eine direkte synchrone Kommunikation vom Order Service zum Billing Service würde den Bestellprozess abhängig von der Verfügbarkeit des Billing Service machen.
Entscheidung
Der Order Service speichert ein OrderCreated Event in einer Outbox-Tabelle innerhalb derselben Datenbanktransaktion wie die Bestellung. Ein separater Publisher veröffentlicht das Event an den Broker. Billing konsumiert das Event idempotent.
Konsequenzen
Der Bestellprozess bleibt auch dann stabil, wenn Billing kurzzeitig nicht erreichbar ist. Dafür entsteht zusätzlicher Betriebsaufwand für Outbox Monitoring, Publisher und Backlog-Runbooks.
Dieser ADR zeigt eine echte Architekturentscheidung. Es geht nicht nur darum, ein Pattern zu nennen, sondern die Konsequenzen für Betrieb und Fehlerfälle zu dokumentieren.
Fehlerfall: Billing verarbeitet Event nicht
Ein typischer Fehlerfall im Sprint ist: Bestellung wurde angelegt, aber im Billing gibt es keinen Rechnungsentwurf. Die Analyse darf nicht raten, sondern muss entlang der Architektur laufen.
Prüfreihenfolge:
Vorlage / Textauszug
Existiert die Bestellung in PostgreSQL Orders?
Existiert ein Outbox Event?
Wurde das Event veröffentlicht?
Hat der Broker das Event angenommen?
Hat Billing das Event konsumiert?
Ist das Event in processed_events markiert?
Gibt es einen Fehler im billing_audit_log?
Gibt es Logs mit derselben traceId oder eventId?
Diese Reihenfolge reduziert Chaos. Jede Stufe prüft einen konkreten Übergang.
Betriebsentscheidung: manuelle Korrektur oder Replay?
Wenn Billing ein Event nicht verarbeitet hat, ist die Versuchung groß, manuell in der Datenbank etwas zu korrigieren. Das ist gefährlich. Zuerst muss geklärt werden, ob ein Replay möglich ist.
Ein Replay ist sinnvoll, wenn das Event korrekt ist und nur die Verarbeitung temporär fehlgeschlagen ist. Eine manuelle fachliche Korrektur ist nötig, wenn das Event selbst falsche Daten enthält oder eine fachliche Sonderentscheidung erforderlich ist.
Das Runbook muss deshalb zwischen technischen und fachlichen Fehlern unterscheiden.
Finale HTML-Relevanz dieses Schritts
Dieser Praxissprint ist wichtig für die spätere HTML-Datei, weil er viele vorherige Einzelthemen verbindet. In der HTML-Navigation darf dieser Schritt nicht als künstlicher Anhang erscheinen. Er soll als eigenes Hauptkapitel im Bereich Praxis und Masterbuild stehen.
Die HTML-Ausgabe muss dafür folgende Regeln einhalten:
Suchfunktion: optionaler Komfort, nicht Voraussetzung
Abnahme dieses großen Schritts
Dieser Teil ist abgenommen, wenn folgende Punkte erfüllt sind:
Vorlage / Textauszug
Der End-to-End-Ablauf ist fachlich verständlich.
Order, Billing, Outbox und Broker sind verbunden.
Security ist im Ablauf integriert.
OpenShift-Manifeste sind enthalten.
GitOps ist enthalten.
Observability ist enthalten.
Runbook ist enthalten.
ADR ist enthalten.
Test und CI sind enthalten.
Der Inhalt besteht nicht aus Fülltabellen.
Der Inhalt enthält keine generischen Serientitel.
Übung
Erweitere den Sprint um einen Fehlerfall: Der Broker ist erreichbar, aber Billing lehnt das Event wegen inkompatiblem Payload ab.
Beschreibe:
Vorlage / Textauszug
Welche Logs entstehen?
Welche Metrik steigt?
Welche Tabelle zeigt den Fehler?
Welches Runbook wird verwendet?
Welche Änderung muss über GitOps ausgerollt werden?
Ob ein Replay erlaubt ist.
Musterlösung
Eine mögliche Lösung:
Vorlage / Textauszug
Billing schreibt einen strukturierten Fehlerlog mit eventId, eventType und Validierungsfehler. Die Metrik billing_events_failed_total steigt. Das Event wird nicht als verarbeitet markiert. Wenn eine Dead Letter Queue verwendet wird, landet das Event dort; sonst bleibt die Verarbeitung im Fehlerstatus sichtbar.
Das Runbook für Billing-Eventfehler wird verwendet. Zuerst wird geprüft, ob der Payload fachlich korrekt ist. Wenn die Änderung nur eine Consumer-Inkompatibilität ist, wird Billing über Git korrigiert, die Pipeline ausgeführt und das Deployment über Argo CD synchronisiert.
Ein Replay ist erlaubt, wenn das ursprüngliche Event fachlich korrekt war und keine doppelte Rechnung erzeugt wurde. Die Idempotenzprüfung über processed_events und den eindeutigen Index auf order_id schützt zusätzlich vor doppelten Rechnungsentwürfen.
Merksätze
Vorlage / Textauszug
Ein End-to-End-Sprint ist wertvoller als zehn isolierte Demo-Blöcke.
Outbox löst kein Betriebsproblem automatisch; sie macht es kontrollierbar.
Idempotenz ist Pflicht, wenn Events erneut zugestellt werden können.
GitOps ist nicht nur Deployment, sondern Nachvollziehbarkeit.
Observability beginnt nicht nach dem Go-live, sondern während der Umsetzung.
Große Praxis-Szenarien für echte Enterprise-Tiefe
Ziel dieses Teils
Dieser Teil ergänzt keine künstlichen Erweiterungen, sondern echte Praxisfälle. Die bisherigen Kapitel erklären Architektur, Infrastruktur, OpenShift, Security, Daten, Betrieb, DevOps und AI-Unterstützung. Jetzt werden diese Themen in langen, zusammenhängenden Szenarien verbunden. Genau so entsteht aus Einzelwissen ein belastbares Enterprise-Verständnis.
Ein Praxis-Szenario ist nur dann wertvoll, wenn es mehrere Ebenen verbindet:
fachlicher Auslöser
beteiligte Anwendungen
Infrastrukturpfad
Security-Entscheidung
Datenfluss
Fehlerbild
Monitoring-Sicht
Betriebsreaktion
Dokumentationsnachweis
Lernkontrolle
Die folgenden Szenarien sind bewusst ausführlich. Sie ersetzen keine Tabellen, sondern erzählen den Ablauf so, wie er in einem echten Projekt sichtbar wird.
---
Szenario 1: Bestellung von Customer Portal bis Billing
Ausgangssituation
Ein Kunde meldet sich im Customer Portal an und legt eine Bestellung an. Das Portal läuft als moderne Webanwendung auf OpenShift. Der Login erfolgt über Keycloak. Nach erfolgreicher Anmeldung erhält das Frontend ein Token. Dieses Token wird bei API-Aufrufen an das Backend mitgegeben.
Der Order Service nimmt die Bestellung entgegen, prüft fachliche Regeln und speichert die Bestellung in PostgreSQL. Gleichzeitig schreibt er ein Outbox Event in dieselbe Datenbanktransaktion. Ein Outbox Publisher veröffentlicht dieses Event später an Kafka oder RabbitMQ. Der Billing Service konsumiert das Event und erzeugt daraus einen Rechnungsentwurf.
Der wichtigste Punkt: Der Billing Service ruft nicht direkt die Order-Datenbank ab. Er reagiert auf ein fachliches Event. Dadurch bleibt der Datenbesitz klar getrennt.
Ablauf im Zielbild
Skizze / Textauszug
Kunde
↓
Customer Portal
↓
Keycloak Login
↓
API Gateway / OpenShift Route
↓
Order Service
↓
PostgreSQL Orders
↓
Outbox Event
↓
Kafka oder RabbitMQ
↓
Billing Service
↓
PostgreSQL Billing
↓
Rechnungsentwurf
Warum dieser Ablauf gut ist
Die Bestellung wird im Order Service konsistent gespeichert. Das Event wird nicht direkt im Controller an Kafka geschickt, sondern über das Outbox Pattern abgesichert. Dadurch kann der Broker kurzfristig ausfallen, ohne dass die Bestellung verloren geht. Der Publisher kann später erneut versuchen, das Event zu senden.
Der Billing Service ist fachlich entkoppelt. Er braucht nicht zu wissen, wie der Order Service seine Tabellen intern strukturiert. Er erhält ein Ereignis, das für ihn fachlich relevant ist: Eine Bestellung wurde erstellt.
Der Kunde sieht im Portal: „Bestellung wurde angenommen“. Im Billing-System entsteht aber keine Rechnung. Entwickler vermuten zuerst einen Fehler im Billing Service. Der eigentliche Fehler liegt jedoch oft in der Mitte: Die Outbox wächst an, weil der Broker nicht erreichbar ist oder die Publisher-Konfiguration falsch ist.
Systematische Analyse
bash
# Order Service prüfen
oc get pods -n order-prod -l app=order-service
oc logs -n order-prod deployment/order-service --tail=200
# Outbox-Metriken prüfen
curl -s http://order-service:8080/actuator/prometheus | grep outbox
# Datenbank prüfen
psql class="str">"$ORDER_DB" -c class="str">"select count(*) from outbox_events where published_at is null;"
# Broker-Erreichbarkeit prüfen
oc rsh -n order-prod deployment/order-service
nc -vz kafka.messaging.svc.cluster.local 9092
Betriebsentscheidung
Wenn die Outbox wächst, darf man nicht blind Pods neu starten. Zuerst muss klar sein, ob Events noch sicher in der Datenbank liegen. Wenn ja, ist die fachliche Bestellung nicht verloren. Der Betrieb muss dann den Publisher-Pfad reparieren und danach kontrollieren, ob die Events abgearbeitet werden.
Nachweisartefakte
README des Order Service erklärt Outbox-Verhalten.
ADR dokumentiert, warum Outbox statt direktem Broker-Senden genutzt wird.
PrometheusRule alarmiert bei wachsender Outbox.
Runbook beschreibt Analyse und sichere Wiederaufnahme.
Integrationstest prüft Bestellung plus Outbox-Eintrag.
---
Szenario 2: Datenbankausfall und kontrollierter Restore
Ausgangssituation
Die Orders-Datenbank läuft auf Bare Metal, weil sie hohe I/O-Anforderungen hat. Eines Morgens melden mehrere Services Fehler. Das Customer Portal zeigt keine Bestellungen mehr an. Der Order Service liefert HTTP 503. Billing läuft noch, kann aber keine neuen Order Events verarbeiten.
Der erste Impuls wäre: Datenbank neu starten. In einem Enterprise-System reicht das nicht. Es muss entschieden werden, ob es ein kurzzeitiger Verbindungsfehler, ein Storage-Problem, ein beschädigter Index, ein voller Datenträger oder ein echter Datenverlust ist.
Analysepfad
Skizze / Textauszug
Symptom im Portal
↓
API Fehler
↓
Order Service Readiness rot
↓
Datenbankverbindung schlägt fehl
↓
DBA prüft Bare-Metal-Host
↓
Storage und PostgreSQL Logs prüfen
↓
Entscheidung: Neustart, Reparatur oder Restore
Prüfung im Cluster
bash
oc get pods -n order-prod
oc describe pod -n order-prod -l app=order-service
oc logs -n order-prod deployment/order-service --tail=100
oc get events -n order-prod --sort-by=.lastTimestamp
Ein Restore darf nicht reflexartig durchgeführt werden. Vorher müssen RPO und RTO geprüft werden.
RPO beantwortet: Wie viele Daten dürfen maximal verloren gehen?
RTO beantwortet: Wie schnell muss das System wieder laufen?
Wenn WAL-Archivierung aktiv ist, kann ein Point-in-Time-Recovery möglich sein. Wenn nur nächtliche Backups existieren, wäre ein Restore auf den letzten Nachtstand ein fachliches Risiko.
Beispiel: Restore-Runbook-Auszug
Vorlage / Textauszug
Runbook: Orders-Datenbank Restore
Vorbedingungen
Incident Ticket ist eröffnet.
Fachbereich wurde informiert.
Letzter konsistenter Backup-Zeitpunkt ist bekannt.
WAL-Archivstatus wurde geprüft.
Restore-Zielzeitpunkt wurde freigegeben.
Schritte
Schreibzugriffe auf Order Service deaktivieren.
Aktuellen Zustand der beschädigten Datenbank sichern.
Restore auf separatem Host oder separatem Volume durchführen.
Konsistenzprüfung ausführen.
Fachliche Stichproben durchführen.
Anwendung gegen Restore-Ziel testen.
Umschaltung freigeben.
Nachkontrolle der Outbox und Billing-Verarbeitung durchführen.
Wichtiger Lernpunkt
Backup ist erst bewiesen, wenn Restore getestet wurde. Eine Backup-Datei allein ist kein Betriebsnachweis. Der Nachweis entsteht erst durch einen erfolgreichen Restore-Test mit dokumentiertem Ergebnis.
---
Szenario 3: NetworkPolicy blockiert Billing
Ausgangssituation
Nach einem Security-Hardening kann der Billing Service keine Events mehr aus Kafka konsumieren. Die Pods laufen, die Anwendung startet, aber die Lag-Metrik steigt. Im Log steht nur ein Timeout zum Broker.
Das Team vermutet zuerst Kafka. Kafka ist aber gesund. Der Fehler liegt in einer neuen NetworkPolicy, die Egress aus dem Billing Namespace zu streng blockiert.
Warum das realistisch ist
NetworkPolicies sind wichtig, aber sie verändern Kommunikationspfade. Wenn sie ohne genaue Service-Abhängigkeiten eingeführt werden, können funktionierende Systeme plötzlich isoliert werden.
Die Policy wird nicht manuell im Cluster korrigiert, sondern im GitOps-Repository angepasst. Danach synchronisiert Argo CD den Zustand. So bleibt nachvollziehbar, warum die Freigabe existiert.
Nachweis
Pull Request mit Änderung der NetworkPolicy
Review durch Security oder Platform Team
Argo CD Sync-Historie
sinkender Kafka Consumer Lag
Incident-Kommentar mit Ursache und Prävention
---
Szenario 4: Keycloak-Rollenproblem im Admin Portal
Ausgangssituation
Interne Mitarbeiter melden, dass sie sich im Admin Portal anmelden können, aber keine Bestellungen sehen. Das Frontend lädt, der Login funktioniert, aber API-Aufrufe liefern HTTP 403.
Das ist ein wichtiger Unterschied:
Vorlage / Textauszug
401 bedeutet: nicht authentifiziert.
403 bedeutet: authentifiziert, aber nicht berechtigt.
Der Fehler liegt daher nicht im Login selbst, sondern im Rollen- oder Berechtigungsmodell.
Mögliche Ursachen
Rolle fehlt im Keycloak Client.
Benutzer ist nicht in der richtigen Gruppe.
Rollen werden im Token nicht als erwarteter Claim geliefert.
Spring Security liest falschen Claim.
API erwartet andere Authority-Namen als im Token vorhanden.
Identity ist nicht nur Login. Ein Benutzer kann korrekt angemeldet sein und trotzdem keine Berechtigung haben. Deshalb müssen Authentifizierung, Autorisierung und fachliche Rollen getrennt verstanden werden.
---
Szenario 5: Outbox Backlog und Dead Letter Queue
Ausgangssituation
Der Order Service schreibt Events korrekt in die Outbox. Der Publisher veröffentlicht Events an Kafka. Trotzdem verarbeitet Billing nicht alle Events. Einige Nachrichten landen in der Dead Letter Queue.
Der Fehler ist kein Infrastrukturfehler, sondern ein fachliches Kompatibilitätsproblem. Ein neues Feld im Event wurde eingeführt, aber Billing erwartet noch das alte Format.
Warum eine DLQ wichtig ist
Ohne Dead Letter Queue würden fehlerhafte Nachrichten immer wieder verarbeitet und den Consumer blockieren. Mit DLQ werden problematische Nachrichten isoliert, damit gültige Nachrichten weiterlaufen können.
DLQ-Nachrichten dürfen nicht automatisch gelöscht werden. Sie enthalten fachliche Hinweise. Der Betrieb muss gemeinsam mit Entwicklung prüfen, ob Reprocessing möglich ist oder ob eine Korrekturtransformation notwendig ist.
Reprocessing-Regel
Vorlage / Textauszug
Nur Nachrichten erneut verarbeiten, wenn:
Ursache verstanden wurde,
Consumer korrigiert wurde,
Idempotenz gewährleistet ist,
fachliche Dopplungen ausgeschlossen sind,
Reprocessing dokumentiert wurde.
---
Szenario 6: VM-Reporting wird nach OpenShift migriert
Ausgangssituation
Das Reporting läuft auf einer VM. Der Prozess startet jede Nacht, liest Daten aus Orders und Billing, erzeugt CSV-Dateien und legt sie auf einem File Share ab. Das System funktioniert, aber es ist schwer zu warten. Logs liegen lokal auf der VM. Deployment erfolgt manuell. Fehler werden oft erst am nächsten Morgen bemerkt.
Das Ziel ist nicht, blind alles nach OpenShift zu verschieben. Zuerst wird analysiert, welche Teile wirklich containerisierbar sind.
Migrationsschritte
Vorlage / Textauszug
Bestehenden VM-Prozess dokumentieren.
Eingaben und Ausgaben identifizieren.
Abhängigkeiten zu Treibern und File Shares prüfen.
Konfiguration externalisieren.
Logging vereinheitlichen.
Job als Container bauen.
Testweise als Kubernetes Job ausführen.
Danach als CronJob planen.
Monitoring und Alerts ergänzen.
VM-Version erst nach erfolgreicher Parallelphase abschalten.
Migration ist kein Kopieren von VM nach Container. Migration bedeutet, Laufzeit, Konfiguration, Datenzugriff, Monitoring, Fehlerbehandlung und Betriebsverantwortung neu zu ordnen.
---
Szenario 7: File Processing zwischen Bare Metal, Object Storage und Broker
Ausgangssituation
Partner liefern große Dateien. Manche Dateien sind klein und können direkt in OpenShift verarbeitet werden. Andere Dateien sind mehrere Gigabyte groß und brauchen Storage-nahe Verarbeitung auf Bare Metal oder VM.
Die Plattform muss beide Fälle unterstützen, ohne zwei völlig unterschiedliche Welten zu bauen.
Zielablauf
Skizze / Textauszug
Partner liefert Datei
↓
Upload API oder SFTP Gateway
↓
Object Storage incoming
↓
File Processing Worker
↓
Validierung
↓
Object Storage processed oder rejected
↓
Event file.accepted oder file.rejected
↓
Integration Service
Die Originaldatei wird nicht überschrieben. Fehlerhafte Dateien werden mit Fehlerbericht in einen Rejected-Bereich verschoben. Dadurch kann der Partner später nachvollziehen, was passiert ist.
---
Szenario 8: GitOps Rollback nach fehlerhaftem Deployment
Ausgangssituation
Eine neue Version des Billing Service wird ausgerollt. Kurz danach steigen Fehler. Die API ist erreichbar, aber der Consumer verarbeitet Events falsch. Das Team muss schnell reagieren, ohne manuell im Cluster herumzuklicken.
GitOps-Prinzip
Der produktive Zustand wird im GitOps-Repository beschrieben. Argo CD synchronisiert diesen Zustand in den Cluster. Ein Rollback ist deshalb nicht „oc edit deployment“, sondern eine Änderung im Git-Repository.
Wenn Version 1.4.3 fehlerhaft war, wird der Tag zurück auf 1.4.2 gesetzt. Der Pull Request dokumentiert Grund und Incident-Referenz.
Rollback-Runbook
Vorlage / Textauszug
Runbook: GitOps Rollback Billing Service
Symptom
Nach Deployment einer neuen Version steigt die Fehlerquote oder der Consumer Lag.
Entscheidung
Rollback wird durchgeführt, wenn:
Fehler eindeutig mit neuer Version korreliert,
keine schnelle Konfigurationskorrektur ausreicht,
fachlicher Schaden durch Weiterbetrieb größer wäre,
Rollback-Version bekannt stabil ist.
Schritte
Incident eröffnen.
Fehlerbild und Metriken sichern.
GitOps-Overlay auf letzte stabile Version setzen.
Pull Request reviewen und mergen.
Argo CD Sync prüfen.
Pods und Metriken beobachten.
Consumer Lag prüfen.
Incident dokumentieren.
Lernpunkt
GitOps macht Rollback nachvollziehbar. Es ersetzt aber nicht die Entscheidungskompetenz. Ein Rollback muss fachlich begründet und nachkontrolliert werden.
---
Szenario 9: Zertifikat läuft ab und externe API ist nicht erreichbar
Ausgangssituation
Am Montagmorgen ist das Customer Portal nicht erreichbar. Browser melden ein Zertifikatsproblem. Monitoring zeigt, dass die Anwendung selbst gesund ist. Das Problem liegt vor der Anwendung: Das TLS-Zertifikat der externen Route ist abgelaufen.
Warum das kritisch ist
Ein abgelaufenes Zertifikat ist kein Codefehler. Trotzdem wirkt es für Kunden wie ein Totalausfall. Deshalb gehören Zertifikate in das Betriebsmodell.
Prüfung
bash
openssl s_client -connect customer.alpine.example.com:443 -servername customer.alpine.example.com </dev/null2>/dev/null | openssl x509 -noout -dates
oc get route -n customer-prod customer-portal -o yaml
oc get certificate -A
oc describe certificate -n customer-prod customer-portal-tls
Prävention
Zertifikatsablauf überwachen.
Alert mindestens 30 Tage vor Ablauf.
Verantwortlichen Owner dokumentieren.
cert-manager oder automatisierte Erneuerung nutzen.
manuelle Zertifikate nur mit klarer Review-Frist verwenden.
---
Szenario 10: AI erzeugt scheinbar korrekten, aber falschen Kubernetes-Code
Ausgangssituation
Ein Entwickler bittet Codex oder Claude Code, ein Deployment mit Secret, Service und Route zu erstellen. Die Ausgabe sieht plausibel aus. Im Review fällt aber auf, dass das Secret direkt im YAML steht, Resource Limits fehlen und die Route öffentlich erreichbar wäre.
Warum das gefährlich ist
AI kann Form und Syntax gut nachbilden. Sie garantiert aber nicht, dass Enterprise-Regeln eingehalten werden. Deshalb braucht das Projekt feste AI-Review-Regeln.
Review-Check
Vorlage / Textauszug
Sind Secrets als ExternalSecret oder Secret-Referenz modelliert?
Sind Resource Requests und Limits vorhanden?
Gibt es Readiness und Liveness Probes?
Gibt es Labels für Owner und Environment?
Gibt es eine NetworkPolicy?
Ist die Route wirklich öffentlich notwendig?
Gibt es eine ADR, wenn vom Standard abgewichen wird?
Lernpunkt
AI ist ein Beschleuniger, kein Ersatz für Architektur- und Security-Verantwortung. Jede AI-Ausgabe braucht Review, Tests und Kontextprüfung.
---
Abschluss von Teil 34
Dieser Teil zeigt die Plattform nicht als Sammlung isolierter Technologien, sondern als zusammenhängendes System. Genau das ist der Unterschied zwischen Demo und Enterprise-Lernbuch.
Die wichtigsten Erkenntnisse:
Vorlage / Textauszug
End-to-End-Denken verbindet Fachlichkeit, Code, Infrastruktur und Betrieb.
Ein Fehlerbild hat selten nur eine Ebene.
Outbox, NetworkPolicy, RBAC, GitOps und Monitoring wirken erst gemeinsam richtig.
Restore, Rollback und Reprocessing sind Betriebsentscheidungen, keine reinen Technikbefehle.
AI kann helfen, muss aber durch Regeln, Reviews und Tests begrenzt werden.
Übung
Wähle eines der zehn Szenarien und schreibe daraus ein eigenes Runbook mit diesen Abschnitten:
Vorlage / Textauszug
Symptom
Betroffene Systeme
Sofortprüfung
technische Analyse
fachliche Auswirkung
Entscheidungskriterien
Korrektur
Nachkontrolle
Dokumentation
Prävention
Musterlösung: Kurz-Runbook für NetworkPolicy-Fehler
Vorlage / Textauszug
Runbook: Billing Service erreicht Kafka nicht
Symptom
Billing Consumer Lag steigt. Billing Service läuft, verarbeitet aber keine neuen Order Events.
Aus dem Billing Pod wird die Verbindung zu Kafka geprüft. Wenn DNS funktioniert, aber TCP-Verbindung blockiert ist, wird die NetworkPolicy geprüft.
fachliche Auswirkung
Neue Rechnungen werden verzögert erstellt. Bestellungen sind nicht verloren, aber Billing hinkt hinterher.
Entscheidung
Wenn Kafka gesund ist und nur Billing blockiert ist, wird die Egress-Policy korrigiert.
Korrektur
Änderung im GitOps Repository, Pull Request, Review und Argo CD Sync.
Nachkontrolle
Consumer Lag muss sinken. Neue Rechnungen müssen entstehen. Logs dürfen keine Broker-Timeouts mehr zeigen.
Prävention
Vor jeder neuen NetworkPolicy wird eine Kommunikationsmatrix geprüft.
Erweiterte Enterprise-Szenarien und Betriebsfälle
Ziel dieses Schritts
Dieser Teil ergänzt größere, zusammenhängende Betriebsfälle. Die bisherigen Teile erklären Architektur, Plattform, Code, Security und Delivery. Jetzt geht es um Situationen, die in einem echten Unternehmen nicht als isolierte Einzelaufgabe auftreten. Ein Incident betrifft oft Anwendung, Netzwerk, Identität, Daten, Observability, GitOps und Kommunikation gleichzeitig.
Der Zweck dieses Schritts ist deshalb nicht, noch mehr Begriffe zu sammeln. Der Zweck ist, fachliche Entscheidungen in realistische Abläufe zu übersetzen. Jeder Fall zeigt, was passiert, welche Signale sichtbar werden, welche Teams beteiligt sind, welche Artefakte geprüft werden und welche dauerhafte Verbesserung daraus entstehen sollte.
1. Betriebsfall: Order Service erzeugt sporadisch HTTP 500
Ein Kunde meldet, dass Bestellungen manchmal fehlschlagen. Im Customer Portal erscheint nur eine allgemeine Fehlermeldung. Für den Betrieb ist wichtig, den Fehler nicht sofort als Frontend-Problem einzuordnen. Das Portal zeigt nur das Symptom. Die Ursache kann im Backend, in der Datenbank, in Keycloak, im Netzwerk oder in einer fehlerhaften Validierung liegen.
Der erste Schritt ist die Korrelation über Trace-ID. Wenn das Portal jede Anfrage mit einer Correlation-ID sendet und der Order Service diese ID in Logs übernimmt, kann man den kompletten Ablauf verfolgen. Ohne diese ID muss man anhand von Uhrzeit, Benutzer und Endpoint suchen. Das ist ungenau und fehleranfällig.
bash
# Fehlerhafte Requests im Order Namespace suchen
oc logs -n order-prod deployment/order-service --since=30m \
| grep class="str">'HTTP 500' \
| head -20
# Danach gezielt nach Trace-ID suchen
oc logs -n order-prod deployment/order-service --since=30m \
| grep class="str">'traceId=7f43a9c2'
Wenn die Logs zeigen, dass der Fehler bei bestimmten Produktkombinationen entsteht, ist die Ursache wahrscheinlich fachlich oder datenbezogen. Wenn der Fehler nur bei Lastspitzen auftritt, muss man Datenbankverbindungen, Threadpools, Timeouts und Resource Limits prüfen. Wenn der Fehler nur nach einem Deployment auftritt, liegt der Fokus auf Release-Diff, GitOps-Commit und Konfiguration.
Ein produktionsnaher Service sollte hier nicht nur Stacktraces ausgeben. Er sollte Fehlerklassen unterscheiden: Validierungsfehler, technische Fehler, externe Abhängigkeit nicht erreichbar, Timeout, Security-Fehler und unerwartete Fehler.
java
package com.seb4u.demo.spring.order.api;
import org.springframework.http.HttpStatus;
import org.springframework.http.ProblemDetail;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import java.net.URI;
@RestControllerAdvicepublicclass ApiExceptionHandler {
@ExceptionHandler(IllegalArgumentException.class)
ProblemDetail handleValidation(IllegalArgumentException ex) {
ProblemDetail detail = ProblemDetail.forStatus(HttpStatus.BAD_REQUEST);
detail.setTitle(class="str">"Invalid order request");
detail.setDetail(ex.getMessage());
detail.setType(URI.create(class="str">"https://errors.alpine.example.com/order/invalid-request"));
return detail;
}
@ExceptionHandler(ExternalDependencyException.class)
ProblemDetail handleDependency(ExternalDependencyException ex) {
ProblemDetail detail = ProblemDetail.forStatus(HttpStatus.SERVICE_UNAVAILABLE);
detail.setTitle(class="str">"Required dependency is unavailable");
detail.setDetail(class="str">"The order could not be processed because a required backend dependency is unavailable.");
detail.setType(URI.create(class="str">"https://errors.alpine.example.com/order/dependency-unavailable"));
return detail;
}
}
Die Verbesserung nach dem Incident besteht nicht nur aus einem Bugfix. Gute Verbesserungen sind: bessere Fehlerklassifizierung, Dashboard für 5xx-Rate, Alert auf ungewöhnliche Fehlerquote, Tests für den betroffenen Fall und ein kurzer Eintrag im Runbook.
In eventgetriebenen Systemen muss man davon ausgehen, dass eine Nachricht mehrfach ankommt. Broker garantieren je nach Konfiguration nicht automatisch exakt einmalige fachliche Verarbeitung. Deshalb muss der Billing Service idempotent sein.
Das Symptom kann sein, dass für eine Bestellung zwei Rechnungsentwürfe entstehen. Der Fehler ist kritisch, weil er direkt fachliche Daten betrifft. Hier darf der Betrieb nicht einfach Nachrichten löschen, ohne die fachliche Wirkung zu prüfen.
Der Billing Consumer muss vor der Verarbeitung prüfen, ob das Event bereits verarbeitet wurde. Dafür eignet sich eine Tabelle processed_events mit einer eindeutigen Event-ID.
sql
CREATETABLE processed_events (
event_id VARCHAR(120) PRIMARYKEY,
event_type VARCHAR(160) NOTNULL,
processed_at TIMESTAMP WITH TIME ZONE NOTNULL,
aggregate_id VARCHAR(120) NOTNULL
);
CREATETABLE invoices (
id UUID PRIMARYKEY,
order_id UUID NOTNULL,
customer_id VARCHAR(80) NOTNULL,
amount NUMERIC(12, 2) NOTNULL,
status VARCHAR(40) NOTNULL,
created_at TIMESTAMP WITH TIME ZONE NOTNULL,
UNIQUE(order_id)
);
Nach dem Incident wird geprüft, ob Duplikate bereits entstanden sind. Wenn ja, braucht es eine fachliche Korrektur. Ein Restore der ganzen Datenbank wäre meist falsch, weil dadurch andere korrekte Rechnungen verloren gehen könnten. Besser ist eine gezielte Korrektur mit Audit-Eintrag.
Ein Team behebt nachts ein Problem direkt im Cluster. Am nächsten Morgen setzt Argo CD den Zustand wieder auf den Git-Stand zurück. Aus Sicht von GitOps ist das korrekt. Aus Sicht des Teams wirkt es wie ein Fehler. In Wirklichkeit zeigt der Fall einen Prozessbruch.
GitOps bedeutet: Git ist die gewünschte Wahrheit. Manuelle Änderungen im Cluster sind nur für Diagnose oder extreme Notfälle erlaubt. Dauerhafte Änderungen müssen ins GitOps-Repository.
bash
# Manuelle Änderung sichtbar machen
oc diff -n order-prod -f platform/overlays/prod/order-service
# Argo CD Status prüfen
argocd app get order-service-prod
# Synchronisationshistorie anzeigen
argocd app history order-service-prod
Ein guter Notfallprozess erlaubt einen temporären Hotfix, verlangt aber danach eine Nachdokumentation. Der Hotfix muss als Pull Request ins GitOps-Repository. Zusätzlich muss im Incident-Log stehen, warum der direkte Eingriff notwendig war.
Vorlage / Textauszug
Emergency Change Record
System
order-service-prod
Grund
Produktionsstörung durch falsch gesetzten Timeout-Wert nach Release 1.18.0.
Temporäre Maßnahme
Timeout im Deployment manuell von 2s auf 8s erhöht.
Dauerhafte Maßnahme
GitOps Pull Request #482 erstellt, um Timeout im Produktions-Overlay anzupassen.
Rückbau
Manuelle Änderung wird nach Argo-CD-Sync nicht mehr benötigt.
Die dauerhafte Verbesserung ist ein klarer Emergency-Change-Prozess. GitOps darf nicht durch heimliche manuelle Änderungen unterlaufen werden.
4. Betriebsfall: Zertifikat erneuert, aber Route nutzt noch altes Secret
Ein Zertifikat wurde erneuert, aber externe Clients melden weiterhin, dass das Zertifikat bald abläuft. Die Ursache kann sein, dass das neue Zertifikat zwar im Secret liegt, aber die Route oder der Router noch das alte Secret verwendet. Möglich ist auch, dass ein externer Load Balancer TLS terminiert und dort ein anderes Zertifikat installiert ist.
Die Diagnose muss die TLS-Kette von außen und im Cluster prüfen.
Ein guter Plattformbetrieb überwacht nicht nur Pod-Status. Er überwacht auch Zertifikatsablauf. Zertifikate sind ein klassisches Beispiel für ein Problem, das technisch klein wirkt, aber schnell produktionskritisch wird.
5. Betriebsfall: VM-Reporting erzeugt falsche Zahlen nach Schemaänderung
Der Reporting Service läuft noch auf einer VM und liest aus einer Datenbankkopie. Nach einer Schemaänderung im Order Service stimmen bestimmte Reports nicht mehr. Das ist ein typischer Hybrid-Fehler: Ein modernes System ändert seine Datenstruktur, aber ein älteres VM-System hängt noch indirekt daran.
Die technische Frage lautet nicht nur: Warum ist der Report falsch? Die wichtigere Architekturfrage lautet: Warum durfte Reporting direkt von einer Struktur abhängen, die einem anderen Service gehört?
In einer sauberen Architektur sollte Reporting nicht direkt produktive Tabellen eines anderen Services interpretieren. Besser sind stabile Exportmodelle, Events, Read Models oder kontrollierte Reporting-Schemas.
sql
CREATE VIEW reporting_order_summary AS
SELECT
o.id AS order_id,
o.customer_id,
o.status,
o.total_amount,
o.created_at,
count(oi.id) AS item_count
FROM orders o
JOIN order_items oi ON oi.order_id = o.id
GROUP BY o.id, o.customer_id, o.status, o.total_amount, o.created_at;
Diese View ist kein perfektes Zielbild, aber eine kontrolliertere Übergangslösung. Langfristig sollte Reporting ein eigenes Modell bekommen, das über Events oder definierte Exporte gefüllt wird.
Nach einer Security-Härtung fehlen Traces. Die Anwendung läuft, Logs sind da, Metriken sind da, aber verteilte Traces kommen nicht mehr im Backend an. Ursache ist oft eine NetworkPolicy, die Egress nur zu Datenbank und Broker erlaubt, aber den OpenTelemetry Collector vergessen hat.
Das zeigt: Security und Observability dürfen nicht gegeneinander arbeiten. Eine gute Policy erlaubt notwendige Betriebsverbindungen bewusst und eng begrenzt.
Nach der Änderung wird nicht nur geprüft, ob der Pod läuft. Es wird geprüft, ob Traces mit korrekter Service-Name-Konvention im Backend sichtbar sind.
7. Betriebsfall: Secret Rotation bricht Billing
Ein Datenbankpasswort wird rotiert. Der neue Secret-Wert wird im Secret Store aktualisiert. Trotzdem schlagen Billing-Verbindungen fehl. Mögliche Ursachen sind: Pod hat Secret noch nicht neu geladen, Connection Pool nutzt alte Verbindungen, ExternalSecret hat nicht synchronisiert, oder Datenbankrolle wurde falsch geändert.
Die Diagnose braucht mehrere Ebenen.
bash
# ExternalSecret Status prüfen
oc get externalsecret -n billing-prod billing-db -o yaml
# Secret-Zeitstempel prüfen
oc get secret -n billing-prod billing-db-secret -o yaml
# Deployment neu starten, falls Anwendung Secrets nur beim Start liest
oc rollout restart deployment/billing-service -n billing-prod
# Rollout überwachen
oc rollout status deployment/billing-service -n billing-prod
Dauerhaft sollte jede Secret Rotation einen Ablauf haben: Änderung im Secret-System, Synchronisation prüfen, Anwendung neu laden oder neu starten, Verbindungstest, Monitoring prüfen und Abschluss dokumentieren.
Cloud-Kosten sind ein Betriebsrisiko. Ein File Processing Service schreibt fehlerhafte Dateien in Object Storage, löscht sie aber nie. Nach einigen Wochen steigen Speicherkosten und API-Aufrufkosten. Technisch funktioniert alles, wirtschaftlich ist es fehlerhaft.
Eine Enterprise-Plattform braucht daher Kostenregeln. Object Storage Buckets sollten Tags, Lifecycle-Regeln und Monitoring haben.
hcl
resourceclass="str">"aws_s3_bucket_lifecycle_configuration" class="str">"partner_files" {
bucket = aws_s3_bucket.partner_files.id
rule {
id = class="str">"expire-rejected-files"
status = class="str">"Enabled"
filter {
prefix = class="str">"rejected/"
}
expiration {
days = 30
}
}
rule {
id = class="str">"archive-processed-files"
status = class="str">"Enabled"
filter {
prefix = class="str">"processed/"
}
transition {
days = 14
storage_class = class="str">"STANDARD_IA"
}
}
}
Dieser Fall zeigt, dass Cloud-Architektur nicht nur Verfügbarkeit und Skalierung meint. Kostenkontrolle ist ein Architekturmerkmal.
9. Betriebsfall: Argo CD synchronisiert falsche Umgebung
Ein Entwickler verwechselt test und prod Overlay. Die Änderung landet im falschen Pfad. Argo CD macht genau das, was im Repository steht. Der Fehler liegt im Prozess und in fehlenden Schutzmechanismen.
Eine gute Repository-Struktur macht Verwechslungen schwerer. Zusätzlich helfen CODEOWNERS, Branch Protection und Pflichtreviews für Produktionspfade.
Der dauerhafte Fix ist nicht nur ein Revert. Der dauerhafte Fix ist eine Schutzregel gegen Wiederholung.
10. Betriebsfall: AI-Vorschlag öffnet zu breite Rechte
Ein AI-Werkzeug schlägt für einen Fehler vor, dem ServiceAccount cluster-admin zu geben. Das Problem wäre damit vielleicht kurzfristig gelöst, aber die Plattform wäre unsicher. Dieser Fall ist wichtig, weil AI-Ausgaben oft plausibel wirken.
Die richtige Reaktion ist ein Minimalrechte-Review. Man prüft, welche Verben und Ressourcen wirklich benötigt werden.
Diese Role ist bewusst eng. Wenn ein Service mehr Rechte braucht, muss der Grund dokumentiert werden. AI darf helfen, aber nicht die Security-Grenzen entscheiden.
11. Betriebsfall: Datenbankmigration dauert länger als das Releasefenster
Eine Migration fügt eine Spalte hinzu und aktualisiert Millionen Zeilen. In Test lief sie schnell, in Produktion blockiert sie länger als erwartet. Das Releasefenster wird überschritten.
Datenbankmigrationen müssen produktionsnah geplant werden. Große Änderungen sollten expand-and-contract nutzen.
sql
-- Phase 1: kompatible Erweiterung
ALTER TABLE orders ADD COLUMN source_system VARCHAR(80);
-- Phase 2: Anwendung schreibt neues Feld optional
-- Phase 3: Backfill in kleinen Batches
UPDATE orders
SET source_system = class="str">'customer-portal'
WHERE source_system IS NULLAND id IN (
SELECT id FROM orders WHERE source_system IS NULL LIMIT 1000
);
-- Phase 4: Constraint erst nach Backfill
ALTER TABLE orders ALTER COLUMN source_system SET NOTNULL;
Der wichtige Lernpunkt: Eine Migration ist Teil des Releases. Sie braucht Tests, Laufzeitabschätzung, Rollback-Strategie und Monitoring.
12. Betriebsfall: Backup ist vorhanden, Restore aber nicht getestet
Ein Team sagt: Backups laufen täglich. Beim echten Restore merkt man, dass Credentials fehlen, WAL-Dateien nicht vollständig sind oder die Dokumentation veraltet ist. Ein Backup ohne Restore-Test ist nur eine Hoffnung.
Ein Restore-Test braucht eine isolierte Umgebung, klare Schritte und fachliche Prüfung.
bash
# Beispielhafter Restore-Test für PostgreSQL-Lab
createdb orders_restore_test
pg_restore \
--dbname=orders_restore_test \
--clean \
--if-exists \
/backup/orders/latest.dump
psql orders_restore_test -c class="str">"select count(*) from orders;"
psql orders_restore_test -c class="str">"select max(created_at) from orders;"
Nach dem Restore muss ein fachlicher Smoke Test laufen. Es reicht nicht, dass Tabellen existieren. Man muss prüfen, ob kritische Abfragen, Constraints und Referenzen stimmen.
13. Zusammenfassung der erweiterten Betriebsfälle
Diese Szenarien zeigen, dass Enterprise-Qualität nicht durch ein einzelnes Framework entsteht. Sie entsteht durch wiederholbare Abläufe, klare Verantwortung, konkrete Artefakte, überprüfbare Sicherheitsgrenzen und eine Kultur, die aus Incidents lernt.
Ein guter Plattformstandard fragt immer:
Vorlage / Textauszug
Was ist passiert?
Welche Signale waren sichtbar?
Welche Grenze hat versagt?
Welche Entscheidung war unklar?
Welche Dokumentation fehlte?
Welche Automatisierung hätte geholfen?
Welche Prüfung verhindert Wiederholung?
Damit werden Betriebsfälle zu Lernmaterial und nicht nur zu Störungen.
Teil I: Übungen, Runbooks, Musterlösungen, kompakte SVGs und Fachglossar
Teil I: Übungen, Runbooks, Musterlösungen, kompakte SVGs und Fachglossar
Konsolidiert aus Rohmaterial: Teil 14, Teil 15, Teil 32, Teil 33.
Übungen, Runbooks und Musterlösungen
1. Warum dieser Teil wichtig ist
Ein Enterprise-Lernprojekt ist erst dann wirklich nützlich, wenn man damit üben kann. Reine Erklärung reicht nicht aus. Wer eine hybride Plattform verstehen will, muss Entscheidungen treffen, Fehler analysieren, Manifeste lesen, Runbooks ausführen und technische Nachweise prüfen können.
Dieser Teil sammelt deshalb keine losen Anhänge. Die Übungen sind nach Fachbereichen geordnet und greifen direkt auf die vorherigen Teile zurück. Jede Aufgabe ist so formuliert, dass sie eine reale Situation aus einem Enterprise-Projekt simuliert. Die Musterlösungen sind nicht nur kurze Antworten, sondern zeigen, wie man eine Lösung begründet.
Wichtig ist: Eine gute Übung prüft nicht nur Wissen, sondern Vorgehen. Im Betrieb zählt nicht, ob man einen Begriff auswendig kennt. Entscheidend ist, ob man aus Symptomen eine Ursache ableiten, die richtige Ebene prüfen und eine nachvollziehbare Entscheidung treffen kann.
---
2. Übungsformat
Jede Übung folgt demselben Aufbau:
Vorlage / Textauszug
Ausgangslage
Aufgabe
Erwartetes Ergebnis
Hinweise
Musterlösung
Bewertungskriterien
Dadurch entsteht ein wiederholbares Trainingsformat. Man kann die Übungen allein bearbeiten, im Team diskutieren oder als Review-Aufgabe für Codex beziehungsweise Claude Code verwenden.
---
3. Übung: Workload richtig einordnen
Ausgangslage
Die Alpine Retail & Services Group plant drei neue Komponenten:
Vorlage / Textauszug
Price Calculation Service
Monthly Archive Export
Partner File Import Worker
Der Price Calculation Service wird häufig von Customer Portal und Admin Portal aufgerufen. Er muss schnell reagieren und soll regelmäßig deployt werden.
Der Monthly Archive Export läuft einmal pro Monat, liest sehr viele Daten und erzeugt große Archivdateien.
Der Partner File Import Worker verarbeitet täglich große Dateien von externen Partnern. Die Dateien liegen in Object Storage, aber einige Validierungsschritte benötigen lokale temporäre Verarbeitung.
Aufgabe
Ordne jede Komponente einer primären Laufzeit zu:
Vorlage / Textauszug
OpenShift
VM
Bare Metal
Cloud Service
Begründe deine Entscheidung fachlich und betrieblich.
Musterlösung
Der Price Calculation Service passt gut zu OpenShift. Er ist ein moderner API-Service, wird häufig aufgerufen, braucht Skalierung, Health Checks, Monitoring und regelmäßige Releases. OpenShift bietet genau dafür ein gutes Betriebsmodell.
Der Monthly Archive Export kann als Kubernetes CronJob laufen, wenn die Laufzeit begrenzt ist und der Zugriff auf Daten kontrolliert erfolgt. Wenn die Datenmenge sehr groß ist oder spezielle alte Exportwerkzeuge benötigt werden, kann auch eine VM sinnvoll sein. Die Entscheidung hängt von Speicherbedarf, Laufzeit, Treibern und Wiederholbarkeit ab.
Der Partner File Import Worker ist ein Grenzfall. Wenn die Dateien über Object Storage verarbeitet werden und die temporären Daten begrenzt bleiben, kann er als containerisierter Worker laufen. Wenn aber sehr große temporäre Dateien, spezielle Dateisysteme oder lokale Performance entscheidend sind, ist VM oder Bare Metal sinnvoll. Wichtig ist, dass die Entscheidung dokumentiert wird.
Bewertungskriterien
Eine gute Antwort nennt nicht nur eine Plattform, sondern erklärt:
Vorlage / Textauszug
technische Anforderungen
Betriebsanforderungen
Security-Auswirkungen
Monitoring und Fehlerbehandlung
spätere Migrationsmöglichkeit
---
4. Übung: Firewall-Freigabe bewerten
Ausgangslage
Ein Team beantragt folgende Firewall-Regel:
Vorlage / Textauszug
Quelle: OpenShift Application Zone
Ziel: Data Zone
Port: any
Protokoll: TCP
Zweck: Zugriff auf Datenbanken und Broker
Aufgabe
Bewerte diesen Antrag. Formuliere eine bessere Variante.
Musterlösung
Der Antrag ist zu breit. Er erlaubt allen Workloads aus der Application Zone Zugriff auf alle TCP-Ports in der Data Zone. Dadurch entstehen unnötige Risiken. Ein kompromittierter Pod könnte viele Systeme erreichen.
Eine bessere Regel beschreibt konkrete Quelle, konkretes Ziel und konkreten Port:
Finde die wichtigsten Probleme und formuliere eine verbesserte Version.
Musterlösung
Das Manifest ist für ein Enterprise-Lab zu schwach. Es nutzt das Tag latest, definiert keine Resource Requests und Limits, keine Readiness Probe, keine Liveness Probe, keine Umgebungsvariablen, keine Security-Einstellungen und keine klare Versionierung.
Danach wird geprüft, ob der Outbox Publisher läuft und ob er Kafka erreicht:
bash
oc get pods -n order-prod -l app=order-service
oc describe pod -n order-prod -l app=order-service
Dann wird die Datenbank geprüft:
sql
SELECT event_type, COUNT(*)
FROM outbox_events
WHERE published_at IS NULL
GROUP BY event_type;
SELECT id, event_type, created_at, publish_attempts, last_error
FROM outbox_events
WHERE published_at IS NULL
ORDER BY created_at
LIMIT 20;
Wenn last_error auf Kafka-Verbindungsprobleme zeigt, werden Broker, Secret und NetworkPolicy geprüft. Wenn die Fehler auf Payload-Probleme zeigen, muss der Publisher gegen ungültige Events robuster gemacht werden. Wenn publish_attempts sehr hoch ist, darf man Events nicht blind löschen. Zuerst muss geklärt werden, ob die Events fachlich noch benötigt werden.
Ein möglicher Sofortschritt ist, den Publisher nach Behebung der Ursache kontrolliert weiterlaufen zu lassen. Falls das Backlog sehr groß ist, kann eine temporäre Skalierung oder ein Batch-Publisher nötig sein. Dabei müssen Broker-Last und Billing-Service-Kapazität beachtet werden.
---
7. Übung: Keycloak-Rollenmodell prüfen
Ausgangslage
Ein Admin Portal verwendet folgende Rollen:
Vorlage / Textauszug
admin
user
superuser
Aufgabe
Bewerte dieses Modell und schlage eine bessere Variante vor.
Musterlösung
Das Modell ist zu grob. superuser ist besonders problematisch, weil nicht klar ist, welche Rechte damit verbunden sind. In Enterprise-Systemen sollten Rollen fachliche Tätigkeiten beschreiben.
Eine bessere Struktur wäre:
Vorlage / Textauszug
order.viewer
order.corrector
billing.viewer
billing.approver
customer.support
audit.viewer
platform.operator
Diese Rollen lassen sich besser prüfen. Ein Mitarbeiter im Support braucht vielleicht order.viewer und customer.support, aber nicht billing.approver. Ein Auditor braucht audit.viewer, aber keine Schreibrechte.
Im Admin Portal sollten Rollen außerdem nicht nur im Frontend verborgen werden. Die Backend-API muss Berechtigungen serverseitig prüfen.
Wenn die neue Version nicht ready wird und Kunden betroffen sind, wird Rollback auf die letzte stabile Version ausgelöst.
Rollback
Im GitOps-Repository wird das Image-Tag zurückgesetzt, zum Beispiel von `1.8.0` auf `1.7.4`. Danach synchronisiert Argo CD die Änderung.
Nacharbeit
Ursache dokumentieren
Release Notes prüfen
fehlende Tests ergänzen
ADR nur bei Architekturentscheidung aktualisieren
Ein gutes Runbook vermeidet hektische Einzelaktionen. Es führt von Symptom zu Analyse, Entscheidung und Nacharbeit.
---
9. Übung: Backup-Restore-Test planen
Ausgangslage
Die Orders-Datenbank wird täglich gesichert. Es gibt aber seit drei Monaten keinen Restore-Test.
Aufgabe
Plane einen Restore-Test für die Testumgebung.
Musterlösung
Ein Restore-Test darf nicht direkt in Produktion stattfinden. Zuerst wird eine isolierte Testdatenbank bereitgestellt. Danach wird das letzte Backup wiederhergestellt. Anschließend werden technische und fachliche Prüfungen durchgeführt.
Prüfschritte:
Vorlage / Textauszug
Backup-Artefakt identifizieren
Prüfsumme kontrollieren
Testdatenbank bereitstellen
Restore durchführen
Schema-Version prüfen
Anzahl wichtiger Tabellen prüfen
Stichproben fachlicher Daten prüfen
Anwendung gegen Restore-Datenbank starten
kritische Use Cases testen
Ergebnis dokumentieren
Beispiel für technische Prüfungen:
sql
SELECT COUNT(*) FROM orders;
SELECT COUNT(*) FROM order_items;
SELECT COUNT(*) FROM outbox_events;
SELECT MAX(created_at) FROM orders;
Das Ergebnis wird im Runbook dokumentiert. Wenn der Restore scheitert, ist das ein kritischer Befund. Ein Backup ohne erfolgreichen Restore-Test ist kein verlässliches Backup.
---
10. Übung: AI-Ausgabe prüfen
Ausgangslage
Ein AI-Werkzeug schlägt folgenden Text für Security vor:
Vorlage / Textauszug
Security ist wichtig. Alle Systeme müssen geschützt werden. RBAC, Audit und Hardening sollten umgesetzt werden. Außerdem müssen README, ADR und Runbook gepflegt werden.
Aufgabe
Bewerte den Text und verbessere ihn fachlich.
Musterlösung
Der Text ist zu allgemein. Er nennt Begriffe, erklärt aber keine konkrete Umsetzung. Eine bessere Fassung muss sagen, welche Komponente betroffen ist, welche Regel gilt und wie der Nachweis aussieht.
Besser:
Vorlage / Textauszug
Für den Billing Service werden fachliche Rollen in Keycloak definiert. Die Rolle `billing.approver` erlaubt das Freigeben von Rechnungen. Die API prüft diese Rolle serverseitig mit Spring Security. Kubernetes RBAC wird davon getrennt betrachtet und nur für technische Deployment- und Betriebsrechte verwendet.
Alle Freigabeaktionen schreiben Audit Events mit Benutzer-ID, Rechnungs-ID, Zeitpunkt, Entscheidung und Trace-ID. Diese Events werden zentral geloggt und mindestens 180 Tage aufbewahrt. Das Runbook beschreibt, wie ein Auditor die Freigabehistorie einer Rechnung nachvollzieht.
Diese Version ist besser, weil sie konkrete Rollen, technische Prüfung, Audit-Inhalt und Betriebsnachweis verbindet.
---
11. Runbook-Vorlage
Für das Lab verwenden wir eine einheitliche Runbook-Vorlage:
Vorlage / Textauszug
Runbook: <Name>
Zweck
Kurz beschreiben, welches Problem dieses Runbook behandelt.
Symptom
Woran erkennt man das Problem?
Betroffene Systeme
Anwendung
Namespace
Datenbank
Broker
externe Abhängigkeiten
Erste Prüfung
Praxisbefehle und Build-Kommandos
Praxisbefehle und Build-Kommandos
Vorlage / Textauszug
Entscheidungsbaum
Welche Beobachtung führt zu welcher nächsten Prüfung?
Sofortmaßnahmen
Welche Maßnahmen sind erlaubt, ohne Datenverlust zu riskieren?
Eskalation
Wann wird welches Team informiert?
Wiederherstellung
Wie wird der Normalzustand wiederhergestellt?
Nacharbeit
Welche Tests, Dokumentationen oder Alerts müssen angepasst werden?
Diese Vorlage verhindert, dass jedes Team Runbooks völlig anders schreibt.
---
12. ADR-Vorlage
Vorlage / Textauszug
ADR <Nummer>: <Titel>
Status
Vorgeschlagen | Akzeptiert | Abgelehnt | Ersetzt
Kontext
Welche Situation oder welches Problem führt zu dieser Entscheidung?
Entscheidung
Welche Lösung wird gewählt?
Alternativen
Welche anderen Möglichkeiten wurden betrachtet?
Konsequenzen
Welche Vorteile, Nachteile, Risiken und Betriebsfolgen entstehen?
Nachweise
Welche Artefakte zeigen die Umsetzung?
Code
Manifest
Pipeline
Runbook
Monitoring
Test
Ein ADR ist kein Roman. Er soll eine wichtige Entscheidung nachvollziehbar machen.
---
13. Review-Checkliste für Pull Requests
Vorlage / Textauszug
Fachlichkeit:
Ist der Zweck der Änderung klar?
Ist der betroffene Use Case beschrieben?
Gibt es fachliche Tests?
Code:
Ist die Paketstruktur sauber?
Sind Verantwortlichkeiten getrennt?
Gibt es keine versteckte Infrastruktur in der Domäne?
Security:
Werden Rollen serverseitig geprüft?
Werden Secrets nicht geloggt?
Gibt es keine breiten Berechtigungen?
Betrieb:
Gibt es Logs, Metriken und Health Checks?
Ist das Runbook betroffen?
Sind Alerts nötig?
Deployment:
Ist das Image versioniert?
Sind Ressourcen gesetzt?
Sind Probes sinnvoll?
Passt das GitOps-Manifest?
Dokumentation:
Muss eine README aktualisiert werden?
Ist ein ADR nötig?
Sind bekannte Grenzen dokumentiert?
Diese Checkliste ist bewusst praktisch. Sie soll im Alltag eines Enterprise-Projekts nutzbar sein.
---
14. Abschlussübung: Mini-End-to-End-Review
Aufgabe
Prüfe eine neue Funktion: Der Billing Service soll Rechnungen manuell freigeben können.
Beantworte:
Vorlage / Textauszug
Welche API entsteht?
Welche Rolle wird benötigt?
Welche Audit-Daten werden geschrieben?
Welche Tests sind nötig?
Welche Metrik ist sinnvoll?
Welche Alert-Regel könnte entstehen?
Muss ein ADR geschrieben werden?
Muss ein Runbook angepasst werden?
Musterlösung
Es entsteht eine API POST /invoices/{id}/approve. Die Rolle billing.approver wird benötigt. Die API prüft die Rolle serverseitig. Audit-Daten enthalten Benutzer-ID, Rechnungs-ID, Zeitpunkt, Entscheidung, vorherigen Status, neuen Status und Trace-ID.
Tests prüfen erfolgreiche Freigabe, fehlende Rolle, ungültigen Status, nicht vorhandene Rechnung und Audit-Erzeugung. Eine sinnvolle Metrik ist billing_invoice_approval_total mit Labels für Ergebnis und Grund. Ein Alert könnte entstehen, wenn ungewöhnlich viele Freigaben fehlschlagen.
Ein ADR ist nur nötig, wenn eine wichtige Architekturentscheidung getroffen wird, zum Beispiel ein neues Audit-Modell. Ein Runbook muss angepasst werden, wenn Betrieb oder Audit später Freigaben nachvollziehen müssen.
---
15. Merksätze
Vorlage / Textauszug
Übungen müssen reales Vorgehen trainieren, nicht nur Begriffe abfragen.
Ein Runbook ist nur gut, wenn es im Störfall wirklich hilft.
Eine Musterlösung soll Entscheidungen begründen, nicht nur Ergebnisse nennen.
Security muss in API, Rolle, Audit, Test und Betrieb sichtbar sein.
GitOps macht nur dann Sinn, wenn Änderungen überprüfbar und rückrollbar sind.
Ein Backup ist erst bewiesen, wenn Restore getestet wurde.
Integrierte Begriffserklärungen und Fachindex
1. Warum dieser Teil kein klassisches Glossar ist
Ein klassisches Glossar steht oft am Ende eines Dokuments. Der Leser muss dann während des Lernens ständig springen: erst Kapitel lesen, dann Begriff suchen, dann zurück zum Kapitel. Für ein großes Enterprise-Lernprojekt ist das unbequem. Deshalb wurden wichtige Begriffe bereits in den vorherigen Teilen direkt im fachlichen Zusammenhang erklärt.
Dieser Teil ist trotzdem wichtig. Er sammelt zentrale Begriffe, aber nicht als isolierte Wortliste. Jeder Begriff wird mit dem Projekt verbunden: Wo taucht er im Lab auf? Warum ist er wichtig? Welche typischen Fehler entstehen? Welche Artefakte zeigen, dass der Begriff nicht nur theoretisch verstanden, sondern praktisch umgesetzt wurde?
Damit wird dieser Teil zu einem Fachindex mit Lernfunktion. Er hilft beim Wiederholen, beim Nachschlagen und beim späteren Erstellen der HTML-Version.
Wichtig ist: Die Begriffserklärungen ersetzen nicht die Fachkapitel. Sie verweisen gedanklich zurück auf Architektur, Infrastruktur, Security, Betrieb, Code und Runbooks.
---
2. Architekturbegriffe
Enterprise-Architektur
Enterprise-Architektur beschreibt nicht nur technische Komponenten. Sie beschreibt, wie Anwendungen, Infrastruktur, Daten, Sicherheit, Betrieb, Organisation und Prozesse zusammenwirken. Im Lab bedeutet das: Der Order Service ist nicht nur ein Java-Service. Er ist Teil eines größeren Systems mit Customer Portal, Billing, Datenbank, Broker, Keycloak, OpenShift, Monitoring, Backup und GitOps.
Ein häufiger Fehler ist, Enterprise-Architektur mit einem großen Diagramm zu verwechseln. Ein Diagramm ist hilfreich, aber nur ein Einstieg. Architektur wird erst belastbar, wenn Entscheidungen dokumentiert, technische Artefakte vorhanden und Betriebsabläufe beschrieben sind.
Nachweise im Lab:
Vorlage / Textauszug
ADRs im Ordner docs/adr
Zielarchitekturdiagramme
Repository-Struktur
OpenShift-Manifeste
Runbooks
CI/CD-Definitionen
Architekturentscheidung
Eine Architekturentscheidung ist eine bewusste Festlegung mit Konsequenzen. Zum Beispiel: Der Order Service läuft auf OpenShift, die große PostgreSQL-Instanz bleibt zunächst auf Bare Metal, und Events werden über das Outbox Pattern veröffentlicht.
Eine gute Entscheidung nennt Kontext, Alternativen, gewählte Lösung und Folgen. Ohne diese Dokumentation wirkt Architektur später beliebig. Neue Teammitglieder wissen dann nicht, warum etwas so gebaut wurde.
Typischer Fehler:
Vorlage / Textauszug
class="str">"Wir machen das so, weil es immer so war."
Besser:
Vorlage / Textauszug
class="str">"Wir lassen die Datenbank zunächst auf Bare Metal, weil I/O-Last, Backup-Prozess und Lizenzmodell aktuell gegen eine sofortige Migration sprechen. Die Entscheidung wird nach dem ersten Lasttest erneut bewertet."
ADR
ADR steht für Architecture Decision Record. Ein ADR ist eine kleine Datei, meistens Markdown, in der eine Architekturentscheidung dokumentiert wird. Im Lab werden ADRs verwendet, um Entscheidungen nachvollziehbar zu machen.
Ein ADR ist kein Roman. Er soll kurz genug sein, damit er gelesen wird, aber konkret genug, damit die Entscheidung später überprüfbar bleibt.
Minimalstruktur:
Vorlage / Textauszug
ADR 004: Order Events über Outbox Pattern
Status
Akzeptiert
Kontext
Der Order Service speichert Bestellungen und muss Billing zuverlässig informieren.
Entscheidung
Events werden zuerst in derselben Datenbanktransaktion in einer Outbox-Tabelle gespeichert.
Konsequenzen
Ein separater Publisher veröffentlicht Events später an Kafka. Monitoring für Outbox Backlog ist verpflichtend.
Zielbild
Das Zielbild beschreibt, wie die Plattform später aussehen soll. Es ist keine vollständige Implementierung, sondern eine Orientierung. Im Lab umfasst das Zielbild moderne Anwendungen auf OpenShift, Datenbanken, Messaging, Identity Provider, Observability, Backup, GitOps und hybride Infrastruktur.
Ein gutes Zielbild hilft bei Entscheidungen. Wenn ein neuer Service entsteht, kann man fragen: Passt er in das Zielbild? Braucht er eine Ausnahme? Muss das Zielbild angepasst werden?
Hybrid-Architektur
Hybrid bedeutet im Lab nicht Chaos, sondern bewusstes Zusammenspiel verschiedener Infrastrukturformen. Cloud, VMs, Bare Metal und Kubernetes/OpenShift werden nach Anforderungen eingesetzt.
Beispiele:
Vorlage / Textauszug
OpenShift: moderne Services, Portale, Event Consumer
Der typische Fehler ist eine ideologische Entscheidung: alles in die Cloud oder alles in Kubernetes. Ein Enterprise-System braucht aber oft differenzierte Entscheidungen.
---
3. Infrastrukturbegriffe
Netzwerkzone
Eine Netzwerkzone trennt Systeme nach Schutzbedarf und Funktion. Im Lab gibt es DMZ, Application Zone, Data Zone, Management Zone und Backup Zone. Diese Trennung verhindert, dass ein Fehler oder Angriff sofort alle Systeme betrifft.
Eine gute Netzwerkzone hat klare Regeln:
Vorlage / Textauszug
Welche Systeme stehen dort?
Wer darf hinein?
Wer darf hinaus?
Welche Ports sind erlaubt?
Wer ist verantwortlich?
DMZ
Die DMZ ist die Zone zwischen Internet und internem Netzwerk. Dort stehen Komponenten, die von außen erreichbar sind oder externen Traffic annehmen. Typische Beispiele sind Load Balancer, Reverse Proxies, API Gateways oder Web Application Firewalls.
Im Lab soll keine Datenbank direkt aus dem Internet erreichbar sein. Externe Zugriffe gehen über kontrollierte Wege: Internet, DMZ, OpenShift Router oder API Gateway, Service, Datenbank.
VLAN
Ein VLAN trennt Netzwerkverkehr logisch. Es kann zum Beispiel ein Management-VLAN, ein Application-VLAN und ein Data-VLAN geben. VLANs helfen, Systeme technisch voneinander zu trennen.
Für Entwickler ist wichtig: Wenn ein Service eine Datenbank nicht erreicht, kann der Grund außerhalb des Codes liegen. VLAN, Routing, Firewall, DNS oder NetworkPolicy können die Ursache sein.
Firewall-Regel
Eine Firewall-Regel erlaubt oder blockiert Netzwerkverkehr. Im Lab muss jede wichtige Regel fachlich begründet sein. Eine gute Regel beschreibt Quelle, Ziel, Port, Protokoll, Zweck und Verantwortliche.
Schlechte Regel:
Vorlage / Textauszug
Allow Application Network to Data Network any port
Gute Regel:
Vorlage / Textauszug
Quelle: order-prod Namespace
Ziel: orders-db.internal.alpine.example.com
Port: 5432/TCP
Zweck: Order Service speichert Bestellungen
Owner: Team Order
Review: halbjährlich
DNS
DNS übersetzt Namen in IP-Adressen. In Enterprise-Systemen ist DNS kritisch, weil Zertifikate, OIDC Redirects, Routes, APIs und interne Dienste davon abhängen.
Typischer Fehler: In Test wird ein anderer Name verwendet als in Produktion, aber der OIDC Client ist nur für einen Redirect konfiguriert. Dann schlägt Login fehl, obwohl Keycloak und Anwendung laufen.
Load Balancer
Ein Load Balancer verteilt Anfragen auf mehrere Ziele. Im Lab gibt es oft mehrere Ebenen: externer Load Balancer, OpenShift Router, Kubernetes Service und Pods.
Wenn ein Endpoint nicht erreichbar ist, muss man systematisch prüfen:
bash
nslookup api.alpine.example.com
curl -vk https://api.alpine.example.com/orders
oc get route -n order-prod
oc get svc -n order-prod
oc get endpoints -n order-prod
oc get pods -n order-prod
Bare Metal
Bare Metal bezeichnet physische Server ohne Virtualisierungsschicht für den eigentlichen Workload. Im Lab eignet sich Bare Metal für große Datenbanken, Storage-nahe Verarbeitung und Backup-Repositories.
Bare Metal ist nicht automatisch moderner oder besser. Es ist nur direkter an der Hardware. Dadurch kann es leistungsfähig sein, aber auch mehr Betriebsverantwortung verursachen.
Virtuelle Maschine
Eine VM ist ein virtualisierter Server. VMs sind im Enterprise-Betrieb weiterhin wichtig. Sie eignen sich für Legacy-Anwendungen, interne Tools, Reporting, Migrationsjobs oder Anwendungen mit Betriebssystemabhängigkeiten.
Eine VM braucht genau wie ein Container saubere Betriebsregeln: Patchmanagement, Monitoring, Logging, Backup, Zugriffskontrolle und Konfigurationsmanagement.
---
4. Cloud-Begriffe
VPC und VNet
VPC oder VNet bezeichnet ein isoliertes Netzwerk in einer Cloud. Darin werden Subnetze, Routing, Security Groups und Verbindungen zu anderen Netzen definiert.
Im Lab wird eine Cloud nicht als magischer Ort betrachtet. Auch dort gelten Zonen, Sicherheitsregeln und Namenskonventionen.
Public Subnet
Ein Public Subnet enthält Ressourcen, die über das Internet erreichbar sein können. Das bedeutet nicht, dass jede Ressource dort offen sein darf. Es bedeutet nur, dass Routing zum Internet grundsätzlich möglich ist.
Typische Komponenten:
Vorlage / Textauszug
Public Load Balancer
Bastion Host, wenn wirklich nötig
API Gateway
Private Subnet
Ein Private Subnet enthält interne Ressourcen ohne direkten Internetzugang von außen. Anwendungskomponenten, Datenbanken und interne Services gehören meist in private Subnetze.
Security Group
Eine Security Group ist eine cloudnahe Firewall-Regelgruppe. Sie definiert, welcher Traffic erlaubt ist. Wie bei klassischen Firewalls gilt: Regeln sollen eng, dokumentiert und überprüfbar sein.
IAM
IAM steht für Identity and Access Management. In der Cloud beschreibt IAM, welche Identität welche Ressource verwenden darf. Ein häufiger Fehler ist zu breite Berechtigung, zum Beispiel AdministratorAccess für eine CI/CD-Pipeline.
Besser ist das Least-Privilege-Prinzip: Jede Identität bekommt nur die Rechte, die sie wirklich braucht.
Object Storage
Object Storage speichert Dateien als Objekte, meistens über eine S3-kompatible API. Im Lab eignet sich Object Storage für Partnerdateien, Exporte, Backups und Austausch zwischen Systemen.
Wichtig: Object Storage ersetzt nicht automatisch eine relationale Datenbank. Es ist gut für Dateien und Objekte, aber nicht für transaktionale Geschäftslogik.
Managed Database
Eine Managed Database wird vom Cloud-Anbieter betrieben. Das reduziert Betriebsaufwand, aber nicht Architekturverantwortung. Backup, Zugriff, Kosten, Migration, Latenz und Datenklassifizierung müssen trotzdem geklärt werden.
---
5. Kubernetes- und OpenShift-Begriffe
Kubernetes
Kubernetes ist eine Plattform zur Orchestrierung von Containern. Es startet, überwacht und skaliert Anwendungen. Kubernetes löst aber nicht automatisch Architekturprobleme. Ein schlecht geschnittener Service bleibt schlecht, auch wenn er in Kubernetes läuft.
OpenShift
OpenShift ist eine Enterprise-Kubernetes-Plattform mit zusätzlichen Funktionen wie Routes, integrierter Registry, Build-Funktionen, Security Constraints, Operatoren und stärkerer Enterprise-Integration.
Im Lab ist OpenShift die Zielplattform für moderne Services.
Namespace
Ein Namespace trennt Ressourcen logisch. Im Lab werden Namespaces nach Domäne und Umgebung getrennt:
Vorlage / Textauszug
order-dev
order-test
order-prod
billing-dev
billing-test
billing-prod
platform-monitoring
security-keycloak
Namespaces helfen bei RBAC, Quotas, NetworkPolicies und Verantwortungsgrenzen.
Pod
Ein Pod ist die kleinste ausführbare Einheit in Kubernetes. Er enthält einen oder mehrere Container. Ein Pod ist vergänglich. Deshalb dürfen wichtige Daten nicht nur im Pod-Dateisystem gespeichert werden.
Deployment
Ein Deployment beschreibt, wie viele Replikate einer Anwendung laufen sollen und welches Container-Image verwendet wird. Es steuert Rollouts und Rollbacks.
Service
Ein Service gibt Pods eine stabile Netzwerkadresse innerhalb des Clusters. Pods können verschwinden und neu entstehen. Der Service bleibt stabil.
Route
Eine OpenShift Route macht einen Service von außen erreichbar. Sie ist besonders wichtig für Web-Anwendungen und APIs.
ConfigMap
Eine ConfigMap enthält nicht-geheime Konfiguration. Beispiele sind Feature Flags, URLs oder technische Einstellungen. Secrets gehören nicht in ConfigMaps.
Secret
Ein Secret enthält sensible Werte wie Passwörter, Tokens oder Zertifikate. Im Lab sollen Secrets möglichst über Vault oder External Secrets verwaltet werden, nicht hart in Git gespeichert werden.
NetworkPolicy
Eine NetworkPolicy begrenzt Netzwerkverkehr im Cluster. Sie ist ein wichtiges Werkzeug für Zero Trust. Ohne Policies können Workloads oft zu viel miteinander kommunizieren.
ServiceAccount
Ein ServiceAccount ist eine Identität für eine Anwendung im Cluster. Anwendungen sollen nicht mit administrativen Rechten laufen. Jeder Service bekommt nur die Rechte, die er braucht.
RBAC
RBAC steht für Role-Based Access Control. In Kubernetes/OpenShift steuert RBAC, welche Benutzer, Gruppen oder ServiceAccounts welche Aktionen ausführen dürfen.
Wichtig ist die Trennung:
Vorlage / Textauszug
Kubernetes RBAC: Wer darf im Cluster Ressourcen verwalten?
Fachliches RBAC: Welcher Benutzer darf im Admin Portal welche Geschäftsfunktion ausführen?
Diese beiden Ebenen dürfen nicht vermischt werden.
SCC
SCC steht für Security Context Constraints. OpenShift nutzt SCCs, um festzulegen, welche Sicherheitskontexte Pods verwenden dürfen. Das betrifft zum Beispiel Root-Rechte, UID, Capabilities und Volume-Typen.
Ein häufiger Fehler ist, einer Anwendung zu breite Rechte zu geben, nur weil sie sonst nicht startet. Besser ist, das Image und die Anwendung so zu bauen, dass sie mit wenig Rechten laufen.
---
6. Security- und Identity-Begriffe
Authentifizierung
Authentifizierung beantwortet die Frage: Wer bist du? Im Lab übernimmt Keycloak diese Aufgabe für Benutzer. Anwendungen vertrauen nicht auf selbstgebaute Login-Logik, sondern verwenden OIDC.
Autorisierung
Autorisierung beantwortet die Frage: Was darfst du? Ein Benutzer kann erfolgreich angemeldet sein, aber trotzdem keine Berechtigung für eine Admin-Funktion haben.
Keycloak
Keycloak ist ein Identity Provider. Er verwaltet Realms, Clients, Benutzer, Gruppen, Rollen und Tokens. Im Lab wird Keycloak an LDAP oder Active Directory angebunden.
OIDC
OIDC steht für OpenID Connect. Es baut auf OAuth 2.0 auf und wird für moderne Authentifizierung verwendet. Eine Anwendung erhält Tokens und prüft Identität und Claims.
JWT
JWT steht für JSON Web Token. Es enthält Claims wie Benutzername, Rollen, Gruppen, Ablaufzeit und Aussteller. Anwendungen dürfen einem JWT nur vertrauen, wenn Signatur, Issuer, Audience und Ablaufzeit korrekt sind.
Claim
Ein Claim ist eine Aussage im Token. Beispiele sind sub, email, preferred_username, roles oder groups. Anwendungen nutzen Claims für fachliche Entscheidungen.
Zero Trust
Zero Trust bedeutet: Kein System wird automatisch vertraut, nur weil es im internen Netzwerk ist. Jeder Zugriff wird anhand von Identität, Kontext, Policy und Nachweis bewertet.
Im Lab bedeutet Zero Trust:
Vorlage / Textauszug
nur notwendige Netzwerkverbindungen
starke Authentifizierung
klare Rollen
ServiceAccounts mit wenig Rechten
Audit Logs
Secrets nicht im Code
überprüfbare Policies
Least Privilege
Least Privilege bedeutet: Eine Identität bekommt nur die Rechte, die sie wirklich braucht. Das gilt für Benutzer, ServiceAccounts, CI/CD-Pipelines und Cloud-Rollen.
Audit Logging
Audit Logging dokumentiert sicherheitsrelevante Aktionen. Im Admin Portal muss zum Beispiel nachvollziehbar sein, wer eine Bestellung manuell geändert oder eine Rechnung neu ausgelöst hat.
Ein gutes Audit Log enthält:
Vorlage / Textauszug
Wer?
Was?
Wann?
Auf welchem Objekt?
Mit welchem Ergebnis?
Über welche Anwendung?
Mit welcher Trace-ID?
Governance
Governance beschreibt Regeln, Verantwortlichkeiten und Nachweise. Im Lab bedeutet Governance nicht Bürokratie, sondern klare Qualitätsgrenzen: Pull Requests, ADRs, Security Reviews, Runbooks, Tests und Betriebsnachweise.
---
7. Entwicklungs- und Anwendungsbegriffe
Domäne
Die Domäne ist der fachliche Problembereich. Im Lab gehören Bestellung, Rechnung, Kunde, Partnerdatei und Reporting zur Domäne. Gute Software modelliert die Domäne klar, statt nur Datenbanktabellen nach außen zu reichen.
Use Case
Ein Use Case beschreibt einen fachlichen Ablauf. Beispiel: Bestellung anlegen, Rechnung erzeugen, Partnerdatei validieren. Im Code liegt ein Use Case oft in der Anwendungsschicht.
Controller
Ein Controller nimmt HTTP-Anfragen entgegen und übersetzt sie in Use-Case-Aufrufe. Er sollte nicht die gesamte Geschäftslogik enthalten.
Controller nimmt Request entgegen, prüft Grundform, ruft Use Case auf und gibt Response zurück.
Repository
Ein Repository kapselt Datenzugriff. Die Domäne muss nicht wissen, ob Daten über JPA, JDBC oder eine externe API gespeichert werden.
Outbox Pattern
Das Outbox Pattern speichert Events zuerst in derselben Datenbanktransaktion wie die fachliche Änderung. Danach veröffentlicht ein separater Publisher die Events an den Broker.
Es verhindert, dass Datenbankzustand und Event-Veröffentlichung auseinanderlaufen.
Idempotenz
Idempotenz bedeutet, dass eine Operation mehrfach ausgeführt werden kann, ohne falsche Mehrfachwirkung zu erzeugen. Bei Messaging ist Idempotenz wichtig, weil Events erneut zugestellt werden können.
Beispiel: Der Billing Service darf eine Rechnung nicht doppelt erzeugen, nur weil ein OrderCreated Event erneut gelesen wird.
API Gateway
Ein API Gateway bündelt und kontrolliert API-Zugriffe. Es kann Routing, Authentifizierung, Rate Limiting, TLS und zentrale Policies unterstützen. Es ersetzt aber keine saubere Servicearchitektur.
Backend for Frontend
Ein Backend for Frontend ist ein Backend, das speziell auf ein Frontend zugeschnitten ist. Es kann sinnvoll sein, wenn ein Customer Portal andere API-Bedürfnisse hat als ein Admin Portal.
---
8. Daten- und Integrationsbegriffe
Datenbesitz
Datenbesitz bedeutet: Ein Service oder eine Domäne ist verantwortlich für bestimmte Daten. Andere Services greifen nicht einfach direkt auf seine Tabellen zu.
Im Lab besitzt der Order Service Bestelldaten. Billing besitzt Rechnungsdaten. Reporting darf Kopien oder Views nutzen, aber nicht heimlich Geschäftslogik über fremde Tabellen erzwingen.
Gemeinsame Datenbank
Eine gemeinsame Datenbank zwischen mehreren Services ist oft ein Legacy-Muster. Es wirkt einfach, führt aber zu starker Kopplung. Änderungen an Tabellen betreffen dann mehrere Systeme gleichzeitig.
Migration
Eine Migration verändert Datenbankstruktur oder Daten. Im Lab werden Flyway oder Liquibase verwendet. Migrationen gehören in Git und werden im Deployment kontrolliert ausgeführt.
Event
Ein Event beschreibt etwas, das fachlich passiert ist. Beispiel: OrderCreated, InvoiceGenerated, PartnerFileRejected. Ein Event ist keine Anweisung, sondern eine Tatsache.
Command
Ein Command fordert eine Aktion an. Beispiel: CreateOrder, CancelOrder, GenerateInvoice. Commands und Events sollten nicht verwechselt werden.
Kafka
Kafka ist ein verteilter Event-Streaming-Broker. Es eignet sich für Event Streams, Replay, hohe Durchsatzraten und langlebige Topics.
RabbitMQ
RabbitMQ ist ein Message Broker, der stark bei Queues, Routing und klassischem Messaging ist. Für viele Unternehmensintegrationen ist RabbitMQ gut geeignet.
Dead Letter Queue
Eine Dead Letter Queue nimmt Nachrichten auf, die nicht erfolgreich verarbeitet werden konnten. Sie ist wichtig, damit fehlerhafte Nachrichten nicht endlos den normalen Fluss blockieren.
Anti-Corruption Layer
Ein Anti-Corruption Layer schützt eine moderne Domäne vor schlechten oder alten Modellen eines Legacy-Systems. Er übersetzt externe Begriffe, Datenstrukturen und Fehlerbilder in saubere interne Modelle.
---
9. Observability- und Betriebsbegriffe
Monitoring
Monitoring beobachtet Systeme anhand von Metriken, Logs und Zuständen. Es zeigt, ob etwas funktioniert oder nicht.
Observability
Observability geht weiter. Sie hilft, aus Systemsignalen zu verstehen, warum etwas passiert. Logs, Metriken und Traces werden gemeinsam betrachtet.
Log
Ein Log ist ein Ereignisprotokoll. Gute Logs sind strukturiert, enthalten Trace-ID, Benutzer- oder Systemkontext und vermeiden sensible Daten.
Metrik
Eine Metrik ist ein messbarer Wert. Beispiele sind Request-Dauer, Fehlerrate, CPU-Nutzung, Outbox Backlog oder Anzahl fehlerhafter Partnerdateien.
Trace
Ein Trace verfolgt eine Anfrage über mehrere Systeme. Das ist wichtig, wenn ein Customer-Portal-Aufruf über API Gateway, Order Service, Datenbank und Broker läuft.
SLI
SLI steht für Service Level Indicator. Ein SLI ist eine konkrete Messgröße, zum Beispiel Erfolgsrate oder Latenz.
SLO
SLO steht für Service Level Objective. Ein SLO definiert ein Ziel, zum Beispiel: 99,5 Prozent der Order-API-Aufrufe sollen unter 500 Millisekunden bleiben.
Alert
Ein Alert informiert, wenn ein Zustand Aufmerksamkeit braucht. Ein schlechter Alert ist laut, aber unklar. Ein guter Alert ist konkret, handlungsorientiert und mit einem Runbook verknüpft.
Runbook
Ein Runbook beschreibt, was bei einem bestimmten Betriebsproblem zu tun ist. Es verbindet Symptome, Prüfkommandos, Ursachen, Maßnahmen und Eskalation.
---
10. Backup- und DR-Begriffe
Backup
Ein Backup ist eine Sicherung von Daten oder Konfiguration. Ein Backup ist nur dann wertvoll, wenn Restore getestet wurde.
Restore
Restore ist die Wiederherstellung aus einem Backup. Im Lab wird Restore nicht nur theoretisch erwähnt, sondern als Übung und Runbook behandelt.
Disaster Recovery
Disaster Recovery beschreibt den Wiederanlauf nach einem größeren Ausfall. Es geht nicht nur um Daten, sondern um Reihenfolge, Abhängigkeiten, Kommunikation und Validierung.
RPO
RPO steht für Recovery Point Objective. Es beschreibt, wie viel Datenverlust maximal akzeptabel ist.
RTO
RTO steht für Recovery Time Objective. Es beschreibt, wie lange die Wiederherstellung maximal dauern darf.
WAL
WAL steht für Write-Ahead Log. PostgreSQL nutzt WAL, um Änderungen nachvollziehbar zu speichern. WAL-Archivierung ist wichtig für Point-in-Time-Recovery.
VolumeSnapshot
Ein VolumeSnapshot ist eine Momentaufnahme eines Persistent Volumes. In Kubernetes/OpenShift kann das für bestimmte Restore-Szenarien nützlich sein, ersetzt aber nicht jedes Datenbankbackup.
---
11. DevOps- und GitOps-Begriffe
DevOps
DevOps verbindet Entwicklung und Betrieb. Im Lab bedeutet das: Entwickler schreiben nicht nur Code, sondern berücksichtigen Deployment, Monitoring, Security und Runbooks. Betrieb arbeitet nicht nur reaktiv, sondern mit Automatisierung, Git und Feedback an Teams.
CI
CI steht für Continuous Integration. Codeänderungen werden automatisch gebaut und getestet.
CD
CD steht für Continuous Delivery oder Continuous Deployment. Im Enterprise-Kontext bedeutet es oft: Artefakte sind jederzeit auslieferbar, aber produktive Freigabe kann kontrolliert erfolgen.
GitOps
GitOps bedeutet: Der gewünschte Plattformzustand liegt in Git. Ein Controller wie Argo CD vergleicht Git mit dem Cluster und synchronisiert Abweichungen.
Argo CD
Argo CD ist ein GitOps-Werkzeug für Kubernetes/OpenShift. Es deployt Anwendungen aus Git-Repositories und zeigt Synchronisationszustand, Drift und Fehler.
Kustomize
Kustomize passt Kubernetes-Manifeste ohne Templates an. Es eignet sich gut für Overlays wie dev, test und prod.
Helm
Helm ist ein Paket- und Template-System für Kubernetes. Es eignet sich für wiederverwendbare Charts, kann aber bei komplexen Templates schwer lesbar werden.
Image Tag
Ein Image Tag identifiziert eine Container-Image-Version. Für produktive Deployments sollten nachvollziehbare Tags oder Digests verwendet werden. latest ist für produktionsnahe Umgebungen ungeeignet.
Rollback
Rollback bedeutet Rückkehr zu einer vorherigen Version. Bei Datenbankmigrationen ist Rollback schwieriger als bei Container Images. Deshalb braucht Release Management auch Rollforward-Strategien.
---
12. AI-Begriffe im Enterprise-Projekt
Codex
Codex wird im Lab als Unterstützung für Code, Tests, Refactoring und technische Artefakte betrachtet. Codex darf Vorschläge machen, aber nicht ungeprüft produktionsrelevante Entscheidungen ersetzen.
Claude Code
Claude Code wird im Lab als Unterstützung für größere Code- und Architekturaufgaben betrachtet, besonders bei Analyse, Refactoring und Dokumentation. Auch hier gilt: AI-Ergebnisse müssen überprüft werden.
AI-Fülltext
AI-Fülltext ist Text, der sprachlich korrekt wirkt, aber fachlich wenig aussagt. Der hochgeladene Problemausschnitt war genau so ein Beispiel: dieselbe Struktur wiederholt sich, nur einzelne Begriffe werden ersetzt.
Gegenmaßnahme:
Vorlage / Textauszug
konkrete Beispiele fordern
Wiederholungen prüfen
Code und Artefakte verlangen
fachliche Unterschiede kontrollieren
keine künstlichen Nummern akzeptieren
Prompt-Regel
Eine Prompt-Regel ist eine feste Vorgabe für AI-Arbeit. Im Lab lautet eine wichtige Regel: Kein Kapitel darf nur aus Tabellen oder Glossar bestehen, und keine Inhalte dürfen künstlich durch austauschbare Absätze verlängert werden.
---
13. Fachindex nach Themen
Architektur
Vorlage / Textauszug
ADR
Architekturentscheidung
Enterprise-Architektur
Hybrid-Architektur
Zielbild
Domänenschnitt
Betriebsmodell
Infrastruktur
Vorlage / Textauszug
DMZ
VLAN
Subnetz
Firewall
DNS
Load Balancer
Bare Metal
Virtuelle Maschine
Storage
Bastion Host
Cloud
Vorlage / Textauszug
VPC
VNet
Public Subnet
Private Subnet
IAM
Security Group
Object Storage
Managed Database
VPN
Direct Connect
Kubernetes/OpenShift
Vorlage / Textauszug
Namespace
Pod
Deployment
Service
Route
ConfigMap
Secret
ServiceAccount
RBAC
SCC
NetworkPolicy
PersistentVolume
CronJob
Operator
Security
Vorlage / Textauszug
Keycloak
OIDC
JWT
Claim
RBAC
Zero Trust
Least Privilege
Audit Logging
Secret Rotation
Policy as Code
Anwendungen
Vorlage / Textauszug
Use Case
Controller
Repository
Domain Model
Outbox Pattern
Idempotenz
API Gateway
Backend for Frontend
OpenAPI
Testcontainers
Daten und Integration
Vorlage / Textauszug
Datenbesitz
Migration
Event
Command
Kafka
RabbitMQ
Dead Letter Queue
Anti-Corruption Layer
CDC
Object Storage
Betrieb
Vorlage / Textauszug
Monitoring
Observability
Log
Metrik
Trace
SLI
SLO
Alert
Runbook
Incident
Postmortem
Backup und DR
Vorlage / Textauszug
Backup
Restore
Disaster Recovery
RPO
RTO
WAL
VolumeSnapshot
Restore-Test
DevOps und GitOps
Vorlage / Textauszug
CI
CD
GitOps
Argo CD
Kustomize
Helm
Image Tag
Rollback
Rollforward
Release Notes
---
14. Prüfregel für spätere HTML-Erzeugung
Bei der späteren HTML-Erzeugung muss dieser Teil nicht als riesiger Glossarblock am Ende erscheinen. Stattdessen wird er als Fachindex eingebunden und zusätzlich mit den Hauptkapiteln verlinkt.
Die HTML-Version soll folgende Regeln einhalten:
Vorlage / Textauszug
Begriffe bleiben mit Fachkapiteln verbunden.
Keine isolierte Glossarwüste als Hauptinhalt.
Jeder Begriff erhält Kontext, Fehlerbild und Nachweis.
Fachindex ist klappbar und standardmäßig geschlossen.
Navigation verwendet fachliche Namen.
Keine generischen Begriffe wie Anhang 16 oder Praxisdurchlauf X.
---
15. Übung
Wähle fünf Begriffe aus diesem Teil und ordne sie konkreten Artefakten im Lab zu.
Beispiel-Fragen:
Vorlage / Textauszug
Welches Artefakt zeigt eine Architekturentscheidung?
Welches Manifest zeigt eine NetworkPolicy?
Wo wird ein Secret technisch definiert?
Wo wird ein Restore beschrieben?
Wo wird ein SLO messbar gemacht?
---
16. Musterlösung
Eine mögliche Lösung:
Vorlage / Textauszug
ADR:
Nachweis durch docs/adr/ADR-001-hybrid-platform.md
NetworkPolicy:
Nachweis durch platform/network-policies/order-prod-egress.yaml
Secret:
Nachweis durch security/secrets/order-db-external-secret.yaml oder ExternalSecret im GitOps-Repo
Restore:
Nachweis durch docs/runbooks/postgresql-restore.md
SLO:
Nachweis durch observability/prometheus/order-service-slo-rules.yaml und Grafana-Dashboard
Diese Zuordnung zeigt, dass Begriffe nicht nur gelernt, sondern im Projekt verankert werden.
---
17. Merksätze
Vorlage / Textauszug
Ein Begriff ist erst wirklich verstanden, wenn man ihn im Projekt zeigen kann.
Ein Glossar ohne Kontext hilft wenig.
Ein Fachindex ist nützlich, wenn er auf echte Kapitel, Artefakte und Fehlerbilder verweist.
Enterprise-Wissen besteht aus Sprache, Code, Infrastruktur, Betrieb und Nachweisen.
Die spätere HTML-Datei darf groß sein, aber nur durch echten Inhalt, nicht durch künstliche Wiederholung.
Kompakte SVGs und großer Fachglossar
Ziel dieses Schritts
Dieser Schritt ergänzt das Masterbuch um eine kompakte visuelle Referenz und einen großen Fachglossar. Die SVGs sind bewusst klein, direkt eingebettet und ohne externe Bilddateien nutzbar. Der Glossar ist als Nachschlagebereich gedacht und ersetzt nicht die fachlichen Kapitel. Er unterstützt die spätere HTML-Version, weil Leser zentrale Begriffe schnell finden, ohne zwischen mehreren Anhängen suchen zu müssen.
Wichtig bleibt: Die SVGs und Begriffe werden nicht als künstliche Füllmasse verwendet. Sie sind ein Navigations- und Verständniswerkzeug für die bereits geschriebenen Fachkapitel.
Kompakte SVG-Übersichten
Die folgenden Diagramme sind bewusst reduziert. Sie zeigen nicht jedes Detail, sondern den Kernfluss. Für mobile Geräte ist das besser als große, überladene Diagramme.
Hybrid-Zielbild kompakt
Kurzer Nutzen: Dieses Diagramm dient als schneller visueller Anker für den jeweiligen Architekturfluss. Details bleiben im passenden Fachkapitel erklärt.
Zonenmodell kompakt
Kurzer Nutzen: Dieses Diagramm dient als schneller visueller Anker für den jeweiligen Architekturfluss. Details bleiben im passenden Fachkapitel erklärt.
OIDC-Fluss kompakt
Kurzer Nutzen: Dieses Diagramm dient als schneller visueller Anker für den jeweiligen Architekturfluss. Details bleiben im passenden Fachkapitel erklärt.
Outbox-Fluss kompakt
Kurzer Nutzen: Dieses Diagramm dient als schneller visueller Anker für den jeweiligen Architekturfluss. Details bleiben im passenden Fachkapitel erklärt.
GitOps-Fluss kompakt
Kurzer Nutzen: Dieses Diagramm dient als schneller visueller Anker für den jeweiligen Architekturfluss. Details bleiben im passenden Fachkapitel erklärt.
Observability kompakt
Kurzer Nutzen: Dieses Diagramm dient als schneller visueller Anker für den jeweiligen Architekturfluss. Details bleiben im passenden Fachkapitel erklärt.
Backup/Restore kompakt
Kurzer Nutzen: Dieses Diagramm dient als schneller visueller Anker für den jeweiligen Architekturfluss. Details bleiben im passenden Fachkapitel erklärt.
VM zu OpenShift kompakt
Kurzer Nutzen: Dieses Diagramm dient als schneller visueller Anker für den jeweiligen Architekturfluss. Details bleiben im passenden Fachkapitel erklärt.
Security-Grenzen kompakt
Kurzer Nutzen: Dieses Diagramm dient als schneller visueller Anker für den jeweiligen Architekturfluss. Details bleiben im passenden Fachkapitel erklärt.
Release-Fluss kompakt
Kurzer Nutzen: Dieses Diagramm dient als schneller visueller Anker für den jeweiligen Architekturfluss. Details bleiben im passenden Fachkapitel erklärt.
File Processing kompakt
Kurzer Nutzen: Dieses Diagramm dient als schneller visueller Anker für den jeweiligen Architekturfluss. Details bleiben im passenden Fachkapitel erklärt.
DR-Wiederanlauf kompakt
Kurzer Nutzen: Dieses Diagramm dient als schneller visueller Anker für den jeweiligen Architekturfluss. Details bleiben im passenden Fachkapitel erklärt.
Großer Fachglossar
Der Glossar ist alphabetisch und praxisbezogen. Jede Erklärung bezieht sich auf das Enterprise Platform Lab und vermeidet reine Wörterbuchdefinitionen.
ADR
Architecture Decision Record. Dokumentiert eine wichtige Entscheidung mit Kontext, Entscheidung und Konsequenzen, damit Architektur nicht nur mündlich existiert.
API Gateway
Zentrale Eingangsschicht für APIs. Es kann Routing, Authentifizierung, Rate Limits und Protokollwechsel bündeln, ersetzt aber keine saubere Servicegrenze.
Application Zone
Netzwerkzone für Anwendungssysteme. Sie darf typischerweise nicht direkt aus dem Internet erreichbar sein und spricht nur kontrolliert mit der Data Zone.
Argo CD
GitOps-Werkzeug, das Kubernetes- oder OpenShift-Zustand aus Git synchronisiert. Git wird dadurch zur nachvollziehbaren Quelle der Deployments.
Audit Log
Protokoll sicherheits- oder fachlich relevanter Aktionen. Wichtig ist nicht nur das Speichern, sondern die spätere Auswertbarkeit im Störungs- und Compliance-Fall.
Backlog
Ansammlung unbearbeiteter Arbeit, etwa nicht veröffentlichter Outbox-Events. Ein Backlog ist ein Betriebsindikator und muss überwacht werden.
Backup
Kopie von Daten oder Systemzustand. Ein Backup ist erst wertvoll, wenn Restore regelmäßig geprüft wurde.
Bare Metal
Physischer Server ohne Virtualisierungsschicht. Sinnvoll bei besonderen Storage-, Latenz- oder Performance-Anforderungen.
Bastion Host
Kontrollierter Zugangspunkt für Administration. Er reduziert direkte SSH-Zugriffe aus beliebigen Netzen.
Billing Service
Service für Rechnungs- oder Abrechnungslogik. Im Lab verarbeitet er Events vom Order Service idempotent.
Blue-Green Deployment
Release-Strategie mit zwei Umgebungen. Die neue Version wird parallel bereitgestellt und Traffic wird kontrolliert umgeschaltet.
Broker
Messaging-System wie Kafka oder RabbitMQ. Es entkoppelt Producer und Consumer, beseitigt aber nicht die Pflicht zu Idempotenz und Fehlerbehandlung.
Canary Release
Schrittweise Auslieferung einer neuen Version an einen kleinen Teil der Nutzer oder des Traffics.
CD
Continuous Delivery oder Continuous Deployment. In diesem Lab bedeutet es nachvollziehbares Ausliefern über Pipeline und GitOps.
CI
Continuous Integration. Code wird gebaut, getestet und geprüft, bevor er als lieferfähig gilt.
Cloud Landing Zone
Grundstruktur in der Cloud mit Accounts, Netzwerk, IAM, Logging, Security und Kostenkontrolle.
ConfigMap
Kubernetes-Objekt für nicht geheime Konfiguration. Sensible Werte gehören nicht in ConfigMaps.
Container Image
Paket aus Anwendung, Runtime und Abhängigkeiten. Es muss versioniert, gescannt und reproduzierbar gebaut werden.
Correlation-ID
Kennung, mit der zusammengehörige Logs über mehrere Services verbunden werden können.
CronJob
Kubernetes-Ressource für zeitgesteuerte Jobs. Geeignet für periodische Aufgaben, aber nicht für dauerhaft laufende Services.
Customer Portal
Frontend für Kunden. Es ruft APIs auf, speichert keine Secrets und nutzt OIDC für Anmeldung.
Data Zone
Netzwerkzone für Datenbanken, Broker und Storage. Sie ist besonders geschützt und sollte nicht direkt aus DMZ oder Internet erreichbar sein.
Dead Letter Queue
Ablage für Nachrichten, die nicht erfolgreich verarbeitet werden konnten. Sie ist kein Mülleimer, sondern ein Betriebsnachweis.
Deployment
Kubernetes-Ressource für zustandslose Pods. Sie beschreibt gewünschte Replikas, Container, Probes und Ressourcen.
DevOps
Arbeitsmodell, bei dem Entwicklung und Betrieb gemeinsam Verantwortung für lauffähige, beobachtbare und wiederherstellbare Systeme übernehmen.
Disaster Recovery
Wiederanlauf nach großem Ausfall. DR braucht Reihenfolge, Verantwortliche, Datenwiederherstellung und Tests.
DMZ
Demilitarized Zone. Übergangszone für öffentlich erreichbare Komponenten, ohne direkte Öffnung interner Systeme.
DNS
Namensauflösung. Fehler in DNS wirken oft wie Anwendungsfehler und müssen deshalb Teil der Architekturprüfung sein.
Dockerfile
Build-Anweisung für Container Images. Es sollte klein, nachvollziehbar, sicher und ohne unnötige Tools aufgebaut sein.
Environment Promotion
Kontrolliertes Überführen einer Version von Dev nach Test, Stage und Prod.
ExternalSecret
Ressource, die Secrets aus einem externen Secret Store in Kubernetes nutzbar macht.
Feature Flag
Schalter, mit dem Funktionen aktiviert oder deaktiviert werden können, ohne zwingend neu zu deployen.
File Processing
Verarbeitung von Partnerdateien oder Exporten. Kann auf VM, Bare Metal oder Kubernetes laufen, je nach Storage- und Lastprofil.
Firewall-Matrix
Dokumentation erlaubter Netzwerkflüsse mit Quelle, Ziel, Port, Zweck und Verantwortlichkeit.
Flyway
Werkzeug für versionierte Datenbankmigrationen. Es macht Schemaänderungen nachvollziehbar.
GitOps
Betriebsmodell, bei dem gewünschter Plattformzustand in Git liegt und automatisiert synchronisiert wird.
Grafana
Visualisierung für Metriken, Logs und teilweise Traces. Grafana ersetzt keine sauberen SLOs.
Hardening
Härtung von Systemen durch Reduktion von Angriffsfläche, sichere Defaults, eingeschränkte Rechte und Nachweise.
Health Check
Prüfung, ob ein Service grundsätzlich läuft. Readiness und Liveness haben unterschiedliche Bedeutung.
Helm
Paket- und Template-Werkzeug für Kubernetes-Ressourcen. Mächtig, aber bei falscher Nutzung schwer lesbar.
Hybrid Architektur
Architektur, die Cloud, VM, Bare Metal und Kubernetes gezielt kombiniert statt alles ideologisch auf eine Plattform zu zwingen.
IAM
Identity and Access Management. Regelt Identitäten, Rollen, Policies und Zugriffsrechte.
Idempotenz
Eigenschaft, dass eine wiederholte Verarbeitung keine falschen Mehrfachwirkungen erzeugt.
Incident
Störung mit Auswirkung auf Betrieb oder Sicherheit. Ein Incident braucht Triage, Eindämmung, Kommunikation und Nachbereitung.
Ingress
Kubernetes-Mechanismus für eingehenden HTTP/S-Traffic. In OpenShift wird häufig Route verwendet.
Jenkinsfile
Pipeline-Definition für Jenkins. In Enterprise-Umgebungen oft weiterhin wichtig.
Kafka
Event-Streaming-Plattform. Gut für Event Logs und skalierbare Verarbeitung, verlangt aber saubere Topic- und Consumer-Strategien.
Keycloak
Identity Provider für OIDC, OAuth2 und SAML. Im Lab verbindet er Anwendungen mit LDAP/AD und Rollen.
Kustomize
Werkzeug für Kubernetes-Overlays ohne Template-Sprache. Gut für klare Umgebungsvarianten.
LDAP
Verzeichnisdienst für Benutzer, Gruppen und Organisationseinheiten. Häufig Grundlage für Enterprise-Identity.
Liveness Probe
Kubernetes-Prüfung, ob ein Container neu gestartet werden soll. Sie darf nicht mit fachlicher Bereitschaft verwechselt werden.
Loki
Log-System, das häufig mit Grafana verwendet wird. Es arbeitet labelorientiert und passt gut zu Kubernetes-Logs.
Managed Database
Cloud-Datenbankdienst mit ausgelagertem Betrieb. Er reduziert Aufwand, verändert aber Kosten-, Netzwerk- und Governance-Fragen.
Maven
Build-Werkzeug im Java-Ökosystem. Für Enterprise-Projekte wichtig wegen Modulstruktur, Plugins und reproduzierbaren Builds.
Micrometer
Metrik-Bibliothek für JVM-Anwendungen. Sie verbindet Anwendungscode mit Monitoring-Systemen wie Prometheus.
MinIO
S3-kompatibler Object Storage, oft für On-Prem- oder Lab-Umgebungen genutzt.
Namespace
Kubernetes-Isolations- und Organisationsbereich. Nützlich für Teams, Umgebungen, RBAC und NetworkPolicies.
NetworkPolicy
Kubernetes-Regel für erlaubte Pod-Kommunikation. Ein praktischer Baustein für Zero Trust im Cluster.
Node Exporter
Prometheus Exporter für Linux-Host-Metriken wie CPU, RAM, Disk und Netzwerk.
Object Storage
Speicher für Objekte über API, meist S3-kompatibel. Gut für Dateien, Exporte, Backups und Partnerdaten.
OIDC
OpenID Connect. Protokoll für Authentifizierung auf Basis von OAuth2.
OpenAPI
Maschinenlesbare API-Beschreibung. Hilft bei Dokumentation, Client-Generierung und Review.
OpenShift
Enterprise-Kubernetes-Plattform mit zusätzlichen Funktionen wie Routes, SCC, integrierter Registry und Operator-Ökosystem.
OpenTelemetry
Standard für Traces, Metriken und Logs. Hilft, verteilte Abläufe sichtbar zu machen.
Outbox Pattern
Muster, bei dem Datenänderung und Event in derselben Datenbanktransaktion gespeichert werden.
PodDisruptionBudget
Kubernetes-Regel, die Mindestverfügbarkeit bei freiwilligen Unterbrechungen schützt.
PostgreSQL
Relationale Datenbank. Im Lab zentrale Datenhaltung für Order und Billing.
Prometheus
Monitoring-System für Metriken. Es sammelt Werte über Pull-Mechanismus und wertet Alerts aus.
PrometheusRule
Kubernetes/OpenShift-Ressource für Alert-Regeln. Sie macht Betriebswissen versionierbar.
Pull Request
Review-Einheit für Code, Manifeste oder Dokumentation. Im Lab eine Qualitätsgrenze.
RabbitMQ
Message Broker mit Queues und Routing. Gut für klassische asynchrone Verarbeitung.
RBAC
Role Based Access Control. Rollen und Bindings legen fest, wer was darf.
Readiness Probe
Kubernetes-Prüfung, ob ein Pod Traffic erhalten darf. Sie sollte abhängige Startbedingungen berücksichtigen.
Release Notes
Beschreibung ausgelieferter Änderungen, Risiken und Betriebsfolgen.
ResourceQuota
Namespace-Grenze für Ressourcenverbrauch. Verhindert unkontrollierten Verbrauch durch fehlerhafte Workloads.
Restore
Wiederherstellung aus Backup. Restore ist der eigentliche Beweis für ein funktionierendes Backup.
Route
OpenShift-Ressource für extern erreichbare HTTP/S-Endpunkte.
Runbook
Betriebsanleitung für wiederkehrende Fehlerbilder oder Aufgaben. Es muss ausführbar, nicht nur beschreibend sein.
SCC
Security Context Constraints in OpenShift. Sie begrenzen, wie Pods laufen dürfen.
Secret
Kubernetes-Objekt für sensible Werte. Es braucht Schutz, Rotation und klare Besitzverhältnisse.
Service
Kubernetes-Abstraktion für Netzwerkzugriff auf Pods. Selector und Ports müssen sauber passen.
ServiceAccount
Identität für Workloads im Cluster. Wichtig für RBAC, externe Zugriffe und Audit.
ServiceMonitor
Ressource des Prometheus Operators, die beschreibt, welche Services Metriken liefern.
SFTP Gateway
Kontrollierter Dateiübergabepunkt für Partner oder Legacy-Systeme.
SLO
Service Level Objective. Zielwert für Verfügbarkeit oder Qualität, z. B. Erfolgsrate oder Latenz.
SLI
Service Level Indicator. Messwert, auf dem ein SLO basiert.
Software Supply Chain
Lieferkette von Code, Dependencies, Build, Image, Registry und Deployment.
Spring Boot Actuator
Spring-Boot-Modul für Health, Metrics und Betriebsendpunkte.
Strangler Pattern
Modernisierungsmuster, bei dem Legacy-Funktionalität schrittweise durch neue Services ersetzt wird.
Terraform/OpenTofu
Infrastructure-as-Code-Werkzeuge zur Beschreibung von Cloud- und Infrastrukturressourcen.
Testcontainers
Java-Testbibliothek, die echte Infrastrukturkomponenten als Container für Integrationstests startet.
Trace
Verfolgung eines Requests über mehrere Services. Hilft bei Latenz- und Fehleranalyse.
Trace-ID
Eindeutige Kennung eines technischen Ablaufs über Servicegrenzen hinweg.
Vault
Secret-Management-System für dynamische und statische Geheimnisse.
VLAN
Logische Netzwerksegmentierung. Hilft bei Zonierung und Zugriffstrennung.
VM
Virtuelle Maschine. Weiterhin wichtig für Legacy, Spezialtools und Übergangsarchitekturen.
VolumeSnapshot
Kubernetes-Mechanismus für Storage-Snapshots, abhängig vom Storage-Treiber.
WAL
Write-Ahead Log. Bei PostgreSQL wichtig für Recovery und Point-in-Time-Restore.
Zero Trust
Sicherheitsprinzip: Kein implizites Vertrauen aufgrund von Netzwerkposition. Identität, Kontext und Policies entscheiden.
Zone
Sicherheits- oder Betriebsbereich im Netzwerk. Zonen strukturieren erlaubte Kommunikationswege.
Admin Portal
Interne Oberfläche für Mitarbeiter. Benötigt stärkere Rollen, Audit und oft separate Freigaben.
Anti-Corruption Layer
Schicht, die ein modernes Domänenmodell vor Legacy-Strukturen schützt.
Backpressure
Kontrollmechanismus, wenn Verbraucher langsamer sind als Erzeuger. Wichtig bei Messaging und Streaming.
Circuit Breaker
Resilienz-Muster, das wiederholte fehlgeschlagene Aufrufe zeitweise unterbricht.
Config Drift
Abweichung zwischen dokumentiertem oder gewünschtem Zustand und realem Systemzustand.
Dependency Scan
Prüfung von Bibliotheken auf bekannte Schwachstellen oder Lizenzprobleme.
Image Registry
Speicherort für Container Images. Muss geschützt, gescannt und versioniert genutzt werden.
Immutable Infrastructure
Prinzip, Systeme nicht im laufenden Zustand manuell zu verändern, sondern neu reproduzierbar bereitzustellen.
Least Privilege
Prinzip, nur die minimal notwendigen Rechte zu vergeben.
MTTR
Mean Time To Recovery. Durchschnittliche Zeit bis zur Wiederherstellung nach Störung.
Policy as Code
Sicherheits- oder Governance-Regeln werden versioniert und automatisch geprüft.
RPO
Recovery Point Objective. Maximal tolerierbarer Datenverlust.
RTO
Recovery Time Objective. Maximal tolerierbare Wiederherstellungszeit.
Sidecar
Zusätzlicher Container im selben Pod, z. B. für Proxy oder Hilfsfunktionen.
SLA
Service Level Agreement. Vertragliche oder organisatorische Zusage für Servicequalität.
Structured Logging
Logs in strukturierter Form, häufig JSON, damit sie maschinell auswertbar sind.
Tenant
Logischer Mandant oder Verantwortungsbereich. In Plattformen wichtig für Trennung und Governance.
TLS
Transportverschlüsselung. Zertifikate, Hostnamen und Trust Chains müssen zusammenpassen.
VPN
Verschlüsselte Netzwerkverbindung, z. B. zwischen Standort und Cloud.
WAF
Web Application Firewall. Schutzschicht gegen typische Webangriffe, ersetzt aber keine sichere Anwendung.
Webhook
HTTP-Rückruf bei Ereignissen. Muss abgesichert, nachvollziehbar und fehlertolerant sein.
Abnahmeregel für diesen Schritt
Die SVGs müssen im finalen HTML inline erscheinen und dürfen keine externen Dateien benötigen. Der Glossar darf groß sein, aber er muss klar als Referenzteil markiert bleiben. In den Hauptkapiteln sollen Begriffe weiterhin im Kontext erklärt werden.
Übung
Wähle fünf Begriffe aus dem Glossar und ordne sie jeweils einem konkreten Artefakt im Lab zu, zum Beispiel Manifest, README, ADR, Runbook, Test oder Dashboard.
Musterlösung
NetworkPolicy gehört zu Kubernetes-Manifests und begrenzt erlaubte Pod-Kommunikation.
ADR gehört zu docs/adr und dokumentiert eine Architekturentscheidung.
Outbox Pattern gehört zu Datenbankmigration, Anwendungscode und Runbook für Backlog.
ServiceMonitor gehört zur Observability-Konfiguration und macht Metriken auffindbar.
Restore gehört zu Backup-Runbooks und muss regelmäßig getestet werden.
Zusätzliche Architektur-SVGs, Glossar-Querverweise und HTML-Ausbau
Dieser Teil erweitert das Masterbuch nicht durch Wiederholung, sondern durch kompakte visuelle Orientierung und bessere Querverweise. Die SVGs sind bewusst klein gehalten: Sie sollen in der HTML-Datei nicht wie große Poster wirken, sondern als schnelle Orientierungskarten neben dem Fachtext dienen.
1. Warum weitere kompakte SVGs sinnvoll sind
Bei großen Enterprise-Lernbüchern entsteht schnell ein anderes Problem als bei kurzen Tutorials: Der Leser verliert die Gesamtkarte. Viele Kapitel erklären einzelne Themen gut, aber der Zusammenhang zwischen Netzwerk, Identity, Deployment, Daten, Betrieb und Recovery wird schwerer sichtbar. Kompakte SVGs lösen dieses Problem, wenn sie nicht als Dekoration eingesetzt werden, sondern als fachliche Wegweiser.
Eine gute kompakte Grafik beantwortet nicht jede Detailfrage. Sie zeigt, in welcher Reihenfolge gedacht werden soll. Für das Lab bedeutet das: Ein Diagramm darf klein sein, muss aber eine klare Aussage haben.
2. End-to-End-Sicht
Kunden- und Mitarbeiterzugriffe werden nicht direkt auf interne Services geleitet. Die Architektur trennt Einstieg, Authentifizierung, Service-Zugriff und Datenhaltung. Diese Sicht hilft besonders bei Reviews, weil sie zeigt, wo Vertrauen beginnt und wo es wieder geprüft werden muss.
Praxisbezug: In der späteren HTML-Version wird diese Grafik direkt im passenden Abschnitt eingebettet. Sie wird nicht als externer Asset-Ordner ausgelagert und nicht als separater Anhang versteckt.
3. Namespace- und Zonenmodell
Namespaces, Netzwerkzonen und Verantwortlichkeiten werden zusammen betrachtet. Ein Namespace ist kein Ersatz für eine Firewall, aber ein wichtiger Container für Berechtigungen, Quotas, NetworkPolicies und Betriebszuordnung.
Praxisbezug: In der späteren HTML-Version wird diese Grafik direkt im passenden Abschnitt eingebettet. Sie wird nicht als externer Asset-Ordner ausgelagert und nicht als separater Anhang versteckt.
4. Datenfluss mit Outbox
Der Order Service speichert Bestellung und Outbox-Ereignis in einer Transaktion. Erst danach veröffentlicht ein Publisher das Ereignis. Dadurch werden fachliche Änderungen und technische Kommunikation entkoppelt.
Praxisbezug: In der späteren HTML-Version wird diese Grafik direkt im passenden Abschnitt eingebettet. Sie wird nicht als externer Asset-Ordner ausgelagert und nicht als separater Anhang versteckt.
5. Security-Kette
Identity, RBAC, Secrets, NetworkPolicy, Container-Härtung und Audit Logging bilden eine Kette. Schwachstellen entstehen oft dort, wo eines dieser Glieder fehlt oder nur dokumentiert, aber nicht technisch umgesetzt ist.
Praxisbezug: In der späteren HTML-Version wird diese Grafik direkt im passenden Abschnitt eingebettet. Sie wird nicht als externer Asset-Ordner ausgelagert und nicht als separater Anhang versteckt.
6. Betriebskette
Health Checks, strukturierte Logs, Metriken, Traces, Alerts, Dashboards und Runbooks gehören zusammen. Ein Alert ohne Runbook hilft nur begrenzt; ein Runbook ohne Messwerte bleibt theoretisch.
Praxisbezug: In der späteren HTML-Version wird diese Grafik direkt im passenden Abschnitt eingebettet. Sie wird nicht als externer Asset-Ordner ausgelagert und nicht als separater Anhang versteckt.
7. Recovery-Kette
Backup ist nur der erste Schritt. Entscheidend sind Restore-Test, Wiederanlaufreihenfolge, Datenkonsistenz, fachliche Nachprüfung und dokumentierte Entscheidung, ob Rollback oder Rollforward sinnvoller ist.
Praxisbezug: In der späteren HTML-Version wird diese Grafik direkt im passenden Abschnitt eingebettet. Sie wird nicht als externer Asset-Ordner ausgelagert und nicht als separater Anhang versteckt.
8. Glossar-Erweiterung mit Querverweisen
Das Glossar wird nicht als Ersatz für Fachkapitel verwendet. Es dient als Nachschlagewerk, wenn ein Begriff im Text auftaucht und kurz eingeordnet werden soll. Die Begriffe werden mit Projektkontext formuliert, nicht als abstrakte Lexikondefinition.
Architecture Fitness Function
Eine prüfbare Regel, die sicherstellt, dass Architekturentscheidungen nicht nur beschrieben, sondern automatisch oder halbautomatisch kontrolliert werden.
Golden Path
Ein empfohlener Standardweg für Teams, um neue Services mit bewährter Struktur, Pipeline, Security und Observability anzulegen.
Platform Contract
Eine Vereinbarung zwischen Plattformteam und Anwendungsteam, welche Laufzeit-, Sicherheits-, Monitoring- und Deploymentregeln gelten.
Operational Readiness
Nachweis, dass ein Service nicht nur entwickelt, sondern auch betrieben, überwacht, gesichert und wiederhergestellt werden kann.
Blast Radius
Der mögliche Schadensbereich eines Fehlers oder Angriffs. Gute Architektur begrenzt diesen Bereich durch Zonen, Rechte und Isolation.
Control Plane
Steuerungsebene einer Plattform, zum Beispiel Kubernetes API, Argo CD oder zentrale Identity-Komponenten.
Data Plane
Ebene, auf der echte Anwendungsdaten und Netzwerkpakete fließen, zum Beispiel Service-Traffic, Datenbankzugriffe oder Broker-Nachrichten.
Progressive Delivery
Schrittweise Auslieferung über Canary, Blue-Green oder Feature Flags, damit Risiken beim Release begrenzt werden.
Policy Drift
Abweichung zwischen dokumentierten Regeln und tatsächlich aktiven Policies, zum Beispiel veraltete Firewall-Freigaben oder zu breite RBAC-Rechte.
Runbook Debt
Betriebsschuld, die entsteht, wenn Systeme ohne aktuelle Runbooks produktionsnah genutzt werden.
9. HTML-Regel für diese Erweiterung
Alle neuen SVGs müssen inline bleiben. Die Navigation verweist auf fachliche Namen, nicht auf technische Dateinamen. Die Content-Kategorie bleibt standardmäßig geschlossen, damit die mobile Darstellung nicht überladen wirkt.
10. Übung
Wähle drei der neuen Begriffe aus und ordne sie einem konkreten Artefakt im Lab zu: README, ADR, Kubernetes-Manifest, Pipeline, Monitoring-Dashboard oder Runbook. Begründe kurz, warum dieser Begriff genau dort sichtbar werden muss.
11. Musterlösung
Golden Path gehört in README und Repository-Template, weil neue Teams dadurch denselben Startpunkt erhalten. Operational Readiness gehört in Pull-Request-Checkliste und Release-Abnahme, weil ein Service sonst technisch fertig, aber betrieblich unfertig sein kann. Policy Drift gehört in Security-Review und regelmäßige Prüfung, weil dokumentierte Regeln ohne technische Kontrolle schnell veralten.
Teil J: Großer Fachglossar und Nachschlageindex
Großer Fachglossar und Nachschlageindex
Dieser Glossar wurde neu generiert und ergänzt die konsolidierte Fassung als eigener Referenzteil. Er ist kein Ersatz für die Fachkapitel, sondern ein schneller Nachschlagebereich für Architektur, Infrastruktur, OpenShift, Security, Anwendungen, Daten, Betrieb, Backup, DevOps und AI.
Leseregel: Jeder Begriff enthält Bedeutung im Lab, typischen Fehler und einen konkreten Nachweis. Dadurch bleibt der Glossar praktisch und überprüfbar.
Typischer Fehler: YAML für jede Umgebung kopieren.
Nachweis: base/overlays-Struktur.
Helm
Bedeutung: Templating und Paketierung für Kubernetes.
Typischer Fehler: Helm-Charts ohne nachvollziehbare Werte betreiben.
Nachweis: Chart und values.yaml.
Environment Promotion
Bedeutung: kontrollierter Weg von dev nach test nach prod.
Typischer Fehler: Image in Prod anders bauen als in Test.
Nachweis: Image Tag und Overlay-PR.
Rollback
Bedeutung: Rückkehr auf vorherigen Zustand.
Typischer Fehler: Rollback ohne Datenbankkompatibilität durchführen.
Nachweis: Rollback-Runbook.
Rollforward
Bedeutung: Fehler durch neue korrigierende Version beheben.
Typischer Fehler: bei Datenänderungen blind zurückrollen.
Nachweis: Hotfix-Plan.
Feature Flag
Bedeutung: Funktion getrennt vom Deployment aktivieren.
Typischer Fehler: Flags nie entfernen.
Nachweis: Flag-Inventar.
Release Notes
Bedeutung: Beschreibung der Änderung und Auswirkungen.
Typischer Fehler: Release ohne Betriebs- und Fachhinweise.
Nachweis: CHANGELOG und Release-Dokument.
Codex
Bedeutung: AI-Unterstützung für Code, Tests und konkrete Dateien.
Typischer Fehler: AI-Code ungeprüft übernehmen.
Nachweis: PR-Review und Tests.
Claude Code
Bedeutung: AI-Unterstützung für größere Refactorings und Projektkontext.
Typischer Fehler: AI ohne klare Grenzen auf Repo loslassen.
Nachweis: Arbeitsplan und Diff-Review.
AI-Fülltext
Bedeutung: plausibler, aber austauschbarer Inhalt.
Typischer Fehler: Umfang statt Qualität erzeugen.
Nachweis: Wiederholungsprüfung.
Prompt-Regel
Bedeutung: verbindliche Vorgabe für AI-Ausgaben.
Typischer Fehler: Prompt ohne Qualitätsgrenzen verwenden.
Nachweis: Projektregel und Review.
Diff Review
Bedeutung: Prüfung konkreter Änderungen.
Typischer Fehler: nur Zusammenfassung lesen.
Nachweis: Pull Request Diff.
Anhang K: Build-, Abnahme- und Pflegeprozess
Anhang K: Build-, Abnahme- und Pflegeprozess
Dieser Anhang enthält technische Regeln, Prüfprozesse und Delivery-Hinweise. Er ist bewusst nicht Teil des fachlichen Hauptlernwegs.
Qualitätsprüfung, Konsolidierung und HTML-Vorbereitung
1. Warum dieser Teil notwendig ist
Nachdem die fachlichen Teile 1 bis 15 entstanden sind, beginnt eine andere Art von Arbeit. Jetzt geht es nicht darum, noch mehr Text zu erzeugen. Es geht darum, den vorhandenen Inhalt gegen die Fehler zu schützen, die in den vorherigen HTML-Fassungen sichtbar wurden: wiederholte Absätze, künstliche Tabellen, generische Überschriften, angehängte Praxisblöcke und Navigationseinträge, die nicht fachlich benannt waren.
Dieser Teil ist deshalb kein normales Fachkapitel, sondern eine Qualitätsstufe. Er beschreibt, wie das Lernprojekt vor der HTML-Erzeugung konsolidiert wird. Die spätere Single-File-HTML darf nicht einfach den Markdown-Inhalt blind in eine Oberfläche kopieren. Sie muss die Struktur erhalten, Navigation sauber abbilden, Code lesbar darstellen und dabei verhindern, dass technische Verpackung den Inhalt wieder verschlechtert.
Die wichtigste Regel lautet:
Vorlage / Textauszug
Qualität entsteht nicht durch Dateigröße.
Qualität entsteht durch fachlich unterschiedliche Kapitel, klare Struktur, konkrete Beispiele und prüfbare Artefakte.
Eine HTML-Datei über 2 MB ist nur sinnvoll, wenn sie durch echten Inhalt groß wird: Erklärungen, Szenarien, Code, Runbooks, Übungen, Musterlösungen und Diagramme. Sie ist nicht sinnvoll, wenn sie durch wiederholte Sätze, künstliche Fülltabellen oder leere Referenzkarten wächst.
---
2. Die bisherigen Fehler als Prüfkriterien
Aus den früheren Versuchen ergeben sich klare Negativregeln. Diese Regeln werden vor der HTML-Erzeugung geprüft.
Nicht erlaubt sind Überschriften wie:
Vorlage / Textauszug
Integrierte Vertiefung 3
Praxisdurchlauf 7
Anhang 16
Referenzkarte 22
Entscheidung 2
Risiko 3
Solche Titel sagen nichts über den Inhalt aus. Sie zeigen, dass ein Generator nummerierte Blöcke erzeugt hat, aber kein Fachbuch geschrieben wurde.
Nicht erlaubt sind Absätze, die nur einen Begriff austauschen, aber sonst identisch bleiben. Ein Beispiel für ein schlechtes Muster wäre:
Vorlage / Textauszug
Bei Security beginnt die Arbeit mit einer konkreten Fragestellung.
Der Schwerpunkt RBAC wird dabei mit realen Artefakten verbunden.
...
Bei Security beginnt die Arbeit mit einer konkreten Fragestellung.
Der Schwerpunkt Hardening wird dabei mit realen Artefakten verbunden.
...
Solche Wiederholungen wirken beim ersten Überfliegen vielleicht umfangreich, aber beim Lesen merkt man sofort, dass kein echter Lernwert entsteht.
Nicht erlaubt sind Tabellen, die nur scheinbar fachliche Inhalte tragen:
Skizze / Textauszug
Entscheidung 2 | Warum das wichtig ist | Risiko 2 | Nachweis
Entscheidung 3 | Warum das wichtig ist | Risiko 3 | Nachweis
Eine Tabelle ist nur dann sinnvoll, wenn jede Zeile einen eigenen fachlichen Zweck hat.
---
3. Positivregeln für jedes Kapitel
Jedes Kapitel muss einen eigenen Beitrag leisten. Ein Kapitel gilt nur dann als ausreichend, wenn es mindestens diese Elemente enthält:
Vorlage / Textauszug
Ziel des Kapitels
fachliche Erklärung
Enterprise-Szenario
technische Umsetzung
Code- oder Konfigurationsbeispiel
typischer Fehler
Betriebs- oder Security-Bezug
Übung oder Kontrollfrage
Musterlösung oder Beispielantwort
Nicht jedes Kapitel muss gleich lang sein. Aber jedes Kapitel muss inhaltlich unterscheidbar sein.
Ein Kapitel über NetworkPolicy darf nicht wie ein Kapitel über RBAC klingen. NetworkPolicy behandelt Netzwerkkommunikation zwischen Pods und Namespaces. RBAC behandelt Benutzer, Gruppen, Rollen und Berechtigungen auf API-Ebene. Beide gehören zu Security, aber sie lösen völlig verschiedene Probleme.
Ein Kapitel über Backup darf nicht wie ein Kapitel über Monitoring klingen. Backup beantwortet die Frage, wie Daten wiederhergestellt werden. Monitoring beantwortet die Frage, wie Probleme sichtbar werden. Beide gehören zum Betrieb, aber ihre Artefakte, Fehlerbilder und Prüfmethoden sind unterschiedlich.
---
4. Konsolidierungsmodell
Die vorhandenen Markdown-Dateien werden nicht als lose Sammlung behandelt. Sie werden zu einem Buch zusammengeführt.
Die Konsolidierung folgt dieser Reihenfolge:
Vorlage / Textauszug
Dateien sortieren
Kapitelüberschriften normalisieren
doppelte oder ähnliche Absätze erkennen
generische Titel entfernen
Praxisabschnitte in Fachkapitel integrieren
Begriffserklärungen im Kontext belassen
Codeblöcke mit Sprache kennzeichnen
Mermaid-Diagramme oder SVG-Platzhalter markieren
interne Links vorbereiten
HTML-Struktur erzeugen
Wichtig ist: Konsolidierung bedeutet nicht Kürzung um jeden Preis. Manche Wiederholungen sind pädagogisch sinnvoll, wenn sie an anderer Stelle mit neuer Bedeutung auftreten. Ein Begriff wie GitOps darf in mehreren Kapiteln vorkommen, aber nicht mit demselben Absatz. In Teil 5 wird GitOps aus OpenShift-Sicht erklärt. In Teil 11 wird GitOps aus Release-Management-Sicht erklärt. Das ist erlaubt.
---
5. Qualitätsprüfung gegen Wiederholungen
Eine einfache Wiederholungsprüfung kann nach Satzähnlichkeit suchen. Dabei werden Absätze normalisiert: Groß-/Kleinschreibung, Sonderzeichen und einzelne Fachbegriffe werden reduziert. Danach wird geprüft, ob mehrere Absätze fast identisch sind.
Ein mögliches Prüfschema:
python
from pathlib import Path
from difflib import SequenceMatcher
root = Path(class="str">"mhepl_md_steps")
paragraphs = []
for file in sorted(root.glob(class="str">"*.md")):
text = file.read_text(encoding=class="str">"utf-8")
for block in text.split(class="str">"\n\n"):
normalized = class="str">" ".join(block.lower().split())
if len(normalized) > 240:
paragraphs.append((file.name, normalized, block))
for i, left in enumerate(paragraphs):
for right in paragraphs[i + 1:]:
score = SequenceMatcher(None, left[1], right[1]).ratio()
if score > 0.92:
print(class="str">"Ähnlicher Absatz:", score)
print(left[0])
print(right[0])
print()
Diese Prüfung ist nicht perfekt. Sie erkennt nicht jede Wiederholung und kann manchmal legitime Ähnlichkeit melden. Aber sie verhindert, dass große Mengen nahezu gleicher Absätze unbemerkt in die HTML-Datei gelangen.
Zusätzlich kann man verbotene Muster direkt suchen:
python
forbidden = [
class="str">"integrierte vertiefung",
class="str">"praxisdurchlauf",
class="str">"anhang 16",
class="str">"entscheidung 2",
class="str">"entscheidung 3",
class="str">"risiko 2",
class="str">"risiko 3",
class="str">"warum das im lab wichtig ist",
]
for file in sorted(root.glob(class="str">"*.md")):
text = file.read_text(encoding=class="str">"utf-8").lower()
for pattern in forbidden:
if pattern in text:
print(fclass="str">"Verbotenes Muster gefunden: {pattern} in {file.name}")
Diese Prüfung wird vor jeder finalen HTML-Erzeugung ausgeführt.
---
6. Umgang mit Tabellen
Tabellen sind nicht verboten. Aber Tabellen dürfen nicht das Buch ersetzen.
Eine gute Tabelle fasst eine fachliche Entscheidung knapp zusammen:
Skizze / Textauszug
| Workload | Geeignete Plattform | Begründung |
|---|---|---|
| Order Service | OpenShift | moderner Service, skalierbar, GitOps-fähig |
| große PostgreSQL-Instanz | Bare Metal oder Managed DB | hoher I/O-Bedarf, klare Backup-Strategie |
| Legacy Reporting | VM | bestehende Treiber und Betriebsvorgaben |
Tabellen sind erlaubt, wenn sie eine echte Übersicht liefern.
Tabellen sind nicht erlaubt, wenn sie nur Platz füllen.
Im Zweifel wird eine Tabelle in Fließtext umgewandelt. Fließtext zwingt stärker dazu, Zusammenhänge zu erklären.
---
7. Umgang mit Glossar und Begriffen
Ein separates Glossar kann hilfreich sein. In diesem Projekt soll es aber nicht der Hauptinhalt sein. Begriffe werden zuerst im Kontext erklärt.
Beispiel:
Vorlage / Textauszug
Ein ServiceMonitor ist eine Custom Resource, mit der Prometheus Operator erkennt, welche Services Metriken liefern. Im Order Service wird der ServiceMonitor verwendet, damit Prometheus den Actuator-Endpunkt /actuator/prometheus regelmäßig abfragt.
Das ist besser als:
Vorlage / Textauszug
ServiceMonitor: Kubernetes-Ressource für Monitoring.
Der kurze Glossarstil ist nur als Index erlaubt. Die Erklärung muss im Fachkapitel stehen.
---
8. Struktur der späteren HTML-Datei
Die spätere HTML-Datei soll weiterhin eine einzige Datei sein. Sie darf keine externen Bibliotheken, keine CDN-Links und keine separaten Assets benötigen.
Content-Kategorien sollen ebenfalls klappbar sein und standardmäßig geschlossen:
html
<details class=class="str">"content-section" id=class="str">"teil-5-kubernetes-und-openshift">
<summary>Teil 5: Kubernetes und OpenShift</summary>
<section>
<h2>Warum Kubernetes nicht nur Deployment ist</h2>
<p>...</p>
</section>
</details>
Der Vorteil: Auch ohne JavaScript funktioniert das Öffnen und Schließen.
---
9. Navigation ohne kaputte Logik
Die Navigation darf nicht von komplexem JavaScript abhängen. In früheren Fassungen war genau das ein Problem: Buttons, dynamische DOM-Änderungen und verschachtelte Steuerungen konnten auf mobilen Geräten oder lokalen HTML-Dateien unzuverlässig funktionieren.
Die neue Regel lautet:
Vorlage / Textauszug
Navigation muss mit HTML allein funktionieren.
JavaScript darf nur Zusatzkomfort liefern.
Zusatzkomfort kann sein:
javascript
document.querySelectorAll(class="str">'a[href^="#"]').forEach(link => {
link.addEventListener(class="str">'click', () => {
const id = link.getAttribute(class="str">'href').slice(1);
const target = document.getElementById(id);
if (!target) return;
const parentDetails = target.closest(class="str">'details');
if (parentDetails) parentDetails.open = true;
});
});
Wenn dieses JavaScript nicht läuft, bleiben die Links trotzdem normale Ankerlinks. Das ist der entscheidende Unterschied.
---
10. Codeblöcke und Syntax-Hervorhebung
Die Codeblöcke sollen farbig und lesbar sein, aber ohne externe Highlighting-Bibliothek. Das bedeutet: Die HTML-Erzeugung muss Code in einfache Klassen einteilen oder wenigstens unterschiedliche Sprachen sauber kennzeichnen.
Für manuelle Syntax-Hervorhebung können Klassen wie kw, str, num, comment, anno, tag, key verwendet werden. Wichtig ist aber: Die Farbe darf nicht wichtiger werden als Lesbarkeit.
---
11. Diagramme und SVGs
Die spätere HTML-Datei soll Diagramme enthalten, aber ohne externe Bilder. Es gibt zwei robuste Möglichkeiten.
Erstens: Inline-SVG. Das ist ideal für Architekturdiagramme, weil die Grafik direkt in der HTML-Datei steckt.
Zweitens: Mermaid-Code als sichtbarer Codeblock. Ohne externe Mermaid-Bibliothek wird daraus kein automatisch gerendertes Diagramm, aber der Leser sieht die Struktur. Für eine echte Offline-Single-File ohne externe Bibliotheken ist Inline-SVG zuverlässiger.
Die Regel lautet:
Vorlage / Textauszug
Wichtige Diagramme werden als Inline-SVG dargestellt.
Mermaid darf ergänzend als lesbares Architekturmodell enthalten sein.
Für die finale HTML-Version sollten mindestens diese SVGs entstehen:
Vorlage / Textauszug
Gesamtarchitektur
Netzwerkzonen und DMZ
OpenShift-Zielplattform
Identity-Flow mit Keycloak und LDAP
Outbox- und Messaging-Flow
Observability-Flow
Backup- und Disaster-Recovery-Flow
GitOps-Release-Flow
VM-zu-OpenShift-Migrationspfad
AI-Unterstützung im Entwicklungsprozess
---
12. HTML-Größe über 2 MB ohne Fülltext
Die Anforderung „HTML über 2 MB“ bleibt bestehen. Aber die Größe darf nicht durch Fülltext entstehen.
Legitime Quellen für Größe sind:
Vorlage / Textauszug
ausführlicher Fließtext
viele echte Codebeispiele
Runbooks
Übungen und Musterlösungen
Inline-SVGs
CSS für modernes Layout
fachliche Navigation
eingebettete Prüflisten
Nicht legitime Quellen sind:
Vorlage / Textauszug
wiederholte Absätze
künstliche Referenzkarten
nummerierte Fülltabellen
zufällige Glossarlisten
lange Lorem-Ipsum-ähnliche Texte
Wenn die HTML-Datei unter 2 MB bleibt, wird nicht einfach Text dupliziert. Stattdessen werden fehlende echte Inhalte ergänzt, zum Beispiel zusätzliche Runbooks, konkrete Codebeispiele oder bessere Diagramme.
---
13. Prüfbericht vor finaler Ausgabe
Jede finale Ausgabe soll einen kurzen Prüfbericht enthalten.
Beispiel:
Vorlage / Textauszug
Prüfbericht:
ZIP fehlerfrei: ja
HTML über 2 MB: ja
externe Assets: nein
CDN-Links: nein
Navigation nativ klappbar: ja
Content-Kategorien standardmäßig geschlossen: ja
verbotene Titel gefunden: nein
künstliche Tabellenmuster gefunden: nein
auffällige Absatzwiederholungen: keine kritischen
Codeblöcke vorhanden: ja
Inline-SVGs vorhanden: ja
Dieser Prüfbericht ersetzt nicht das Lesen, aber er verhindert offensichtliche technische Fehler.
---
14. Konsolidierter Master-Index
Für die spätere HTML-Version wird ein Master-Index vorbereitet.
Vorlage / Textauszug
Teil 1: Unternehmenskontext und Zielbild
Teil 2: Infrastruktur-Fundament
Teil 3: Cloud-Architektur
Teil 4: VM- und Bare-Metal-Betrieb
Teil 5: Kubernetes- und OpenShift-Plattform
Teil 6: Identity, Security und Governance
Teil 7: Moderne Anwendungen
Teil 8: Daten, Messaging und Integration
Teil 9: Observability und Betrieb
Teil 10: Backup, Restore und Disaster Recovery
Teil 11: DevOps, GitOps und Release Management
Teil 12: Codex und Claude Code im Enterprise-Projekt
Teil 13: Komplettes Beispielprojekt
Teil 14: Übungen, Runbooks und Musterlösungen
Teil 15: Integrierte Begriffserklärungen und Fachindex
Teil 16: Qualitätsprüfung, Konsolidierung und HTML-Vorbereitung
Dieser Index darf in der HTML-Navigation erscheinen. Er ist fachlich benannt und enthält keine künstlichen Seriennamen.
---
15. Übung: Qualitätsprüfung planen
Erstelle für dein eigenes Lernprojekt eine Qualitätsprüfung mit mindestens zehn Regeln.
Die Regeln sollen prüfen:
Vorlage / Textauszug
verbotene Titel
wiederholte Absätze
Tabellenanteil
Codeblock-Anzahl
Diagramm-Anzahl
externe Assets
Navigation
mobile Nutzbarkeit
Fachlichkeit der Überschriften
ZIP-Inhalt
Beschreibe zusätzlich, welche Fehler automatisch geprüft werden können und welche Fehler ein Mensch lesen muss.
---
16. Musterlösung zur Übung
Eine mögliche Qualitätsprüfung lautet:
Vorlage / Textauszug
Suche nach „integrierte Vertiefung“, „Praxisdurchlauf“, „Anhang 16“ und ähnlichen generischen Titeln.
Vergleiche lange Absätze mit Ähnlichkeitswerten über 0,92.
Zähle Tabellen und prüfe, ob sie mehr als 20 Prozent des Inhalts ausmachen.
Zähle Codeblöcke und prüfe, ob wichtige Kapitel technische Beispiele enthalten.
Prüfe, ob mindestens acht Inline-SVGs enthalten sind.
Suche nach http://, https://, cdn, script src und link rel stylesheet.
Prüfe, ob Navigation mit details/summary umgesetzt ist.
Prüfe, ob Content-Kategorien standardmäßig geschlossen sind.
Suche nach Überschriften mit reinen Nummern oder Platzhaltern.
Öffne das ZIP testweise und prüfe, ob README, Markdown und HTML enthalten sind.
Automatisch prüfbar sind Muster, Dateigrößen, ZIP-Struktur, Links, verbotene Wörter und Codeblock-Anzahlen. Menschlich geprüft werden müssen fachliche Tiefe, Verständlichkeit, didaktischer Aufbau und die Frage, ob ein Kapitel wirklich einen eigenen Lernwert hat.
---
17. Merksätze
Vorlage / Textauszug
Eine große HTML-Datei ist nur dann wertvoll, wenn sie aus echtem Inhalt besteht.
Native HTML-Navigation ist robuster als komplexe lokale JavaScript-Logik.
Tabellen und Glossar dürfen unterstützen, aber nicht das Fachbuch ersetzen.
Praxis gehört in das passende Fachkapitel, nicht in angehängte Serienblöcke.
Qualitätsprüfung ist kein Nachtrag, sondern Teil der Erzeugung.
Wenn ein Generator denselben Absatz mehrfach ausgibt, muss der Prozess geändert werden, nicht nur der Absatz repariert.
Finale Markdown-Konsolidierung und Masterbuch-Aufbau
1. Ziel dieses Teils
Nach den ersten sechzehn Teilen liegt das Projekt nicht mehr als lose Chat-Ausgabe vor, sondern als wachsendes Markdown-Buch. Dieser Teil beschreibt, wie daraus ein sauberes Masterbuch entsteht. Der Schwerpunkt liegt nicht auf neuer Technik, sondern auf Ordnung, Lesbarkeit, Konsistenz und Wiederverwendbarkeit.
Das Ziel ist eine konsolidierte Markdown-Fassung, die später ohne Qualitätsverlust in HTML, PDF oder ein Repository-Paket umgewandelt werden kann. Dabei darf kein Inhalt künstlich aufgeblasen werden. Wiederholungen, generische Platzhalter und angehängte Erweiterungsblöcke müssen vor der HTML-Erzeugung entfernt oder fachlich integriert werden.
Ein Masterbuch ist mehr als die Summe einzelner Kapitel. Es braucht eine klare Leserführung. Der Leser soll verstehen, warum das Projekt existiert, wie die Infrastruktur aufgebaut ist, wie moderne Anwendungen betrieben werden, wie Security und Observability integriert sind und wie am Ende ein vollständiges Enterprise-Lab entsteht.
---
2. Warum Konsolidierung notwendig ist
Beim schrittweisen Schreiben entstehen häufig kleine Unterschiede im Stil. Ein Kapitel verwendet vielleicht den Begriff OpenShift Route, ein anderes Kapitel spricht von Ingress, ein weiteres erwähnt API Gateway. Alle Begriffe können korrekt sein, aber ohne Konsolidierung wirkt das Buch uneinheitlich.
Auch Codebeispiele können auseinanderlaufen. In einem Kapitel heißt der Namespace order-prod, in einem anderen orders-prod. In einem Abschnitt heißt der Service order-service, in einem anderen orders-api. Solche Kleinigkeiten wirken harmlos, führen aber beim Lernen zu Verwirrung.
Die Konsolidierung hat deshalb drei Aufgaben:
Vorlage / Textauszug
Fachliche Begriffe vereinheitlichen
Technische Namen konsistent machen
Kapitel so verbinden, dass ein zusammenhängendes Lernbuch entsteht
Wichtig ist: Konsolidierung bedeutet nicht, Inhalte zu kürzen, bis nur noch eine Zusammenfassung übrig bleibt. Konsolidierung bedeutet, die vorhandenen Inhalte zu ordnen, Dopplungen zu entfernen und fehlende Übergänge zu ergänzen.
---
3. Zielstruktur des Masterbuchs
Das finale Markdown-Masterbuch soll eine klare Hauptstruktur erhalten:
Vorlage / Textauszug
Modern_Hybrid_Enterprise_Platform_Lab_MASTER.md
Vorwort und Lernziel
Unternehmenskontext und Zielbild
Infrastruktur-Fundament
Cloud-Architektur
VM- und Bare-Metal-Betrieb
Kubernetes- und OpenShift-Plattform
Identity, Security und Governance
Moderne Anwendungen
Daten, Messaging und Integration
Observability und Betrieb
Backup, Restore und Disaster Recovery
DevOps, GitOps und Release Management
Codex und Claude Code im Enterprise-Projekt
Komplettes Beispielprojekt
Übungen, Runbooks und Musterlösungen
Integrierte Begriffserklärungen und Fachindex
Qualitätsprüfung und HTML-Vorbereitung
Konsolidierte Abschlussstruktur
Die Dateiteile bleiben zusätzlich erhalten. Das Masterbuch ist also nicht der Ersatz für die Einzeldateien, sondern die zusammengeführte Lesefassung.
---
4. Regeln für den Masterbuch-Aufbau
Die Zusammenführung muss nach festen Regeln erfolgen. Sonst entstehen wieder die alten Probleme: Anhänge ohne Kontext, generische Überschriften, wiederholte Absätze oder künstliche Tabellen.
Regel 1: Keine künstlichen Serientitel
Nicht erlaubt:
Vorlage / Textauszug
Praxisdurchlauf 1
Praxisdurchlauf 2
Integrierte Vertiefung 3
Anhang 16
Referenzkarte 7
Erlaubt:
Vorlage / Textauszug
Outbox-Backlog im Betrieb analysieren
Keycloak-Rollenmodell für Admin Portal umsetzen
OpenShift Deployment mit Readiness und Resource Limits absichern
PostgreSQL-Restore fachlich validieren
Der Titel muss sagen, worum es fachlich geht.
Regel 2: Praxis direkt integrieren
Praxisabschnitte werden nicht an das Ende eines Kapitels geklebt. Sie stehen dort, wo der Leser sie braucht.
Beispiel: Das Runbook für einen Outbox-Backlog gehört in den Bereich Daten, Messaging und Integration oder in das Beispielprojekt. Es gehört nicht in einen losen Anhang mit dem Titel Praxisdurchlauf.
Regel 3: Begriffe im Kontext erklären
Ein Begriff wie NetworkPolicy wird dort erklärt, wo er eingesetzt wird: im Kubernetes/OpenShift-Kapitel und später im Security-Kontext. Der Fachindex darf auf den Begriff verweisen, aber er ersetzt nicht die Erklärung im Kapitel.
Regel 4: Tabellen nur als Werkzeug
Tabellen dürfen Entscheidungen zusammenfassen, aber sie dürfen nicht der Hauptinhalt sein. Ein Kapitel muss zuerst erklären, warum ein Thema wichtig ist, wie es funktioniert und wie es im Lab angewendet wird. Erst danach kann eine Tabelle helfen.
Regel 5: Code muss erklärend eingebettet sein
Ein Codeblock ohne Erklärung ist wenig wert. Jeder größere Codeblock braucht:
Vorlage / Textauszug
Zweck
Kontext
wichtige Stellen
typische Fehler
Bezug zum Lab
---
5. Konsistenzregeln für Namen
Für das gesamte Buch gelten feste Namen. Diese Namen werden in allen Kapiteln gleich verwendet.
Vorlage / Textauszug
Unternehmen: Alpine Retail & Services Group
Plattform: Enterprise Platform Lab
Kernservice: order-service
Abrechnungsservice: billing-service
Frontend: customer-portal
Internes Frontend: admin-portal
Reporting: reporting-service
Dateiverarbeitung: file-processing-service
Namespace Produktion Order: order-prod
Namespace Produktion Billing: billing-prod
Namespace GitOps: platform-gitops
Identity Provider: Keycloak
Verzeichnisdienst: LDAP / Active Directory
Broker: Kafka oder RabbitMQ
Datenbank: PostgreSQL
Object Storage: S3-kompatibel oder MinIO
Diese Namen wirken vielleicht klein, aber sie verhindern sehr viele spätere Inkonsistenzen. Wenn die HTML-Datei später eine Sidebar und Ankerlinks bekommt, sind konsistente Namen besonders wichtig.
---
6. Konsistenzregeln für technische Beispiele
Alle Java-Beispiele verwenden die Paketstruktur:
Vorlage / Textauszug
com.seb4u.demo.spring
com.seb4u.demo.quarkus
com.seb4u.demo.micronaut
Für den Hauptpfad wird Spring Boot verwendet, weil es im Enterprise-Umfeld breit eingesetzt wird und sich gut für ausführliche Beispiele eignet. Quarkus und Micronaut werden ergänzend betrachtet, aber nicht in jedem Kapitel parallel wiederholt.
Alle Kubernetes- und OpenShift-Beispiele verwenden:
Vorlage / Textauszug
apiVersion: apps/v1
kind: Deployment
metadata.name: order-service
namespace: order-prod
Alle CI/CD-Beispiele verwenden nachvollziehbare Schritte:
Vorlage / Textauszug
checkout
setup java
build
test
container image build
security scan
push image
update gitops repo
---
7. Master-README
Neben dem Masterbuch braucht das ZIP eine README. Diese README ist nicht der Inhalt des Lernbuchs, sondern eine Bedienungsanleitung für die Dateien.
Eine gute README enthält:
Vorlage / Textauszug
Enterprise Platform Lab
Dieses Paket enthält die Markdown-Schritte des Lernbuchs.
Inhalt
Einzelkapitel als Markdown-Dateien
README zur Orientierung
später: konsolidiertes Master-Markdown
später: Single-File-HTML
Lesereihenfolge
Beginne mit Teil 1 und arbeite dich chronologisch bis zum letzten Teil vor.
Qualitätsregeln
Diese Fassung vermeidet künstliche Generator-Wiederholungen. Praxis, Begriffe und Beispiele werden in den jeweiligen Fachkapiteln integriert.
Nächste Ausbaustufe
Nach der Markdown-Konsolidierung wird eine Single-File-HTML mit klappbarer Navigation, inline SVGs und farbigen Codeblöcken erzeugt.
---
8. Vorbereitung einer konsolidierten Markdown-Datei
Die finale Master-Markdown-Datei kann automatisiert aus den Einzeldateien erzeugt werden. Dabei sollte aber nicht blind alles aneinandergehängt werden. Es braucht einen Vorspann, ein Inhaltsverzeichnis und klare Übergänge.
Beispielskript:
python
from pathlib import Path
source_dir = Path(class="str">"mhepl_md_steps")
output_file = source_dir / class="str">"Modern_Hybrid_Enterprise_Platform_Lab_MASTER.md"
parts = sorted(source_dir.glob(class="str">"[0-9][0-9]_Teil_*.md"))
header = class="str">""class="str">"# Enterprise Platform Lab\n\n"
header += class="str">"## Konsolidiertes Masterbuch\n\n"
header += class="str">"Dieses Dokument fasst alle fachlich geschriebenen Teile des Lernbuchs zusammen.\n\n"
with output_file.open(class="str">"w", encoding=class="str">"utf-8") as out:
out.write(header)
out.write(class="str">"## Inhaltsverzeichnis\n\n")
for part in parts:
title = part.stem.replace(class="str">"_", class="str">" ")
out.write(fclass="str">"- {title}\n")
out.write(class="str">"\n---\n\n")
for part in parts:
out.write(part.read_text(encoding=class="str">"utf-8"))
out.write(class="str">"\n\n---\n\n")
Dieses Skript ist bewusst einfach. In einer späteren Stufe kann es erweitert werden, um automatisch Anker, HTML-IDs, Codeblock-Klassen und Kapitelnummern zu erzeugen.
---
9. Qualitätsprüfung vor der HTML-Erzeugung
Vor der HTML-Erzeugung wird die Markdown-Basis geprüft. Die Prüfung sucht nicht nur technische Fehler, sondern auch typische Qualitätsprobleme.
Gesucht werden:
Vorlage / Textauszug
Praxisdurchlauf
integrierte Vertiefung
Anhang 16
Entscheidung 2
Risiko 2
Warum das im Lab wichtig ist: klare Nachvollziehbarkeit
Bei Security, Hardening und Audit beginnt die Arbeit
Wenn solche Muster auftauchen, wird nicht versucht, sie kosmetisch umzubenennen. Der betroffene Abschnitt muss fachlich neu geschrieben werden.
Beispielprüfung:
python
from pathlib import Path
forbidden = [
class="str">"Praxisdurchlauf",
class="str">"integrierte Vertiefung",
class="str">"Anhang 16",
class="str">"Entscheidung 2",
class="str">"Risiko 2",
class="str">"Warum das im Lab wichtig ist: klare Nachvollziehbarkeit",
class="str">"Bei Security, Hardening und Audit beginnt die Arbeit",
]
for path in Path(class="str">"mhepl_md_steps").glob(class="str">"*.md"):
text = path.read_text(encoding=class="str">"utf-8")
for pattern in forbidden:
if pattern in text:
print(fclass="str">"FEHLER: {pattern} in {path.name}")
Diese Prüfung ist keine perfekte Qualitätskontrolle, aber sie verhindert die bekannten Fehler aus den früheren Versionen.
---
10. Inhaltliche Übergänge zwischen den Teilen
Ein Masterbuch braucht Übergänge. Ohne Übergänge wirkt es wie eine Sammlung einzelner Notizen.
Beispielübergang von Infrastruktur zu Cloud:
Vorlage / Textauszug
Nachdem die lokalen Infrastrukturzonen verstanden sind, erweitert das nächste Kapitel diese Sicht in Richtung Cloud. Die Cloud ersetzt die lokale Infrastruktur nicht vollständig, sondern ergänzt sie um flexible Dienste wie Object Storage, temporäre Umgebungen und optional Managed Databases.
Beispielübergang von OpenShift zu Security:
Vorlage / Textauszug
Nachdem Namespaces, Deployments, Routes und NetworkPolicies eingeführt wurden, stellt sich die nächste Frage: Wer darf diese Ressourcen sehen, ändern und betreiben? Damit beginnt der Übergang von Plattformtechnik zu Identity, Security und Governance.
Solche Übergänge helfen dem Leser, den roten Faden zu behalten.
---
11. Vorbereitung der späteren HTML-Struktur
Die HTML-Datei soll aus der konsolidierten Markdown-Basis entstehen. Sie bekommt keine externen Assets. Alles muss in einer Datei funktionieren.
Wichtige Regel: Die Datei muss auch ohne JavaScript lesbar bleiben. JavaScript darf nur Komfort liefern, zum Beispiel Suche oder automatisches Öffnen eines Zielabschnitts.
---
12. Warum das Masterbuch vor HTML kommt
HTML zu früh zu erzeugen war einer der Hauptfehler der früheren Fassungen. Wenn der Inhalt schwach ist, macht eine schöne HTML-Oberfläche ihn nicht besser. Navigation, Farben und Codeblöcke können nur helfen, wenn der Text fachlich gut ist.
Die Reihenfolge ist deshalb:
Vorlage / Textauszug
Fachlich gutes Markdown
Konsolidiertes Master-Markdown
Qualitätsprüfung
HTML-Erzeugung
ZIP mit HTML, Markdown und README
Nicht:
Vorlage / Textauszug
Große HTML-Datei erzwingen
Inhalt künstlich auffüllen
Fehler nachträglich reparieren
Diese neue Reihenfolge verhindert, dass wieder eine 2-MB-Datei entsteht, die zwar groß ist, aber inhaltlich schwach wirkt.
---
13. Übung: Konsolidierungsprüfung durchführen
Prüfe ein Kapitel deiner Wahl mit folgenden Fragen:
Vorlage / Textauszug
Gibt es generische Überschriften?
Wiederholt sich ein Absatz fast identisch?
Gibt es Tabellen, die nur Inhalt vortäuschen?
Sind Codeblöcke erklärt?
Gibt es einen fachlichen Übergang zum nächsten Kapitel?
Sind Begriffe im Kontext erklärt?
Ist klar, welchen Nutzen das Kapitel im Lab hat?
Schreibe danach drei konkrete Verbesserungen auf.
---
14. Musterlösung zur Übung
Beispielprüfung für ein Security-Kapitel:
Vorlage / Textauszug
Problem 1:
Der Abschnitt erklärt RBAC, erwähnt aber nicht den Unterschied zwischen Kubernetes RBAC und fachlichen Rollen im Admin Portal.
Verbesserung:
Einen eigenen Abschnitt ergänzen, der Kubernetes RoleBinding, Keycloak Realm Roles und Spring Security Authorities sauber trennt.
Problem 2:
Ein Codeblock zeigt eine RoleBinding, aber erklärt nicht, warum diese Berechtigung notwendig ist.
Verbesserung:
Vor dem YAML erklären, welche Person oder Pipeline diese Rechte benötigt und warum keine ClusterRole verwendet wird.
Problem 3:
Das Kapitel endet abrupt.
Verbesserung:
Übergang zu Policy as Code ergänzen, weil Governance nicht nur aus Rollen besteht, sondern auch aus überprüfbaren Regeln.
Diese Musterlösung zeigt: Qualitätsprüfung bedeutet nicht nur Rechtschreibung oder Format. Es geht um fachliche Klarheit.
---
15. Merksätze
Vorlage / Textauszug
Ein Masterbuch entsteht nicht durch Aneinanderkleben, sondern durch Konsolidierung.
Konsistente Namen sind ein Qualitätsmerkmal.
HTML darf erst entstehen, wenn die Markdown-Basis fachlich tragfähig ist.
Praxis gehört in das passende Fachkapitel, nicht in künstliche Anhänge.
Ein Begriff ist erst verstanden, wenn er im Projektkontext erklärt wird.
Große Dateien sind nur dann wertvoll, wenn der Inhalt fachlich unterschiedlich und nützlich ist.
Finale HTML-Erzeugung aus dem geprüften Markdown-Material
1. Ziel dieses Teils
Nachdem die fachlichen Teile als Markdown-Schritte aufgebaut wurden, darf die HTML-Erzeugung nicht wieder ein eigener Generator werden, der Inhalte künstlich verlängert. Die HTML-Datei soll das vorhandene Markdown-Material sauber darstellen. Sie ist also nicht der Ort, an dem neue Fülltexte entstehen, sondern der Ausgabecontainer für das bereits geschriebene Fachbuch.
Das Ziel lautet:
Vorlage / Textauszug
Markdown ist die Quelle.
HTML ist die lesbare Ausgabe.
ZIP ist das saubere Übergabeformat.
Damit bleibt nachvollziehbar, was fachlicher Inhalt ist und was nur Darstellung ist. Wenn später ein Kapitel verbessert wird, wird zuerst Markdown angepasst. Danach wird HTML neu gebaut. So entsteht kein Durcheinander aus reparierten HTML-Dateien, halben Versionen und unsichtbaren Altlasten.
---
2. Warum die HTML-Erzeugung gefährlich werden kann
Die bisherigen fehlerhaften Fassungen hatten ein typisches Problem: Die HTML sollte groß wirken. Dadurch wurden generische Textmuster, wiederholte Tabellen, künstliche Praxisdurchläufe oder nummerierte Anhänge erzeugt. Das Ergebnis sah umfangreich aus, war aber fachlich schwach.
Eine gute HTML-Erzeugung macht genau das Gegenteil. Sie bewahrt den Inhalt, verändert aber nicht seine fachliche Aussage. Sie ergänzt nur Struktur, Navigation, Lesbarkeit, Code-Darstellung und mobile Nutzbarkeit.
Nicht erlaubt sind deshalb:
Vorlage / Textauszug
zusätzliche Platzhalterkapitel
automatisch erzeugte Wiederholungsabsätze
künstliche Tabellen zum Aufblasen
generische Überschriften wie Praxisdurchlauf 7
generische Überschriften wie integrierte Vertiefung 4
Navigationseinträge wie Anhang 16
Glossarlisten als Ersatz für echte Kapitel
Erlaubt sind:
Vorlage / Textauszug
saubere Kapitelstruktur
klappbare Navigation
klappbare Content-Kategorien
farbige Codeblöcke
responsive Layouts
inline SVG-Diagramme
Suchfunktion als Komfort
Druck-/PDF-taugliche Struktur
Der Unterschied ist wichtig: Darstellung darf verbessert werden, Inhalt darf nicht künstlich ersetzt werden.
---
3. Zielstruktur der finalen HTML-Datei
Die finale HTML-Datei soll als Single-File funktionieren. Das bedeutet: CSS, JavaScript und SVGs werden direkt eingebettet. Es gibt keine externen CDN-Abhängigkeiten und keine fehlenden Asset-Ordner.
Die Struktur sieht so aus:
Skizze / Textauszug
lab.html
├── HTML Head
│ ├── Meta Charset
│ ├── Viewport
│ ├── Titel
│ └── Inline CSS
├── Body
│ ├── Kopfbereich
│ ├── Layout Container
│ │ ├── Sidebar Navigation
│ │ └── Main Content
│ ├── Inline SVGs
│ ├── Codeblöcke
│ └── optionales Komfort-JavaScript
Die Datei muss offline funktionieren. Wenn sie lokal geöffnet wird, soll der Inhalt lesbar bleiben. JavaScript darf Komfort liefern, aber nicht notwendig sein.
---
4. Robuste Navigation
Die Navigation wird mit nativen HTML-Elementen gebaut:
html
<nav class=class="str">"sidebar">
<details>
<summary>Teil 1: Unternehmenskontext und Zielbild</summary>
<a href=class="str">"#teil-1-ziel">Ziel des Teils</a>
<a href=class="str">"#teil-1-unternehmen">Beispielunternehmen</a>
<a href=class="str">"#teil-1-architektur">Zielarchitektur</a>
</details>
</nav>
Der Vorteil von details und summary ist Stabilität. Diese Elemente funktionieren auch ohne eigenes JavaScript. Auf iPhone, iPad, Safari, Chrome und Desktop-Browsern sind sie deutlich robuster als komplizierte Button-Logik mit dynamischem DOM-Umbau.
Die Navigation ist standardmäßig geschlossen. Der Leser öffnet nur den Bereich, den er braucht. Bei sehr großen Lernbüchern ist das angenehmer als eine kilometerlange Seitenleiste.
---
5. Klappbare Content-Kategorien
Auch die Hauptinhalte werden mit details strukturiert. Jede große Kategorie ist standardmäßig geschlossen.
html
<main>
<details class=class="str">"content-section" id=class="str">"teil-5">
<summary>Teil 5: Kubernetes- und OpenShift-Plattform</summary>
<article>
<h2>Warum OpenShift im Enterprise-Lab wichtig ist</h2>
<p>...</p>
</article>
</details>
</main>
Wichtig ist: Der Inhalt ist vorhanden. Er wird nicht per JavaScript nachgeladen. Wenn JavaScript deaktiviert ist, kann der Leser die Bereiche trotzdem öffnen.
Das verhindert genau jene Probleme, die bei lokalen HTML-Dateien auf mobilen Geräten häufig auftreten.
---
6. Suchfunktion nur als Komfort
Eine Suchfunktion ist hilfreich, aber sie darf nicht die einzige Möglichkeit sein, Inhalte zu erreichen. Die HTML-Datei muss auch ohne Suche nutzbar bleiben.
Die eigentliche Nutzbarkeit kommt von der sauberen Navigation und den Ankern.
---
7. Codeblöcke im JetBrains-Dark-Stil
Codeblöcke sind ein Kernbestandteil dieses Projekts. Sie müssen lesbar sein, horizontal scrollen können und auf hellem wie dunklem Hintergrund funktionieren.
Da keine CDN-Bibliothek verwendet wird, wird das Highlighting entweder einfach CSS-basiert umgesetzt oder durch beim Build erzeugte span-Elemente vorbereitet. Wichtig ist nicht perfekte IDE-Genauigkeit, sondern stabile Lesbarkeit.
---
8. Copy-Button ohne Pflichtfunktion
Ein Copy-Button ist nützlich, aber nicht kritisch. Wenn der Button auf einem mobilen Browser nicht funktioniert, muss der Code trotzdem manuell markierbar und kopierbar bleiben.
Wenn JavaScript scheitert, bleibt der Code sichtbar.
---
9. Inline SVG statt externe Bilder
Alle wichtigen Diagramme sollen direkt in die HTML eingebettet werden. Externe Dateien führen bei lokalen HTML-Ausgaben oft zu fehlenden Bildern, besonders wenn ZIPs entpackt, Dateien verschoben oder auf iPhones geöffnet werden.
Ein Inline-SVG sieht beispielsweise so aus:
html
class="str">"
0
0
900
360
" role=
class
="str">"img" aria-label=
class
="str">"Hybrid Enterprise Plattform">
class="str">"
20
" y=
class
="str">"
40
" width=
class
="str">"
180
" height=
class
="str">"
80
" rx=
class
="str">"
14
">
class="str">"
110
" y=
class
="str">"
85
" text-anchor=
class
="str">"middle">Customer Portal
Für die finale HTML sind mehrere Diagrammtypen vorgesehen:
Vorlage / Textauszug
Zielarchitektur
Netzwerkzonen
Cloud/VPC-Struktur
OpenShift Deployment Flow
Event Flow mit Outbox
Observability-Pipeline
Backup/Restore-Fluss
GitOps Release Flow
Die Diagramme sollen nicht dekorativ sein. Sie sollen fachliche Zusammenhänge zeigen.
---
10. Markdown-zu-HTML-Konsolidierung
Die Markdown-Dateien werden in numerischer Reihenfolge gelesen:
Ein einfaches Python-Prüfskript kann typische Wiederholungen finden. Es ersetzt keine fachliche Prüfung, hilft aber gegen offensichtliche Generatorfehler.
python
from pathlib import Path
from collections import Counter
import re
source_dir = Path(class="str">"mhepl_md_steps")
texts = []
for file in sorted(source_dir.glob(class="str">"*.md")):
if file.name == class="str">"README.md":
continue
text = file.read_text(encoding=class="str">"utf-8")
paragraphs = [p.strip() for p in re.split(rclass="str">"\n\s*\n", text) if len(p.strip()) > 120]
texts.extend(paragraphs)
counter = Counter(texts)
repeated = [(p, n) for p, n in counter.items() if n > 1]
if repeated:
print(class="str">"Wiederholte längere Absätze gefunden:")
for paragraph, count in repeated[:20]:
print(class="str">"---")
print(class="str">"Anzahl:", count)
print(paragraph[:500])
else:
print(class="str">"Keine identischen längeren Absätze gefunden.")
Dieses Skript findet identische Absätze. Zusätzlich sollte später eine semantische Prüfung erfolgen, bei der auch fast gleiche Absätze auffallen.
---
12. Prüfskript gegen verbotene Muster
python
from pathlib import Path
forbidden = [
class="str">"integrierte Vertiefung",
class="str">"Praxisdurchlauf",
class="str">"Anhang 16",
class="str">"Entscheidung 2",
class="str">"Entscheidung 3",
class="str">"Risiko 2",
class="str">"Risiko 3",
class="str">"Warum das im Lab wichtig ist: klare Nachvollziehbarkeit",
]
source_dir = Path(class="str">"mhepl_md_steps")
failed = False
for file in sorted(source_dir.glob(class="str">"*.md")):
text = file.read_text(encoding=class="str">"utf-8")
for pattern in forbidden:
if pattern in text:
print(fclass="str">"Verbotenes Muster gefunden: {pattern} in {file.name}")
failed = True
if failed:
raise SystemExit(1)
print(class="str">"Keine verbotenen Muster gefunden.")
Dieses Skript bildet die Erfahrungen aus den fehlerhaften HTML-Versionen ab. Es verhindert, dass dieselben Muster erneut in die finale Ausgabe gelangen.
---
13. HTML-Build-Skizze
Die spätere Build-Logik kann so aussehen:
python
from pathlib import Path
import html
source_dir = Path(class="str">"mhepl_md_steps")
out_dir = Path(class="str">"dist")
out_dir.mkdir(exist_ok=True)
files = [p for p in sorted(source_dir.glob(class="str">"*.md")) if p.name != class="str">"README.md"]
master = []
for file in files:
master.append(fclass="str">"\n\n<!-- SOURCE: {file.name} -->\n\n")
master.append(file.read_text(encoding=class="str">"utf-8"))
master_md = class="str">"\n".join(master)
(out_dir / class="str">"Modern_Hybrid_Enterprise_Platform_Lab_MASTER.md").write_text(master_md, encoding=class="str">"utf-8")
# Danach: Markdown parser, Codeblock-Renderer, Navigation-Builder, SVG-Inline-Blöcke
In der echten Umsetzung wird danach ein Markdown-Parser oder eine eigene kontrollierte Konvertierung verwendet. Wichtig ist, dass der Build reproduzierbar bleibt.
---
14. Mobile Regeln
Die HTML muss auf Desktop und Mobilgeräten lesbar sein. Besonders wichtig ist iPhone/Safari, weil lokale HTML-Dateien dort oft eingeschränkt geöffnet werden.
Dadurch kann die HTML genutzt werden, ohne die Quellen zu verlieren. Gleichzeitig bleiben alle Zwischenstände nachvollziehbar.
---
17. Übung
Erstelle eine kurze Qualitätsdefinition für eine HTML-Ausgabe dieses Projekts.
Sie soll beantworten:
Vorlage / Textauszug
Was darf die HTML-Erzeugung verändern?
Was darf sie nicht verändern?
Welche Funktionen müssen ohne JavaScript funktionieren?
Welche Dateien müssen im ZIP enthalten sein?
Welche Muster müssen verboten werden?
---
18. Musterlösung
Eine mögliche Antwort:
Vorlage / Textauszug
Die HTML-Erzeugung darf Layout, Navigation, Codeblock-Darstellung, Anker, Inhaltsverzeichnis und Inline-Diagramme ergänzen. Sie darf den fachlichen Inhalt nicht durch künstliche Fülltexte erweitern.
Ohne JavaScript müssen Navigation, Content-Kategorien, Lesen der Kapitel und Zugriff auf Codeblöcke funktionieren.
Das ZIP muss die Single-File-HTML, das Master-Markdown, alle einzelnen Markdown-Schritte und eine README enthalten.
Verboten sind generische Muster wie Praxisdurchlauf X, integrierte Vertiefung X, Anhang 16, künstliche Entscheidungstabellen, wiederholte Standardabsätze und Glossarlisten als Ersatz für Fachkapitel.
---
19. Merksätze
Vorlage / Textauszug
Die HTML ist Ausgabe, nicht Inhaltserzeuger.
Markdown bleibt die fachliche Quelle.
Navigation muss robust sein, nicht spektakulär.
JavaScript darf helfen, aber nicht tragen.
Eine große Datei ist nur dann wertvoll, wenn der Inhalt echt ist.
Qualität entsteht vor der HTML-Erzeugung, nicht durch nachträgliches Aufblasen.
Finale Delivery-Struktur, ZIP-Paket und Abnahmeprüfung
1. Warum Delivery ein eigenes Fachkapitel braucht
Ein Lernbuch oder Enterprise-Lab ist nicht fertig, nur weil Inhalte geschrieben wurden. Fertig ist es erst, wenn die Ausgabe reproduzierbar, prüfbar und für den Leser einfach nutzbar ist. Gerade bei großen HTML-, Markdown- und ZIP-Paketen entstehen sonst schnell Probleme: Dateien fehlen, Links zeigen ins Leere, Codeblöcke sind schlecht lesbar, Navigation funktioniert nur auf einem Gerät, Bilder liegen in einem separaten Ordner und werden auf dem iPhone nicht geladen, oder das ZIP enthält alte Zwischenversionen mit Namen wie final_fix_neu_v2.
Delivery bedeutet in diesem Projekt: Aus dem fachlichen Markdown-Material wird ein sauberes, nachvollziehbares Paket. Dieses Paket enthält die Master-Markdown-Datei, die einzelnen Kapiteldateien, eine Single-File-HTML, eine README, optional spätere PDF-Ausgaben und Prüfberichte. Die Struktur muss so einfach sein, dass man sie herunterladen, entpacken und sofort verwenden kann.
Der wichtigste Grundsatz lautet:
Vorlage / Textauszug
Ein Delivery-Paket ist kein Dateiablageplatz.
Es ist das fertige, überprüfte Ergebnis einer Lern- und Projektarbeit.
Deshalb bekommt das Projekt eine klare Delivery-Struktur.
---
2. Zielstruktur des finalen ZIP-Pakets
Das finale ZIP soll keine unübersichtliche Sammlung zufälliger Dateien sein. Es soll klar zeigen, welche Datei wofür gedacht ist.
Diese Struktur trennt die fertigen Ausgaben von den Quellen. Die Markdown-Dateien bleiben nachvollziehbar. Die HTML-Datei ist als Endnutzer-Ausgabe klar erkennbar. Prüfberichte liegen unter checks. Wiederverwendbare Beispiele liegen unter examples.
---
3. Warum keine unklaren Dateinamen erlaubt sind
In früheren Iterationen entstehen bei Reparaturversuchen oft Dateinamen wie:
Vorlage / Textauszug
final.html
final_neu.html
final_fix.html
final_fix_2.html
wirklich_final.html
neu_final_final.html
Solche Namen sind gefährlich. Niemand erkennt später, welche Datei gültig ist. Deshalb nutzt dieses Projekt sprechende Namen.
Die HTML-Datei ist offlinefähig. SVGs, CSS und Codeblock-Stile sind inline eingebettet. Wichtige Navigation basiert auf nativen HTML-Elementen und ist nicht zwingend von JavaScript abhängig.
Die README darf nicht nur Platzhalter enthalten. Sie muss dem Nutzer wirklich helfen.
---
5. CHANGELOG für nachvollziehbare Entwicklung
Ein CHANGELOG dokumentiert, was sich zwischen Versionen geändert hat. Für ein Lernbuch ist das hilfreich, weil später klar ist, wann Inhalte ergänzt, entfernt oder umstrukturiert wurden.
Beispiel:
Vorlage / Textauszug
CHANGELOG
1.0.0
erste vollständige Markdown-Fassung mit Teilen 1 bis 19
Qualitätsregeln gegen Wiederholungen eingeführt
Delivery-Struktur definiert
HTML-Erzeugungsregeln vorbereitet
0.9.0
Teile 1 bis 18 einzeln als Markdown geschrieben
Zwischen-ZIP mit allen Markdown-Dateien erstellt
0.5.0
Neustart nach Entfernung künstlicher Generator-Wiederholungen
Das CHANGELOG ist besonders wichtig, wenn HTML, Markdown und später PDF-Ausgaben parallel entstehen.
---
6. Abnahmeprüfung vor HTML-Erzeugung
Bevor die finale HTML-Datei erzeugt wird, muss das Markdown geprüft werden. Sonst werden Fehler nur schöner verpackt.
Die Abnahmeprüfung beantwortet:
Vorlage / Textauszug
Gibt es künstliche Wiederholungen?
Gibt es generische Titel?
Gibt es leere Kapitel?
Gibt es zu viele Tabellen?
Gibt es Codeblöcke ohne Sprache?
Gibt es defekte interne Links?
Gibt es fehlende Überschriften?
Gibt es Kapitel ohne Praxisbezug?
Gibt es Begriffe ohne Kontext?
Gibt es alte Reparaturreste?
Diese Prüfung ist wichtiger als die optische Gestaltung. Eine schöne HTML-Datei mit schlechtem Inhalt bleibt schlechtes Material.
---
7. Verbotene Muster
Das Projekt verwendet eine Liste verbotener Muster. Diese Liste wird vor jeder finalen Ausgabe geprüft.
Beispiele:
Vorlage / Textauszug
integrierte Vertiefung
Praxisdurchlauf 1
Praxisdurchlauf 2
Praxisdurchlauf 3
Anhang 16
Entscheidung 2
Entscheidung 3
Risiko 2
Risiko 3
Warum das im Lab wichtig ist: klare Nachvollziehbarkeit
Bei Security, Hardening und Audit beginnt die Arbeit
Ein Treffer bedeutet nicht automatisch, dass die Datei falsch ist. Aber jeder Treffer muss geprüft werden. In diesem Projekt sollen solche Muster nicht mehr vorkommen, weil sie auf künstlich erzeugte Inhalte hindeuten.
---
8. Python-Prüfung für verbotene Muster
python
from pathlib import Path
root = Path(class="str">"markdown")
forbidden = [
class="str">"integrierte Vertiefung",
class="str">"Praxisdurchlauf 1",
class="str">"Praxisdurchlauf 2",
class="str">"Praxisdurchlauf 3",
class="str">"Anhang 16",
class="str">"Entscheidung 2",
class="str">"Entscheidung 3",
class="str">"Risiko 2",
class="str">"Risiko 3",
class="str">"Warum das im Lab wichtig ist: klare Nachvollziehbarkeit",
class="str">"Bei Security, Hardening und Audit beginnt die Arbeit",
]
hits = []
for md_file in root.glob(class="str">"*.md"):
text = md_file.read_text(encoding=class="str">"utf-8")
for pattern in forbidden:
if pattern in text:
hits.append((md_file.name, pattern))
if hits:
print(class="str">"Verbotene Muster gefunden:")
for file_name, pattern in hits:
print(fclass="str">"- {file_name}: {pattern}")
raise SystemExit(1)
print(class="str">"Keine verbotenen Muster gefunden.")
Diese Prüfung ist einfach, aber wirkungsvoll. Sie verhindert, dass bekannte Fehler erneut in die finale Ausgabe gelangen.
---
9. Prüfung gegen zu ähnliche Absätze
Eine zweite Prüfung erkennt Absätze, die fast identisch sind. Das ist wichtig, weil Wiederholungen nicht immer über exakt gleiche Wörter entstehen.
Beispiel für problematische Struktur:
Vorlage / Textauszug
Bei X beginnt die Arbeit mit einer konkreten Fragestellung...
Bei Y beginnt die Arbeit mit einer konkreten Fragestellung...
Bei Z beginnt die Arbeit mit einer konkreten Fragestellung...
Eine einfache Heuristik kann Absätze normalisieren und Wiederholungen zählen.
python
import re
from pathlib import Path
from collections import Counter
root = Path(class="str">"markdown")
paragraphs = []
for md_file in root.glob(class="str">"*.md"):
text = md_file.read_text(encoding=class="str">"utf-8")
for paragraph in re.split(rclass="str">"\n\s*\n", text):
clean = paragraph.strip()
if len(clean) < 180:
continue
normalized = re.sub(rclass="str">"\b\d+\b", class="str">"<NUM>", clean.lower())
normalized = re.sub(rclass="str">"[a-z0-9_.+-]+@[a-z0-9_.+-]+", class="str">"<EMAIL>", normalized)
normalized = re.sub(rclass="str">"\s+", class="str">" ", normalized)
paragraphs.append(normalized[:280])
counts = Counter(paragraphs)
for snippet, count in counts.most_common(20):
if count > 1:
print(class="str">"Wiederholung gefunden:", count)
print(snippet)
Diese Prüfung ersetzt kein menschliches Lesen. Sie ist aber ein guter Schutz gegen künstliche Wiederholungen.
---
10. Linkprüfung
In der späteren HTML-Datei müssen interne Links funktionieren. Wenn Navigationseinträge auf IDs zeigen, die nicht existieren, wirkt die Datei kaputt.
Die Linkprüfung kontrolliert:
Vorlage / Textauszug
Jeder Navigationslink zeigt auf eine vorhandene ID.
Jede Kategorie hat eine eindeutige ID.
Jede Überschrift erzeugt einen stabilen Anker.
Es gibt keine doppelten IDs.
Es gibt keine leeren href=class="str">"#"-Links.
Ein einfaches Prüfskript für HTML:
python
from pathlib import Path
import re
html = Path(class="str">"web/Modern_Hybrid_Enterprise_Platform_Lab_SINGLE.html").read_text(encoding=class="str">"utf-8")
ids = set(re.findall(rclass="str">'id="([^"]+)"', html))
hrefs = re.findall(rclass="str">'href="#([^"]+)"', html)
missing = [href for href in hrefs if href not in ids]
duplicate_ids = []
for value in ids:
if html.count(fclass="str">'id="{value}"') > 1:
duplicate_ids.append(value)
if missing:
print(class="str">"Fehlende Ziel-IDs:")
for item in missing:
print(class="str">"-", item)
if duplicate_ids:
print(class="str">"Doppelte IDs:")
for item in duplicate_ids:
print(class="str">"-", item)
if missing or duplicate_ids:
raise SystemExit(1)
print(class="str">"Interne Links sind in Ordnung.")
---
11. Prüfung der Codeblöcke
Codeblöcke müssen lesbar und konsistent sein. In diesem Projekt gilt das JetBrains-Dark-Prinzip: dunkler Hintergrund, klare Kontraste, farbige Syntax, horizontales Scrollen und keine wechselnden zufälligen Designs.
Zu prüfen ist:
Vorlage / Textauszug
Jeder Codeblock hat eine Sprache.
Codeblöcke sind scrollbar.
Copy-Button ist Komfort, aber keine Pflichtfunktion.
Farben sind kontrastreich.
Java, YAML, SQL, HTML, CSS, JavaScript und XML sind unterscheidbar.
Ein Markdown-Codeblock ohne Sprache ist problematisch:
Vorlage / Textauszug
public class Demo {}
Vorlage / Textauszug
Besser:
Vorlage / Textauszug
public class Demo {}
Vorlage / Textauszug
Die Sprache hilft später beim Syntax-Highlighting.
---
12. Abnahme der Single-File-HTML
Die finale HTML-Datei muss offline funktionieren. Deshalb werden keine externen CDN-Bibliotheken verwendet.
Pflichtpunkte:
Vorlage / Textauszug
CSS inline
SVG inline
kein externes JavaScript
keine externen Bilder
keine externen Fonts
Navigation mit details/summary
Content-Kategorien mit details/summary
standardmäßig geschlossen
Codebereiche scrollbar
Tabellen scrollbar, falls Tabellen vorkommen
Suchfunktion optional
Copy-Buttons optional
Wichtig: Die Datei muss auch ohne JavaScript nutzbar sein. JavaScript darf Komfort bieten, aber nicht die Grundlage der Nutzbarkeit sein.
---
13. iPhone- und Safari-Abnahme
Lokale HTML-Dateien auf iPhone/Safari sind besonders empfindlich. Manche JavaScript-Funktionen funktionieren dort unzuverlässig, besonders wenn die Datei aus der Dateien-App, aus Messenger-Apps oder direkt lokal geöffnet wird.
Deshalb gelten folgende Regeln:
Vorlage / Textauszug
Navigation nicht nur per Button-JavaScript öffnen.
Kapitel nicht per JavaScript verstecken.
Lösungen nicht nur per onclick anzeigen.
Dark Mode nicht zwingend per localStorage steuern.
Wichtige Inhalte nicht nachträglich per JavaScript erzeugen.
Native HTML-Elemente sind stabiler:
html
<details>
<summary>Teil 5: Kubernetes und OpenShift</summary>
<p>Inhalt...</p>
</details>
Das ist nicht so spektakulär wie eine komplexe App-Navigation, aber deutlich robuster für ein offlinefähiges Lernbuch.
---
14. Abnahmebericht
Ein Abnahmebericht dokumentiert die wichtigsten Prüfergebnisse.
Vorlage:
Vorlage / Textauszug
Quality Report
Datei
Modern_Hybrid_Enterprise_Platform_Lab_SINGLE.html
Inhalt
Markdown-Teile: 19
Masterbook vorhanden: ja
README vorhanden: ja
HTML vorhanden: ja
Prüfungen
verbotene Muster: bestanden
doppelte Navigations-IDs: bestanden
interne Links: bestanden
Codeblöcke mit Sprache: bestanden
externe Assets: keine gefunden
ZIP-Test: bestanden
Bekannte Grenzen
Suchfunktion ist Komfortfunktion
lokale iPhone-Anzeige hängt teilweise von der App ab, mit der die HTML geöffnet wird
PDF-Ausgabe muss separat geprüft werden
Ein solcher Bericht ist nicht Bürokratie. Er schützt davor, dieselben Fehler wieder einzubauen.
---
15. ZIP-Erzeugung
Das ZIP sollte reproduzierbar erstellt werden. Nicht per Drag-and-drop mit zufälliger Ordnerstruktur, sondern über ein klares Skript.
Beispiel:
python
from pathlib import Path
import zipfile
root = Path(class="str">"Modern_Hybrid_Enterprise_Platform_Lab_DELIVERY")
zip_path = Path(class="str">"Modern_Hybrid_Enterprise_Platform_Lab_v1.0.0_DELIVERY.zip")
with zipfile.ZipFile(zip_path, class="str">"w", compression=zipfile.ZIP_DEFLATED) as zf:
for file in root.rglob(class="str">"*"):
if file.is_file():
zf.write(file, file.relative_to(root.parent))
print(zip_path)
Wenn unzip -t Fehler meldet, darf die Datei nicht ausgeliefert werden.
---
16. Google-Drive-Ablage
Wenn das ZIP nach Google Drive kopiert wird, sollte der Zielordner klar sein. Für dieses Projekt ist ein Ordner wie chatgpt sinnvoll, weil dort die Projektartefakte gesammelt werden.
Wichtig ist:
Vorlage / Textauszug
Dateiname bleibt eindeutig.
Upload wird bestätigt.
Drive-Datei-ID wird dokumentiert.
Falls möglich: Link wird gespeichert.
Lokale Datei bleibt zusätzlich verfügbar.
Ein Upload ohne Bestätigung reicht nicht. Erst wenn Drive eine Datei-ID zurückgibt oder die Datei im Ordner sichtbar ist, gilt der Upload als abgeschlossen.
---
17. Was nicht ins finale ZIP gehört
Nicht ins finale ZIP gehören:
Vorlage / Textauszug
alte Reparaturversionen
kaputte HTML-Prototypen
Generator-Skripte mit Zwischenfehlern
leere Ordner
Testdateien ohne Nutzen
Screenshots von Fehlern
Dateien mit Namen final_fix_2
Falls Skripte mitgeliefert werden, dann nur bewusst und sauber unter einem Ordner wie tools/ oder scripts/.
---
18. Abnahmekriterien für Version 1.0
Version 1.0 ist erreicht, wenn folgende Punkte erfüllt sind:
Vorlage / Textauszug
Alle Hauptteile liegen als Markdown vor.
MASTERBOOK.md ist konsolidiert.
Single-File-HTML ist erzeugt.
Navigation funktioniert mit nativen Details-Elementen.
Content-Kategorien sind standardmäßig geschlossen.
Codeblöcke sind gut lesbar.
SVGs sind inline eingebettet.
Keine externen Assets werden benötigt.
Verbotene Muster sind nicht vorhanden.
Das ZIP ist geprüft.
README erklärt die Nutzung.
Quality Report dokumentiert die Prüfung.
Erst dann sollte das Paket als finale Version bezeichnet werden.
---
19. Übung
Erstelle eine Abnahmecheckliste für das finale Delivery-Paket.
Die Checkliste soll mindestens enthalten:
Vorlage / Textauszug
Dateistruktur
README
Markdown-Dateien
HTML-Datei
Navigation
Codeblöcke
SVGs
externe Assets
verbotene Muster
ZIP-Prüfung
Google-Drive-Ablage
---
20. Musterlösung
Vorlage / Textauszug
Abnahmecheckliste Delivery-Paket
Dateistruktur
[ ] ZIP enthält genau einen klaren Hauptordner
[ ] README.md liegt im Hauptordner
[ ] MASTERBOOK.md liegt im Hauptordner
[ ] einzelne Markdown-Dateien liegen unter md/
[ ] HTML-Datei liegt unter web/
[ ] Prüfberichte liegen unter checks/
Inhalt
[ ] alle Kapitel sind vorhanden
[ ] keine Kapitel bestehen nur aus Tabellen
[ ] Begriffe sind im Kontext erklärt
[ ] Praxis ist in Fachkapitel integriert
[ ] keine künstlichen Erweiterungsblöcke vorhanden
HTML
[ ] Single-File-HTML vorhanden
[ ] Navigation ist klappbar
[ ] Content-Kategorien sind klappbar
[ ] Kategorien sind standardmäßig geschlossen
[ ] interne Links funktionieren
[ ] Codeblöcke sind scrollbar und lesbar
[ ] SVGs sind inline sichtbar
[ ] keine externen CDN-Links vorhanden
Qualität
[ ] verbotene Muster geprüft
[ ] Wiederholungen geprüft
[ ] ZIP mit unzip -t geprüft
[ ] Quality Report erstellt
Ablage
[ ] ZIP lokal vorhanden
[ ] ZIP optional in Google Drive hochgeladen
[ ] Drive-Datei-ID dokumentiert
Diese Checkliste ist die Brücke zwischen Inhaltserstellung und stabiler Auslieferung.
---
21. Merksätze
Vorlage / Textauszug
Delivery ist Teil der Qualität.
Ein gutes ZIP ist einfach, sauber und eindeutig.
Eine schöne HTML-Datei ersetzt keine Inhaltsprüfung.
Verbotene Muster müssen vor der finalen Ausgabe geprüft werden.
Navigation muss robust sein, nicht nur optisch modern.
Offlinefähigkeit ist bei Lernmaterial ein echtes Qualitätsmerkmal.
Eine Datei ist erst ausgeliefert, wenn sie geprüft und auffindbar ist.
Versionierung, Pflegeplan und Weiterentwicklung
1. Warum ein Pflegeplan nötig ist
Ein großes Lernbuch und ein Enterprise-Lab sind nicht fertig, sobald die erste Version erzeugt wurde. Gerade ein Projekt, das Cloud, VM, Bare Metal, OpenShift, moderne Java-Services, Frontends, Security, Observability, Backup, GitOps und AI-Werkzeuge verbindet, verändert sich laufend. Bibliotheken bekommen neue Versionen, Kubernetes-APIs werden abgelöst, Security-Empfehlungen ändern sich, interne Standards wachsen und manche Architekturentscheidungen erweisen sich nach praktischer Nutzung als zu streng oder zu schwach.
Deshalb braucht das Enterprise Platform Lab einen Pflegeplan. Der Pflegeplan beschreibt, wie Inhalte aktualisiert werden, wie Fehler korrigiert werden, wie neue Kapitel aufgenommen werden und wie verhindert wird, dass spätere Erweiterungen wieder in künstliche Wiederholungen oder unklare Anhänge abrutschen.
Die wichtigste Regel lautet:
Vorlage / Textauszug
Eine neue Version darf nicht einfach mehr Text enthalten.
Eine neue Version muss fachlich besser, konsistenter und überprüfbarer sein.
Umfang allein ist kein Qualitätsmerkmal. Ein 2-MB-HTML kann schlecht sein, wenn es Wiederholungen enthält. Eine kleinere Markdown-Datei kann wertvoller sein, wenn sie sauber erklärt, konkrete Beispiele enthält und echte Entscheidungen nachvollziehbar macht. Für dieses Projekt zählt daher nicht nur Dateigröße, sondern vor allem fachliche Dichte.
---
2. Versionsmodell für das Lernbuch
Das Projekt verwendet ein einfaches semantisches Versionsmodell.
Vorlage / Textauszug
Version 1.0.x = Korrekturen ohne Strukturänderung
Version 1.x.0 = neue Kapitel oder größere Ergänzungen
Version 2.0.0 = neue Grundstruktur oder neues Zielbild
Eine Patch-Version wird verwendet, wenn Tippfehler, kaputte Links, kleine Codefehler oder fehlerhafte Formulierungen korrigiert werden.
Eine Minor-Version wird verwendet, wenn ein neues Kapitel hinzukommt, ein bestehendes Kapitel deutlich erweitert wird oder zusätzliche Übungen und Runbooks ergänzt werden.
Eine Major-Version wird verwendet, wenn die Buchstruktur selbst geändert wird. Das kann passieren, wenn später aus dem Lernbuch ein vollständiges Repository-Lab mit lauffähigen Services, Docker Compose, OpenShift-Manifests und CI/CD-Pipelines entsteht.
Beispiel:
Skizze / Textauszug
1.0.0 Erste fachlich konsolidierte Markdown-Version
1.0.1 Rechtschreibung, Links und kleinere Codekorrekturen
1.1.0 Ergänzung: Quarkus Billing Service
1.2.0 Ergänzung: vollständiges Terraform/OpenTofu Cloud-Lab
2.0.0 Umstellung auf echtes Multi-Repository-Projekt mit lauffähigem Code
Dieses Modell hilft, Änderungen nachvollziehbar zu machen. Es verhindert außerdem, dass Dateien Namen wie final_neu_fix_v2_korrigiert_letzte_version bekommen.
---
3. Saubere Dateinamen
Die bisherige Arbeit hat gezeigt, dass chaotische Dateinamen schnell unübersichtlich werden. Für die weitere Pflege gelten daher klare Namensregeln.
Dadurch kann man später eindeutig erkennen, welche Datei welche Rolle hat.
---
4. Changelog-Regeln
Jede Version bekommt einen Changelog-Eintrag. Der Changelog beschreibt nicht jeden Tippfehler, sondern relevante Änderungen.
Beispiel:
Vorlage / Textauszug
CHANGELOG
1.0.0
Erstellt
Fachbuch-Struktur mit 20 Teilen aufgebaut
Markdown-Schritte getrennt gespeichert
Qualitätsregeln gegen Wiederholungen eingeführt
Delivery-Struktur vorbereitet
Enthalten
Unternehmenskontext
Infrastruktur-Fundament
Cloud-Architektur
VM- und Bare-Metal-Betrieb
Kubernetes/OpenShift
Identity, Security und Governance
moderne Anwendungen
Daten, Messaging und Integration
Observability und Betrieb
Backup, Restore und Disaster Recovery
DevOps, GitOps und Release Management
Codex und Claude Code
komplettes Beispielprojekt
Übungen, Runbooks und Musterlösungen
integrierte Begriffserklärungen
Qualitätsprüfung und HTML-Vorbereitung
finale Delivery-Struktur
Pflegeplan
Bekannte Grenzen
lauffähiger Quellcode ist noch nicht als Repository erzeugt
finale Single-File-HTML wird in einem separaten Schritt gebaut
PDF-Ausgabe wird erst nach HTML-Abnahme erzeugt
Ein guter Changelog ist sachlich. Er behauptet nicht, dass alles perfekt ist. Er sagt klar, was enthalten ist und was noch fehlt.
---
5. Pflegeprozess für neue Inhalte
Neue Inhalte werden nicht direkt irgendwo angehängt. Sie werden nach Verantwortung einsortiert.
Wenn ein neues Thema zu Security gehört, kommt es in Teil 6. Wenn es um OpenShift-Manifests geht, kommt es in Teil 5. Wenn es um Deployments, Releases oder Rollbacks geht, kommt es in Teil 11. Wenn es um konkrete Projektdateien geht, kommt es in Teil 13.
Der Pflegeprozess lautet:
Vorlage / Textauszug
Thema bestimmen
passenden Teil auswählen
fachlichen Abschnitt schreiben
Beispiel oder Code ergänzen
typische Fehler ergänzen
Betrieb/Security-Bezug ergänzen
Übung oder Runbook ergänzen, wenn sinnvoll
Wiederholungsprüfung ausführen
README und Changelog aktualisieren
neues ZIP erzeugen
Diese Reihenfolge verhindert, dass neue Inhalte als lose Erweiterung am Ende landen.
---
6. Regel gegen künstliche Erweiterungen
Ein späterer Abschnitt darf nicht so heißen:
Vorlage / Textauszug
Praxisdurchlauf 1
Praxisdurchlauf 2
Integrierte Vertiefung 3
Anhang 16
Erweiterung 7
Zusatz 4
Solche Titel zeigen meistens, dass der Inhalt nicht sauber eingeordnet wurde.
Stattdessen muss der Titel fachlich sein:
Vorlage / Textauszug
Outbox-Backlog im Order Service analysieren
Keycloak-Rollenmodell für interne Mitarbeiter
OpenShift NetworkPolicy für Billing-Kommunikation
Restore-Test für PostgreSQL mit WAL-Archiv
Argo-CD-Rollback nach fehlerhaftem Deployment
File Processing auf Bare Metal mit Object Storage
Ein fachlicher Titel zwingt dazu, den Inhalt konkret zu machen.
---
7. Pflege von Codebeispielen
Codebeispiele altern schnell. Deshalb müssen Codebeispiele eigene Pflegekriterien erfüllen.
Ein Codeblock darf nicht nur dekorativ sein. Er muss einen Zweck haben.
Dieser Code zeigt Transaktion, Domänenaktion, Repository und Outbox. Er passt zum Lernziel.
Schlechter Codeblock:
java
publicclass Example {
publicvoid run() {
System.out.println(class="str">"Hello");
}
}
Dieser Code ist für ein Enterprise-Lab wertlos, wenn er keinen fachlichen Zusammenhang hat.
---
8. Pflege von YAML und Infrastrukturbeispielen
YAML-Beispiele müssen vollständig genug sein, um ihren Zweck zu zeigen. Gleichzeitig dürfen sie nicht so tun, als wären sie direkt produktionsfertig, wenn wichtige Teile fehlen.
Dieser Ausschnitt gehört fachlich in Security, Kubernetes oder Messaging. Er darf nicht isoliert in einem zufälligen Anhang stehen.
---
9. Pflege von Übungen
Übungen sollen nicht nur Wissen abfragen. Sie sollen Denken trainieren.
Eine schwache Übung wäre:
Vorlage / Textauszug
Was ist Kubernetes?
Eine bessere Übung wäre:
Vorlage / Textauszug
Der Order Service läuft auf OpenShift. Er kann Kafka erreichen, aber nicht PostgreSQL.
Beschreibe eine systematische Fehlersuche über DNS, Secret, NetworkPolicy, Firewall und Datenbankstatus.
Eine gute Übung enthält:
Vorlage / Textauszug
Ausgangssituation
konkrete Symptome
erwartete Analyse
technische Artefakte
Musterlösung
Dadurch wird aus einem Lernbuch ein Arbeitsbuch.
---
10. Pflege von Runbooks
Runbooks müssen ausführbar sein. Ein Runbook darf nicht nur sagen: „Problem prüfen“. Es muss konkrete Schritte enthalten.
Ein gutes Runbook enthält:
Vorlage / Textauszug
Symptom
Auswirkung
Sofortprüfung
technische Prüfkommandos
häufige Ursachen
Entscheidungspunkte
Eskalation
Wiederherstellung
Nachbereitung
Beispiel für einen Entscheidungspunkt:
Vorlage / Textauszug
Wenn nur ein Pod betroffen ist:
Pod-Logs prüfen
Readiness Probe prüfen
Rollout-Historie prüfen
Wenn alle Pods betroffen sind:
ConfigMap prüfen
Secret prüfen
externe Abhängigkeit prüfen
letzte Deployment-Version prüfen
Wenn mehrere Services betroffen sind:
Cluster-DNS prüfen
Netzwerk prüfen
Plattformkomponenten prüfen
Diese Struktur hilft im echten Betrieb.
---
11. Pflege von Architekturentscheidungen
ADRs werden nicht gelöscht, nur weil sich eine Entscheidung ändert. Eine neue Entscheidung bekommt einen neuen ADR, der den alten ersetzt oder ergänzt.
Beispiel:
Vorlage / Textauszug
ADR 001: Hybrid Platform statt Single Platform
ADR 014: PostgreSQL bleibt zunächst auf Bare Metal
ADR 021: Reporting wird schrittweise nach OpenShift migriert
ADR 029: Kafka ersetzt RabbitMQ für fachliche Domain Events
Ein ADR muss nicht lang sein. Er muss klar sein.
Mindeststruktur:
Vorlage / Textauszug
ADR XXX: Titel
Status
Vorgeschlagen / Akzeptiert / Ersetzt / Abgelehnt
Kontext
Welche Situation oder welches Problem gibt es?
Entscheidung
Was wird entschieden?
Konsequenzen
Was wird dadurch besser?
Was wird dadurch schwieriger?
Welche Nachweise sind nötig?
---
12. Qualitätsprüfung vor jeder neuen Version
Vor jeder neuen Version wird geprüft:
Vorlage / Textauszug
Gibt es generische Titel?
Gibt es wiederholte Absätze?
Besteht ein Kapitel hauptsächlich aus Tabellen?
Gibt es künstliche Nummern wie Entscheidung 2 oder Risiko 3?
Sind Praxisabschnitte fachlich integriert?
Sind Begriffe im Kontext erklärt?
Gibt es genug Fließtext?
Gibt es echte Beispiele?
Gibt es Betrieb/Security-Bezug?
Sind Dateinamen sauber?
Ein einfaches Prüfskript kann verbotene Muster finden:
python
from pathlib import Path
forbidden = [
class="str">"Praxisdurchlauf",
class="str">"integrierte Vertiefung",
class="str">"Anhang 16",
class="str">"Entscheidung 2",
class="str">"Risiko 3",
class="str">"Warum das im Lab wichtig ist: klare Nachvollziehbarkeit",
]
for path in Path(class="str">".").glob(class="str">"*.md"):
text = path.read_text(encoding=class="str">"utf-8")
for pattern in forbidden:
if pattern in text:
print(fclass="str">"Verbotenes Muster gefunden: {pattern} in {path}")
Diese Prüfung ersetzt keine fachliche Prüfung, aber sie verhindert bekannte Fehler.
---
13. Qualitätsprüfung gegen Wiederholungen
Wiederholungen sind schwieriger zu erkennen als verbotene Wörter. Deshalb braucht es zusätzlich eine Absatzprüfung.
python
from pathlib import Path
from collections import Counter
import re
paragraphs = []
for path in Path(class="str">".").glob(class="str">"*.md"):
text = path.read_text(encoding=class="str">"utf-8")
for paragraph in re.split(rclass="str">"\n\s*\n", text):
cleaned = class="str">" ".join(paragraph.split())
if len(cleaned) > 180:
paragraphs.append((cleaned, path.name))
counter = Counter(p for p, _ in paragraphs)
for paragraph, count in counter.items():
if count > 1:
print(class="str">"Wiederholter Absatz:", count)
print(paragraph[:300])
print()
Wenn ein Absatz mehrfach vorkommt, muss geprüft werden, ob es sich um eine legitime Wiederholung oder um Fülltext handelt.
---
14. Pflege der HTML-Version
Die spätere HTML-Version wird aus Markdown erzeugt. Dabei gelten feste Regeln.
<details class=class="str">"chapter" id=class="str">"teil-5">
<summary>Teil 5: Kubernetes und OpenShift</summary>
<section>
<h2>Warum OpenShift Teil der Plattform ist</h2>
<p>...</p>
</section>
</details>
Wichtige Inhalte dürfen nicht nur durch JavaScript sichtbar werden. JavaScript darf Komfort bieten, aber nicht die Grundfunktion tragen.
---
15. iPhone- und Safari-Regeln
Für lokale HTML-Dateien auf iPhone oder Safari gelten besonders vorsichtige Regeln:
Vorlage / Textauszug
keine Pflichtnavigation nur über JavaScript
keine wichtigen Inhalte nur durch onclick
details/summary für Klappbereiche
normale Ankerlinks
Tabellen und Codeblöcke horizontal scrollbar
keine externen CDN-Abhängigkeiten
keine externen Bilder
SVG inline einbetten
Copy-Button nur optional
Das bedeutet: Auch wenn der Copy-Button nicht funktioniert, muss der Code lesbar sein. Auch wenn die Suche nicht funktioniert, muss die Navigation nutzbar sein. Auch wenn Dark Mode nicht umschaltet, muss der Inhalt lesbar bleiben.
---
16. Geplanter nächster Ausbau
Nach Teil 20 gibt es drei sinnvolle Wege.
Weg A: Master-Markdown erstellen
Alle bisherigen Teile werden in eine große Markdown-Datei zusammengeführt.
Dieser Weg ist sinnvoll, wenn aus dem Lernbuch ein praktisches Lab werden soll.
---
17. Empfehlung für die nächste Phase
Die beste nächste Phase ist nicht sofort PDF. Zuerst sollte die Markdown-Konsolidierung erfolgen.
Empfohlene Reihenfolge:
Vorlage / Textauszug
Master-Markdown erzeugen
Wiederholungsprüfung ausführen
verbotene Muster prüfen
Kapitelübergänge glätten
HTML erzeugen
HTML auf Navigation prüfen
ZIP mit Markdown, HTML und README erzeugen
optional PDF erzeugen
PDF sollte erst nach HTML-Abnahme entstehen, weil PDF-Korrekturen aufwendiger sind.
---
18. Abnahmekriterien für Version 1.0
Version 1.0 ist fertig, wenn folgende Punkte erfüllt sind:
Vorlage / Textauszug
alle 20 Teile liegen als Markdown vor
Master-Markdown ist erzeugt
keine verbotenen Muster vorhanden
keine auffälligen Copy/Paste-Absätze vorhanden
Codeblöcke sind sprachlich markiert
Kapitelstruktur ist konsistent
README erklärt die Nutzung
ZIP enthält saubere Dateinamen
HTML ist erzeugt und lokal nutzbar
Navigation ist standardmäßig geschlossen
Content-Kategorien sind standardmäßig geschlossen
keine externen Assets nötig
Diese Kriterien sind strenger als „Datei wurde erzeugt“. Genau das ist wichtig, damit das Projekt nicht wieder in fehlerhafte Generatorausgaben abrutscht.
---
19. Übung: Pflegeentscheidung treffen
Ein Team möchte einen neuen Abschnitt hinzufügen:
Vorlage / Textauszug
Praxisdurchlauf 7: Keycloak testen
Der Abschnitt enthält eine kurze Beschreibung, drei Befehle und eine Tabelle mit generischen Risiken.
Entscheide:
Vorlage / Textauszug
Darf dieser Abschnitt so aufgenommen werden?
Wo müsste der Inhalt fachlich einsortiert werden?
Wie sollte der Titel lauten?
Welche zusätzlichen Inhalte fehlen?
---
20. Musterlösung
Der Abschnitt darf so nicht aufgenommen werden. Der Titel Praxisdurchlauf 7 ist generisch und zeigt keine fachliche Einordnung.
Der Inhalt gehört wahrscheinlich in Teil 6: Identity, Security und Governance. Wenn es um die technische Nutzung in einer Anwendung geht, kann zusätzlich ein Bezug zu Teil 7: Moderne Anwendungen entstehen.
Ein besserer Titel wäre:
Vorlage / Textauszug
Keycloak-OIDC-Login für das Admin Portal überprüfen
Der Abschnitt sollte enthalten:
Vorlage / Textauszug
Ausgangssituation
betroffene Anwendung
Realm und Client
Redirect-URI
Rollen und Gruppen
Token-Claims
Spring-Security-Prüfung
typische Fehler
konkrete Prüfkommandos
Runbook-Schritte
Musterlösung
Damit wird aus einem generischen Praxisdurchlauf ein echter fachlicher Abschnitt.
---
21. Merksätze
Vorlage / Textauszug
Ein Pflegeplan schützt ein großes Lernbuch vor Chaos.
Versionierung ist wichtiger als Dateinamen mit final, neu und fix.
Neue Inhalte werden fachlich integriert, nicht angehängt.
Codebeispiele müssen einen Zweck haben.
Runbooks müssen ausführbar sein.
HTML muss ohne JavaScript grundsätzlich nutzbar bleiben.
PDF kommt erst nach HTML-Abnahme.
Qualität bedeutet: weniger Wiederholung, mehr fachlicher Zusammenhang.
Übergang von Markdown zum finalen HTML-Masterbuch
1. Ziel dieses Teils
Nach den bisherigen Teilen liegt das Lernbuch nicht mehr als künstlich aufgeblasene HTML-Datei vor, sondern als Sammlung einzelner Markdown-Kapitel. Das ist Absicht. Markdown ist in dieser Phase besser geeignet, weil Inhalte fachlich geprüft, ergänzt, verschoben und konsolidiert werden können, ohne dass Layout, JavaScript oder CSS die Qualitätsarbeit verdecken.
Dieser Teil beschreibt den kontrollierten Übergang vom Markdown-Material zum finalen HTML-Masterbuch. Das Ziel ist nicht, sofort wieder eine große Datei zu erzeugen. Das Ziel ist, aus dem vorhandenen Material eine stabile, lesbare und iPhone-taugliche Single-File-HTML zu bauen, die fachlich aus echten Kapiteln besteht.
Die zentrale Regel lautet:
Vorlage / Textauszug
HTML ist nur das Ausgabeformat.
Die Qualität entsteht vorher im Markdown.
Wenn das Markdown wiederholend oder schlecht strukturiert ist, wird auch die schönste HTML-Datei schlecht. Wenn das Markdown sauber ist, kann die HTML-Datei robust, übersichtlich und langlebig werden.
---
2. Warum nicht direkt HTML schreiben?
HTML eignet sich sehr gut für die finale Darstellung, aber weniger gut für inhaltliche Facharbeit. Sobald Sidebar, Dark Mode, Copy-Buttons, Suchfeld, Code-Styling, mobile Darstellung und klappbare Kapitel eingebaut sind, wird jede inhaltliche Änderung technischer.
Markdown trennt Inhalt und Darstellung. Ein Kapitel kann erst fachlich geprüft werden, bevor es in HTML übertragen wird. Dadurch entsteht ein besserer Arbeitsfluss:
Dieser Ablauf verhindert, dass eine optisch große Datei entsteht, deren Inhalt aus Wiederholungen besteht. Genau dieser Fehler wurde vorher sichtbar: gleichartige Absätze wurden mehrfach erzeugt, nur einzelne Wörter wurden ausgetauscht. Das darf in der finalen HTML nicht mehr passieren.
---
3. Zielbild der finalen HTML
Die finale HTML ist eine einzige Datei. Sie benötigt keine externen Assets, keine CDN-Bibliotheken und keine zusätzlichen Bilderordner. Alles, was angezeigt werden soll, ist in der Datei enthalten.
Die Datei soll enthalten:
Vorlage / Textauszug
vollständiges Lernbuch
Sidebar mit Kapitelstruktur
klappbare Navigation
klappbare Inhaltskategorien
standardmäßig geschlossene Hauptkategorien
farbige Codeblöcke
Copy-Button als Komfortfunktion
inline SVG-Diagramme
responsive Darstellung für iPhone, iPad und Desktop
Suchfeld als Komfortfunktion
Inhaltsstruktur auch ohne JavaScript nutzbar
Die Datei soll nicht enthalten:
Vorlage / Textauszug
externe CSS-Dateien
externe JavaScript-Dateien
externe Bilddateien
CDN-Abhängigkeiten
künstliche Füllkapitel
generische Titel wie class="str">"Praxisdurchlauf 3"
generische Titel wie class="str">"integrierte Vertiefung 4"
generische Titel wie class="str">"Anhang 16"
Tabellen als Hauptinhalt
ein separates Glossar als Ersatz für Fachtext
---
4. HTML-Struktur
Die finale HTML bekommt eine einfache, robuste Struktur. Sie soll nicht von komplizierten JavaScript-Zuständen abhängig sein.
Diese Struktur ist bewusst einfach. Die Navigation ist semantisch ein nav. Der Hauptinhalt liegt in main. Klappbare Bereiche werden mit nativen HTML-Elementen details und summary gebaut. Dadurch funktioniert das Grundverhalten auch dann, wenn JavaScript auf einem iPhone oder in einer lokalen Datei nicht zuverlässig ausgeführt wird.
---
5. Klappbare Navigation
Die Navigation soll nicht aus verschachtelten Buttons bestehen. Buttons brauchen JavaScript und können auf lokalen iPhone-Dateien unzuverlässig sein. Stattdessen wird details/summary genutzt.
Die Gruppen sind standardmäßig geschlossen. Der Nutzer kann öffnen, was er braucht. Die Links sind echte Ankerlinks. Wenn JavaScript aktiv ist, kann ein kleines Skript den Zielbereich automatisch öffnen. Wenn JavaScript nicht aktiv ist, bleibt der Inhalt trotzdem erreichbar, weil der Link zur Stelle springt.
---
6. Klappbarer Content
Auch der Content nutzt details/summary. Jede Hauptkategorie ist standardmäßig geschlossen. Das vermeidet eine extrem lange Seite, die auf dem iPhone schwer zu überblicken wäre.
Beispiel:
html
<details class=class="str">"chapter" id=class="str">"teil-5">
<summary>
<span class=class="str">"chapter-number">Teil 5</span>
<span class=class="str">"chapter-title">Kubernetes und OpenShift-Plattform</span>
</summary>
<section id=class="str">"teil-5-namespaces">
<h3>Namespaces als Betriebs- und Sicherheitsgrenze</h3>
<p>...</p>
</section>
</details>
Wichtig: Die Überschrift im summary muss fachlich sein. Nicht erlaubt sind generische Titel wie „Kapitel 5“, wenn darunter keine fachliche Orientierung steht. Die Zahl darf helfen, aber der Name muss den Inhalt tragen.
---
7. Codeblock-Regeln
Die Codeblöcke sollen einheitlich wirken. Der Stil orientiert sich am JetBrains-Dark-Prinzip: dunkler Hintergrund, hoher Kontrast, farbliche Unterscheidung für Schlüsselwörter, Strings, Zahlen, Kommentare und Annotationen.
Die finale HTML darf dafür keine externe Highlighting-Bibliothek laden. Stattdessen gibt es zwei mögliche Wege:
Vorlage / Textauszug
Weg 1: Markdown-Codeblöcke mit CSS-Klassen darstellen, ohne feines Token-Highlighting.
Weg 2: Beim HTML-Build einfache Tokens in span-Elemente umwandeln.
Weg 2 ist schöner, aber aufwendiger. Wichtig ist, dass die Lesbarkeit stimmt. Ein Codeblock darf nicht hellgraue Schrift auf hellgrauem Hintergrund haben.
Der Copy-Button ist Komfort. Der Code muss auch ohne Button lesbar und kopierbar bleiben.
---
8. Mobile Regeln
Die HTML muss besonders für iPhone und Safari robust sein. Lokale HTML-Dateien auf iOS können bei JavaScript, Dateizugriff und komplexer DOM-Logik empfindlich sein.
Deshalb gelten folgende Regeln:
Vorlage / Textauszug
Wichtige Inhalte nicht per JavaScript nachladen.
Navigation nicht ausschließlich per JavaScript öffnen.
Keine externen Assets.
Keine CDN-Skripte.
Kein Pflicht-localStorage.
Kein Pflicht-hashchange-System.
Keine komplexe SPA-Logik.
Codeblöcke horizontal scrollbar machen.
Tabellen nur sparsam und scrollbar.
große SVGs responsive skalieren.
CSS für Codeblöcke:
css
.code-card pre {
overflow-x: auto;
-webkit-overflow-scrolling: touch;
white-space: pre;
}
Eine Suchfunktion ist hilfreich, aber sie darf die Navigation nicht ersetzen. Wenn JavaScript nicht funktioniert, muss der Nutzer weiterhin über die Sidebar und die Kapitelstruktur arbeiten können.
Die Suche kann so funktionieren:
Skizze / Textauszug
Eingabe im Suchfeld
↓
Skript sucht Überschriften und Absätze
↓
passende Kapitel werden geöffnet
↓
Treffer werden kurz markiert
Nicht erlaubt ist:
Vorlage / Textauszug
Ohne Suche ist der Inhalt nicht zugänglich.
Die Suchfunktion ist also Zusatzkomfort, nicht Fundament.
---
10. Diagramme als inline SVG
Diagramme sollen nicht als externe Bilddateien eingebunden werden. Externe Bilder waren in früheren Varianten fehleranfällig. Deshalb werden wichtige Diagramme direkt als SVG in die HTML geschrieben.
Geeignete Diagrammtypen:
Vorlage / Textauszug
Zielarchitektur
Netzwerkzonen
Cloud-VPC
OpenShift-Namespace-Modell
Eventfluss mit Outbox
Backup- und Restore-Fluss
GitOps-Deployment-Fluss
Observability-Pipeline
Ein SVG muss nicht künstlerisch perfekt sein. Es muss verständlich sein. Gute Beschriftung ist wichtiger als Dekoration.
Beispiel für ein einfaches Ziel-SVG:
html
class="str">"
0
0
900
420
" role=
class
="str">"img" aria-label=
class
="str">"Hybrid Enterprise Zielarchitektur">
class="str">"
40
" y=
class
="str">"
40
" width=
class
="str">"
180
" height=
class
="str">"
80
" rx=
class
="str">"
14
">
class="str">"
130
" y=
class
="str">"
85
" text-anchor=
class
="str">"middle">Customer Portal
class="str">"
320
" y=
class
="str">"
40
" width=
class
="str">"
180
" height=
class
="str">"
80
" rx=
class
="str">"
14
">
class="str">"
410
" y=
class
="str">"
85
" text-anchor=
class
="str">"middle">Order Service
class="str">"
220
" y1=
class
="str">"
80
" x2=
class
="str">"
320
" y2=
class
="str">"
80
">
---
11. Konsolidierung der Markdown-Dateien
Vor der HTML-Erzeugung werden alle Markdown-Dateien in eine konsolidierte Reihenfolge gebracht. Die Dateinamen geben bereits die Ordnung vor:
Der Build-Prozess liest diese Dateien sortiert ein. Dabei wird jeder Teil als eigener HTML-details-Block erzeugt.
Wichtig: Die Markdown-Dateien bleiben erhalten. Die HTML ist ein Ausgabeprodukt, nicht die einzige Quelle.
---
12. Qualitätsprüfung vor der HTML-Erzeugung
Vor dem Build wird eine Prüfung ausgeführt. Sie sucht verbotene Muster und auffällige Wiederholungen.
Beispielhafte verbotene Muster:
Vorlage / Textauszug
integrierte Vertiefung
Praxisdurchlauf
Anhang 16
Entscheidung 2
Risiko 2
Warum das im Lab wichtig ist: klare Nachvollziehbarkeit
Bei Security, Hardening und Audit beginnt die Arbeit
Diese Muster sind nicht deshalb verboten, weil die Wörter grundsätzlich falsch wären. Sie sind verboten, weil sie in den vorherigen Fassungen Anzeichen für künstliche Füllgenerierung waren.
Ein Prüfskript kann so aussehen:
python
from pathlib import Path
root = Path(class="str">"mhepl_md_steps")
forbidden = [
class="str">"integrierte Vertiefung",
class="str">"Praxisdurchlauf",
class="str">"Anhang 16",
class="str">"Entscheidung 2",
class="str">"Risiko 2",
class="str">"Warum das im Lab wichtig ist: klare Nachvollziehbarkeit",
]
failed = False
for path in sorted(root.glob(class="str">"*.md")):
text = path.read_text(encoding=class="str">"utf-8")
for pattern in forbidden:
if pattern in text:
print(fclass="str">"VERBOTENES MUSTER in {path.name}: {pattern}")
failed = True
if failed:
raise SystemExit(class="str">"Qualitätsprüfung fehlgeschlagen")
print(class="str">"Qualitätsprüfung bestanden")
---
13. Wiederholungsprüfung
Zusätzlich zur Musterprüfung braucht es eine Wiederholungsprüfung. Nicht jede Wiederholung ist schlecht. Begriffe wie OpenShift, Keycloak oder PostgreSQL kommen natürlich oft vor. Schlecht sind fast identische Absätze.
Eine einfache Heuristik:
Vorlage / Textauszug
Absätze normalisieren
sehr kurze Absätze ignorieren
identische Absätze zählen
fast identische Absätze mit Ähnlichkeit prüfen
auffällige Blöcke melden
Beispiel:
python
from pathlib import Path
from collections import Counter
import re
root = Path(class="str">"mhepl_md_steps")
paragraphs = []
for path in sorted(root.glob(class="str">"*.md")):
text = path.read_text(encoding=class="str">"utf-8")
for block in re.split(rclass="str">"\n\s*\n", text):
normalized = re.sub(rclass="str">"\s+", class="str">" ", block.strip())
if len(normalized) > 220:
paragraphs.append((path.name, normalized))
counter = Counter(p for _, p in paragraphs)
for paragraph, count in counter.items():
if count > 1:
print(class="str">"WIEDERHOLUNG", count, paragraph[:180])
Diese Prüfung ersetzt keine menschliche Kontrolle, aber sie verhindert die schlimmsten Generatorfehler.
---
14. HTML-Build-Schritte
Der finale Build folgt diesen Schritten:
Vorlage / Textauszug
Markdown-Dateien sortieren
README und Metadaten lesen
Kapitelüberschriften extrahieren
Navigation erzeugen
Markdown in HTML umwandeln
Codeblöcke in Code-Karten verpacken
SVG-Blöcke einfügen oder erhalten
Content-Kapitel als details/summary erzeugen
zentrale CSS-Datei inline einbetten
kleines Komfort-JavaScript inline einbetten
Qualitätsprüfung auf HTML ausführen
ZIP mit HTML, Markdown, README und Prüfbericht erzeugen
Der Build soll reproduzierbar sein. Das bedeutet: Wenn dieselben Markdown-Dateien eingegeben werden, entsteht dieselbe HTML-Struktur.
---
15. Abnahme der HTML
Die HTML ist erst fertig, wenn sie fachlich und technisch geprüft wurde.
Fachliche Prüfung:
Vorlage / Textauszug
Kapitel haben unterschiedliche Inhalte.
Praxis ist in Fachkapitel integriert.
Begriffe sind im Kontext erklärt.
Codebeispiele passen zum Thema.
Runbooks sind konkret.
Übungen haben Musterlösungen.
Technische Prüfung:
Vorlage / Textauszug
Datei öffnet lokal im Browser.
Navigation ist nicht kaputt.
Hauptkategorien sind geschlossen.
Anklicken von Links öffnet Zielbereich oder springt korrekt.
Codeblöcke sind lesbar.
Codeblöcke scrollen horizontal.
SVGs werden angezeigt.
ZIP enthält alle relevanten Dateien.
Mobile Prüfung:
Vorlage / Textauszug
iPhone zeigt die Datei ohne kaputtes Layout.
Sidebar bleibt nutzbar.
Content ist nicht abgeschnitten.
Code ist scrollbar.
Details/summary funktioniert ohne Speziallogik.
---
16. Ziel-ZIP der finalen Ausgabe
Das finale ZIP soll nicht aus zufälligen Dateien bestehen. Es bekommt eine saubere Struktur:
source/ enthält eine zusammengeführte Markdown-Fassung.
quality-reports/ enthält Prüfergebnisse.
README.md erklärt Start und Struktur.
---
17. Warum diese Struktur besser ist
Frühere Pakete hatten mehrere Probleme: zu viele Reparaturversionen, unklare Dateinamen, künstliche Inhalte, kaputte Navigation oder eine HTML, die zwar groß war, aber fachlich schwach. Die neue Struktur trennt diese Probleme.
Der Inhalt wächst in Markdown. Die finale HTML wird erst erzeugt, wenn das Material stabil genug ist. Das ZIP enthält sowohl das Ergebnis als auch die Quellen. Dadurch kann später gezielt verbessert werden, ohne alles neu zu verlieren.
Das ist besonders wichtig für große Lernbücher. Eine 2-MB-HTML ist nur dann wertvoll, wenn sie aus echten Inhalten besteht. Größe allein ist kein Qualitätsmerkmal.
---
18. Übung
Erstelle eine Abnahmeliste für die finale HTML. Die Liste soll mindestens zehn Punkte enthalten und zwischen fachlicher Prüfung, technischer Prüfung und mobiler Prüfung unterscheiden.
---
19. Musterlösung
Eine mögliche Abnahmeliste:
Vorlage / Textauszug
Fachliche Prüfung:
Jedes Kapitel hat einen eigenen fachlichen Schwerpunkt.
Keine Kapitel bestehen hauptsächlich aus Tabellen.
Praxisbeispiele sind in passende Fachkapitel integriert.
Begriffe werden direkt im Kontext erklärt.
Codebeispiele passen zum jeweiligen Thema.
Technische Prüfung:
Navigation verwendet native details/summary.
Alle Ankerlinks funktionieren.
Codeblöcke sind farbig und horizontal scrollbar.
SVG-Diagramme sind inline eingebettet und sichtbar.
ZIP enthält HTML, Markdown, README und Qualitätsbericht.
Mobile Prüfung:
Die Datei ist auf iPhone/Safari lesbar.
Kategorien sind standardmäßig geschlossen.
Inhalte sind auch ohne JavaScript erreichbar.
Copy-Buttons sind Komfort, aber nicht notwendig.
Keine externen Assets werden geladen.
---
20. Merksätze
Vorlage / Textauszug
Die finale HTML ist ein Ausgabeprodukt, nicht der Ort für ungeprüfte Inhaltserzeugung.
Markdown bleibt die Quelle der Wahrheit.
Navigation muss robust sein, nicht spektakulär.
Eine große HTML-Datei ist nur dann gut, wenn der Inhalt nicht künstlich wiederholt wird.
Details/summary ist für lokale, mobile und robuste Lernbücher oft besser als komplexe JavaScript-Navigation.
Das ZIP muss Quellen, Ergebnis und Prüfbericht enthalten.
Finale HTML-Build-Vorlage und Generator-Regeln
1. Ziel dieses Teils
Nach den bisherigen Markdown-Kapiteln ist klar: Die finale HTML-Datei darf nicht wieder aus automatisch aufgeblasenen Wiederholungen entstehen. Sie soll aus den vorhandenen, kapitelweise geschriebenen Markdown-Dateien gebaut werden. Dieser Teil beschreibt deshalb die Build-Regeln für die spätere Single-File-HTML.
Das Ziel ist eine robuste, offline-fähige HTML-Datei, die auf Desktop, iPad und iPhone gut lesbar bleibt. Die Datei soll keine externen Assets benötigen, keine CDN-Bibliotheken laden und keine kritischen Funktionen von JavaScript abhängig machen. JavaScript darf Komfortfunktionen ergänzen, aber Navigation, Lesen und Aufklappen müssen auch ohne JavaScript funktionieren.
Die HTML-Erzeugung ist also nicht nur ein technischer Export. Sie ist ein kontrollierter Build-Schritt mit Qualitätsprüfung.
---
2. Warum ein Build-Prozess nötig ist
Eine große Lernbuch-HTML kann schnell unübersichtlich werden. Wenn jedes Kapitel direkt per Copy/Paste eingebaut wird, entstehen leicht doppelte Überschriften, defekte Anker, kaputte Codeblöcke oder nicht funktionierende Navigation.
Ein sauberer Build-Prozess löst mehrere Aufgaben:
Vorlage / Textauszug
Markdown-Dateien in richtiger Reihenfolge einsammeln
Überschriften in stabile HTML-Anker umwandeln
Navigation aus den echten Kapitelüberschriften erzeugen
Codeblöcke einheitlich darstellen
SVGs inline einfügen
Kategorien standardmäßig geschlossen darstellen
verbotene Muster prüfen
Wiederholungen erkennen
finale HTML-Datei schreiben
ZIP-Paket mit HTML, Markdown und README erzeugen
Damit wird verhindert, dass spätere Reparaturen wieder neue Fehler erzeugen.
Wichtig ist: Navigation und Inhalt verwenden native HTML-Elemente. Dadurch bleibt die Datei auch auf iPhone/Safari stabiler.
---
4. Navigation mit details und summary
Die Navigation soll nicht aus komplexen Buttons bestehen. Buttons, die über JavaScript Inhalte ein- und ausblenden, waren in früheren Versionen fehleranfällig. Deshalb verwendet die finale Fassung native HTML-Elemente.
Beispiel:
html
<details class=class="str">"nav-group">
<summary>Teil 5: Kubernetes und OpenShift</summary>
<a href=class="str">"#teil-5-kubernetes-und-openshift-plattform">Kapitelanfang</a>
<a href=class="str">"#namespace-strategie">Namespace-Strategie</a>
<a href=class="str">"#deployment-service-und-route">Deployment, Service und Route</a>
</details>
Die Gruppen sind standardmäßig geschlossen. Der Nutzer kann sie manuell öffnen. Beim Klick auf einen Anker darf ein kleines JavaScript den Zielbereich automatisch öffnen, aber der Link selbst muss auch ohne JavaScript funktionieren.
---
5. Content-Kategorien standardmäßig geschlossen
Auch der Inhalt selbst wird pro Teil klappbar dargestellt. Dadurch ist die große Datei auf mobilen Geräten besser nutzbar.
Das ist kein vollständiger Parser. Für eine offline-fähige Single-HTML reicht ein kontrolliertes, einfaches Highlighting aus.
---
7. Inline-SVG-Regeln
Diagramme sollen nicht als separate Bilddateien eingebunden werden. Frühere Versionen hatten Probleme mit fehlenden Assets. Deshalb gilt:
Vorlage / Textauszug
SVGs werden inline in die HTML geschrieben.
Keine externen PNGs.
Keine externen SVG-Dateien.
Keine CDN-Diagrammbibliotheken.
Ein Diagramm soll fachlich passend sein. Es darf nicht nur dekorativ sein.
Gute SVG-Typen für dieses Projekt:
Vorlage / Textauszug
Zielarchitektur
Netzwerkzonen
Cloud-VPC
OpenShift Namespace-Struktur
OIDC Login Flow
Outbox Flow
GitOps Deployment Flow
Backup/Restore Flow
Observability Pipeline
VM zu OpenShift Migration
---
8. Suchfunktion als Komfort, nicht als Pflicht
Eine Suche ist hilfreich, aber sie darf die Datei nicht abhängig von JavaScript machen. Wenn JavaScript deaktiviert ist oder auf iPhone/Safari unzuverlässig läuft, muss das Lernbuch weiterhin lesbar sein.
Die Suche darf:
Vorlage / Textauszug
Treffer markieren
passende Kapitel öffnen
zum ersten Treffer springen
Die Suche darf nicht:
Vorlage / Textauszug
Inhalte dauerhaft aus dem DOM entfernen
Navigation ersetzen
Kapitel nur noch über JavaScript anzeigen
localStorage zwingend benötigen
---
9. Qualitätsprüfung vor dem HTML-Build
Vor dem HTML-Build wird geprüft, ob verbotene Muster existieren.
Beispiele für verbotene Texte:
Vorlage / Textauszug
Praxisdurchlauf 1
Praxisdurchlauf 2
integrierte Vertiefung
Anhang 16
Entscheidung 2
Risiko 2
Warum das im Lab wichtig ist: klare Nachvollziehbarkeit
Die Prüfung soll den Build abbrechen, wenn solche Muster gefunden werden.
Beispiel:
python
from pathlib import Path
forbidden = [
class="str">"Praxisdurchlauf",
class="str">"integrierte Vertiefung",
class="str">"Anhang 16",
class="str">"Entscheidung 2",
class="str">"Risiko 2",
class="str">"Warum das im Lab wichtig ist: klare Nachvollziehbarkeit",
]
root = Path(class="str">"mhepl_md_steps")
errors = []
for file in sorted(root.glob(class="str">"*.md")):
text = file.read_text(encoding=class="str">"utf-8")
for pattern in forbidden:
if pattern in text:
errors.append((file.name, pattern))
if errors:
for filename, pattern in errors:
print(fclass="str">"FEHLER: {filename} enthält verbotenes Muster: {pattern}")
raise SystemExit(1)
print(class="str">"OK: keine verbotenen Muster gefunden")
---
10. Wiederholungsprüfung
Nicht jede Wiederholung ist falsch. Fachbegriffe dürfen wieder vorkommen. Aber ganze Absätze dürfen nicht mehrfach mit minimalen Wortänderungen erscheinen.
Eine einfache Prüfung kann Absätze normalisieren und Duplikate erkennen.
python
from pathlib import Path
import re
from collections import defaultdict
root = Path(class="str">"mhepl_md_steps")
seen = defaultdict(list)
for file in sorted(root.glob(class="str">"*.md")):
text = file.read_text(encoding=class="str">"utf-8")
paragraphs = re.split(rclass="str">"\n\s*\n", text)
for idx, paragraph in enumerate(paragraphs, start=1):
clean = re.sub(rclass="str">"\s+", class="str">" ", paragraph.strip())
if len(clean) < 240:
continue
key = clean.lower()
seen[key].append((file.name, idx))
duplicates = {k: v for k, v in seen.items() if len(v) > 1}
if duplicates:
for text, locations in duplicates.items():
print(class="str">"DOPPELTER ABSATZ:")
print(text[:240], class="str">"...")
print(locations)
print()
raise SystemExit(1)
print(class="str">"OK: keine langen identischen Absätze gefunden")
Diese Prüfung ersetzt keine menschliche Kontrolle, aber sie verhindert die schlimmsten Generatorfehler.
---
11. Generator-Regel: Inhalt nicht künstlich aufblasen
Die HTML-Datei darf über 2 MB groß sein. Aber die Größe muss aus echtem Inhalt entstehen.
Nicht erlaubt:
Vorlage / Textauszug
gleiche Absätze mit ausgetauschtem Begriff
lange künstliche Tabellen
nummerierte Füllzeilen
identische Praxisblöcke
sinnlose Referenzkarten
wiederholte Glossarlisten als Seitenfüller
Erlaubt:
Vorlage / Textauszug
zusätzliche echte Kapitel
längere Enterprise-Szenarien
echte Codebeispiele
konkrete Runbooks
konkrete ADRs
echte Übungen mit Musterlösungen
fachlich passende SVG-Diagramme
---
12. Finale Build-Ausgabe
Das finale Delivery-Paket soll mindestens enthalten:
Die HTML-Datei ist der bequeme Lesestand. Die Markdown-Dateien bleiben die fachliche Quelle. Der Quality-Report dokumentiert, welche Prüfungen durchgeführt wurden.
---
13. Abnahmekriterien für die HTML
Die finale HTML gilt nur als abgenommen, wenn folgende Punkte erfüllt sind:
Vorlage / Textauszug
Datei öffnet lokal im Browser.
Navigation ist sichtbar und klappbar.
Navigation ist standardmäßig geschlossen.
Content-Kapitel sind standardmäßig geschlossen.
Ankerlinks springen zum richtigen Kapitel.
Zielkapitel kann geöffnet werden.
Codeblöcke sind lesbar.
Codeblöcke scrollen horizontal auf iPhone.
SVGs werden angezeigt.
Keine externen Assets werden benötigt.
Keine verbotenen Muster kommen vor.
Keine langen identischen Absätze kommen vor.
README erklärt Startdatei und Struktur.
ZIP enthält HTML, Master-MD, Einzelschritte und Prüfbericht.
---
14. Übung
Erstelle eine eigene kurze Checkliste für den HTML-Build. Sie soll mindestens zehn Prüfpunkte enthalten und zwischen fachlicher Qualität und technischer Qualität unterscheiden.
---
15. Musterlösung
Eine mögliche Checkliste:
Vorlage / Textauszug
Fachliche Qualität:
Jedes Kapitel hat eigenen fachlichen Zweck.
Keine künstlich wiederholten Absätze.
Praxis ist im Fachkapitel integriert.
Begriffe werden im Kontext erklärt.
Codebeispiele passen zum Kapitel.
Runbooks enthalten echte Symptome und Prüfkommandos.
Technische Qualität:
Single-File-HTML öffnet offline.
Navigation verwendet details/summary.
Content-Kapitel sind standardmäßig geschlossen.
Codeblöcke sind dunkel und lesbar.
Tabellen oder lange Zeilen scrollen horizontal.
SVGs sind inline eingebettet.
ZIP enthält README und Markdown-Quellen.
Qualitätsprüfung wurde dokumentiert.
Diese Checkliste verhindert, dass die HTML-Erzeugung wieder nur als kosmetischer Export betrachtet wird.
Finale Abnahme vor der großen HTML-Erzeugung
1. Warum eine finale Abnahme nötig ist
Bevor aus den Markdown-Kapiteln ein großes HTML-Masterbuch erzeugt wird, braucht das Projekt eine klare Abnahme. Diese Abnahme ist nicht nur ein technischer Test. Sie prüft, ob das Lernbuch fachlich sinnvoll, strukturell sauber, mobil nutzbar und frei von künstlichen Wiederholungen ist.
In den früheren Fassungen ist ein typisches Problem sichtbar geworden: Inhalte wurden zu stark automatisch aufgefüllt. Dadurch entstanden Abschnitte, die zwar lang waren, aber inhaltlich kaum Neues sagten. Genau das darf in der finalen HTML-Erzeugung nicht wieder passieren.
Die finale Abnahme beantwortet deshalb vier Fragen:
Vorlage / Textauszug
Ist der Inhalt fachlich unterschiedlich und wirklich lernbar?
Ist die Struktur stabil genug für eine große Single-File-HTML?
Funktioniert die Navigation ohne fragile JavaScript-Abhängigkeit?
Sind Codeblöcke, SVGs, Runbooks und Übungen sauber eingebettet?
Erst wenn diese Fragen positiv beantwortet sind, sollte das finale HTML erzeugt werden.
---
2. Abnahmeziel
Das Ziel ist eine robuste Version 1.0 des Lernbuchs Enterprise Platform Lab. Diese Version soll später als Markdown, HTML und ZIP ausgeliefert werden können.
Die finale HTML-Datei soll kein Generator-Demonstrator sein, sondern ein nutzbares Lernbuch. Der Leser soll darin nicht nur Begriffe finden, sondern Zusammenhänge verstehen: Warum eine hybride Plattform entsteht, wie Anwendungen und Infrastruktur zusammenhängen, wie Security eingebaut wird, wie Betrieb funktioniert und wie Codex oder Claude Code im Enterprise-Projekt sinnvoll eingesetzt werden.
Die Abnahme prüft daher nicht nur formale Dinge wie Dateinamen. Sie prüft auch, ob der Inhalt als Lernmaterial funktioniert.
---
3. Inhaltliche Abnahmekriterien
Ein Kapitel gilt nur dann als ausreichend, wenn es mehrere unterschiedliche Inhaltsformen enthält.
Erwartet werden:
Vorlage / Textauszug
fachliche Erklärung
Unternehmenskontext
Architekturentscheidung
technisches Beispiel
Code oder Konfiguration
Betriebsbezug
Security-Bezug
typische Fehler
Übung
Musterlösung
Nicht jedes Kapitel muss gleich lang sein. Aber jedes Kapitel muss einen klaren Zweck haben.
Ein schlechtes Kapitel wäre:
Vorlage / Textauszug
Das Thema ist wichtig. Es braucht README, ADR, Manifest und Runbook. Der Nachweis erfolgt über Dokumentation.
Ein gutes Kapitel erklärt dagegen konkret:
Vorlage / Textauszug
Warum der Order Service das Outbox Pattern nutzt,
welche Datenbanktabellen dafür nötig sind,
wie ein Publisher fehlerhafte Events wiederholt,
welche Metrik einen Backlog sichtbar macht,
welches Runbook im Störfall genutzt wird,
und welche Fehler bei Transaktionen auftreten können.
Diese Unterscheidung ist entscheidend.
---
4. Verbotene Muster
Vor der HTML-Erzeugung müssen bestimmte Muster ausgeschlossen werden. Sie haben in früheren Fassungen zu künstlichem Inhalt geführt.
Nicht erlaubt sind:
Vorlage / Textauszug
integrierte Vertiefung 1
integrierte Vertiefung 2
Praxisdurchlauf 1
Praxisdurchlauf 2
Anhang 16
Entscheidung 2
Risiko 3
Warum das im Lab wichtig ist: klare Nachvollziehbarkeit und reproduzierbare Umsetzung.
Solche Formulierungen zeigen meist, dass ein Generator nummerierte Blöcke erzeugt hat, statt echte Fachabschnitte zu schreiben.
Für die finale HTML-Version gilt:
Vorlage / Textauszug
Keine nummerierten Füllabschnitte.
Keine künstlichen Anhangsserien.
Keine Tabellen als Hauptinhalt.
Keine wiederholten Absatzschablonen.
Keine isolierten Praxisblöcke am Ende.
Praxis muss in die passenden Fachkapitel integriert werden.
---
5. Strukturprüfung der Markdown-Dateien
Vor dem HTML-Build müssen alle Markdown-Dateien geprüft werden.
Diese Reihenfolge wird später für Navigation, Kapitelnummern und ZIP-Struktur verwendet.
---
6. Prüfung gegen Wiederholungen
Eine einfache Wiederholungsprüfung kann Absätze vergleichen. Der Zweck ist nicht, jeden ähnlichen Satz zu verbieten. Manche Begriffe müssen wiederkehren. Der Zweck ist, große kopierte Textblöcke zu finden.
Beispielskript:
python
from pathlib import Path
from collections import Counter
import re
base = Path(class="str">"mhepl_md_steps")
paragraphs = []
for file in sorted(base.glob(class="str">"*.md")):
text = file.read_text(encoding=class="str">"utf-8")
raw_blocks = re.split(rclass="str">"\n\s*\n", text)
for block in raw_blocks:
normalized = re.sub(rclass="str">"\s+", class="str">" ", block.strip())
if len(normalized) > 180:
paragraphs.append((file.name, normalized))
counter = Counter(block for _, block in paragraphs)
for block, count in counter.most_common():
if count > 1:
print(class="str">"DUPLICATE", count, block[:240])
Wenn das Skript lange identische Absätze findet, muss vor dem HTML-Build nachgearbeitet werden.
---
7. Prüfung gegen verbotene Begriffe
Zusätzlich wird gegen bekannte Problemwörter geprüft.
python
from pathlib import Path
forbidden = [
class="str">"integrierte Vertiefung",
class="str">"Praxisdurchlauf",
class="str">"Anhang 16",
class="str">"Entscheidung 2",
class="str">"Entscheidung 3",
class="str">"Risiko 2",
class="str">"Risiko 3",
class="str">"Warum das im Lab wichtig ist: klare Nachvollziehbarkeit",
]
base = Path(class="str">"mhepl_md_steps")
failed = False
for file in sorted(base.glob(class="str">"*.md")):
text = file.read_text(encoding=class="str">"utf-8")
for pattern in forbidden:
if pattern in text:
failed = True
print(fclass="str">"FOUND: {pattern} in {file.name}")
if failed:
raise SystemExit(class="str">"Abnahme fehlgeschlagen")
print(class="str">"Keine verbotenen Muster gefunden")
Diese Prüfung ist einfach, aber sehr nützlich. Sie verhindert, dass alte Generatorreste in die finale Version gelangen.
---
8. Codeblock-Abnahme
Codeblöcke sind im Lernbuch zentral. Sie dürfen nicht nur dekorativ sein.
Jeder wichtige Codeblock soll eine Funktion haben:
Vorlage / Textauszug
Java-Code erklärt Anwendungslogik oder Security.
YAML erklärt Kubernetes, OpenShift, GitOps oder CI/CD.
SQL erklärt Datenmodell, Migration oder Analyse.
Bash erklärt Diagnose, Betrieb oder Build-Schritte.
HCL erklärt Cloud- oder Infrastrukturressourcen.
Markdown erklärt ADRs, README oder Runbooks.
Für die finale HTML-Version gelten zusätzlich diese Regeln:
Vorlage / Textauszug
dunkler Codeblock-Hintergrund
gut lesbare Schrift
Syntaxfarben nach JetBrains-Dark-Prinzip
horizontales Scrollen auf iPhone, iPad und Desktop
Copy-Button nur als Komfortfunktion
Code bleibt auch ohne JavaScript lesbar
Ein Codeblock darf nie schwarze Schrift auf dunklem Hintergrund oder hellgraue Schrift auf hellem Hintergrund erzeugen.
---
9. SVG- und Diagramm-Abnahme
SVGs sollen nicht zufällig eingefügt werden. Jedes Diagramm muss ein Thema besser verständlich machen.
Geeignete Diagrammarten:
Vorlage / Textauszug
Zielarchitektur
Netzwerkzonen
Cloud-VPC
OpenShift-Namespaces
OIDC-Loginfluss
Outbox-Eventfluss
Backup-und-Restore-Fluss
GitOps-Deploymentfluss
Observability-Pipeline
VM-zu-OpenShift-Migration
Für die finale HTML gilt:
Vorlage / Textauszug
SVGs inline einbetten
keine externen Bilddateien voraussetzen
Diagramme mit Textlabels versehen
mobile Ansicht beachten
keine riesigen überbreiten SVGs ohne Scrollcontainer
Ein Diagramm ist gut, wenn der Leser nach dem Betrachten eine Beziehung schneller versteht als nur durch Text.
---
10. Navigationsabnahme
Die Navigation war in früheren HTML-Versionen fehleranfällig. Deshalb wird die finale Navigation bewusst einfach gehalten.
Die HTML-Datei soll auch dann nutzbar bleiben, wenn JavaScript nicht oder nur teilweise funktioniert.
---
11. Content-Kategorien standardmäßig geschlossen
Der Nutzer möchte klappbare Kategorien, die standardmäßig geschlossen sind. Das wird mit nativen details umgesetzt.
Beispiel:
html
<details class=class="str">"chapter" id=class="str">"teil-8">
<summary>Teil 8: Daten, Messaging und Integration</summary>
<section>
<h2>Warum Datenbesitz wichtiger ist als gemeinsame Datenbanken</h2>
<p>...</p>
</section>
</details>
Wichtig: Die Inhalte dürfen nicht durch CSS display:none ohne zugänglichen Öffnungsmechanismus versteckt werden. Native Details-Elemente sind stabiler, besonders bei lokalen HTML-Dateien auf iPhone und iPad.
---
12. iPhone- und Safari-Abnahme
Lokale HTML-Dateien auf iPhone oder iPad können problematisch sein. Daher muss die finale HTML bewusst robust sein.
Prüfpunkte:
Vorlage / Textauszug
Datei öffnet ohne externe Internetverbindung.
Navigation ist mit Tippen bedienbar.
Kategorien lassen sich öffnen und schließen.
Codeblöcke scrollen horizontal.
Tabellen, falls vorhanden, sprengen nicht das Layout.
Copy-Button ist optional, nicht notwendig.
Suche ist Komfort, nicht Pflicht.
Inhalte bleiben auch ohne JavaScript erreichbar.
Falls eine Funktion auf iPhone nicht zuverlässig ist, darf sie nicht kritisch sein.
---
13. Qualitätsbericht
Vor dem finalen HTML-Build sollte ein kurzer Qualitätsbericht erzeugt werden.
Vorlage:
Vorlage / Textauszug
Quality Report
Dateien
Markdown-Teile: 23
README vorhanden: ja
ZIP geprüft: ja
Verbotene Muster
integrierte Vertiefung: nicht gefunden
Praxisdurchlauf: nicht gefunden
Anhang 16: nicht gefunden
Entscheidung 2/3: nicht gefunden
Risiko 2/3: nicht gefunden
Wiederholungsprüfung
lange identische Absätze: keine kritischen Treffer
künstliche Tabellenserien: keine kritischen Treffer
HTML-Vorbereitung
Navigation: details/summary
Content-Kategorien: geschlossen
Codeblöcke: JetBrains-Dark-Prinzip
SVGs: inline
externe Assets: keine
Ergebnis
Freigegeben für finale HTML-Erzeugung.
Dieser Bericht muss nicht lang sein. Er soll aber zeigen, dass die Datei nicht blind generiert wurde.
---
14. Entscheidung: Wann wird HTML erzeugt?
HTML sollte erst erzeugt werden, wenn die Markdown-Fassung inhaltlich stabil ist.
Noch nicht geeignet:
Vorlage / Textauszug
Kapitel fehlen
Wiederholungen sind sichtbar
Beispiele sind nur Platzhalter
Codeblöcke sind unvollständig
Navigation ist nicht geplant
Geeignet:
Vorlage / Textauszug
alle Hauptteile sind vorhanden
Code und Text sind sinnvoll verteilt
Übungen und Musterlösungen existieren
Qualitätsregeln sind dokumentiert
verbotene Muster wurden geprüft
HTML-Struktur ist festgelegt
Mit Teil 23 ist die fachliche Abnahme vorbereitet. Danach kann die HTML-Erzeugung als eigener Build-Schritt erfolgen.
---
15. Übung
Erstelle eine eigene Abnahmeliste für ein Lernbuch oder Projektpaket.
Die Liste soll prüfen:
Vorlage / Textauszug
Inhaltliche Qualität
Wiederholungen
Dateistruktur
Codeblöcke
Diagramme
Navigation
mobile Nutzung
ZIP-Paket
---
16. Musterlösung
Eine mögliche Abnahmeliste:
Vorlage / Textauszug
Inhalt:
Jedes Kapitel erklärt ein eigenes Thema und enthält keine sichtbaren Füllabsätze.
Wiederholungen:
Lange identische Absätze werden mit einem Skript geprüft.
Dateistruktur:
Alle Kapitel liegen als nummerierte Markdown-Dateien vor.
Codeblöcke:
Code ist fachlich sinnvoll, lesbar und mit Sprache gekennzeichnet.
Diagramme:
SVGs sind inline und erklären reale Architekturbeziehungen.
Navigation:
HTML nutzt details/summary und echte Ankerlinks.
Mobile Nutzung:
Codeblöcke scrollen, Kategorien sind tippbar, JavaScript ist nicht kritisch.
ZIP:
Das ZIP enthält Markdown, HTML, README und Quality Report. Es wird mit unzip -t geprüft.
Diese Musterlösung ist absichtlich praktisch. Sie kann direkt als Checkliste für die finale Version 1.0 verwendet werden.
---
17. Merksätze
Vorlage / Textauszug
Eine große HTML-Datei ist nur wertvoll, wenn der Inhalt nicht künstlich aufgeblasen ist.
Die beste Reparatur gegen schlechte Generatorausgaben ist eine klare Abnahme vor der Erzeugung.
Navigation muss robust sein, nicht beeindruckend kompliziert.
Codeblöcke und Diagramme müssen erklären, nicht dekorieren.
Mobile Nutzbarkeit entsteht durch einfache HTML-Struktur und nicht durch fragile Skripte.
Ein ZIP-Paket ist erst fertig, wenn Inhalt, Struktur und Prüfung nachvollziehbar sind.
Finale HTML-Erzeugung als Single-File-Masterbuch
1. Ziel dieses Teils
Nach den vorherigen Abnahmeregeln darf die finale HTML-Datei nicht mehr durch künstliches Aufblasen entstehen. Sie soll aus den vorhandenen Markdown-Teilen erzeugt werden und dabei die Fachstruktur bewahren. Der Zweck dieses Teils ist deshalb nicht, noch mehr Inhalt anzuhängen, sondern den sauberen Übergang vom geprüften Markdown-Material zum endgültigen HTML-Masterbuch zu beschreiben.
Die HTML-Erzeugung verfolgt vier Ziele:
Vorlage / Textauszug
Der Inhalt bleibt fachlich und kapitelorientiert.
Die Navigation ist robust und funktioniert auch ohne komplexes JavaScript.
Codeblöcke sind gut lesbar, dunkel und farbig hervorgehoben.
Die Datei ist als lokale Single-File-HTML auf PC, iPad und iPhone nutzbar.
Wichtig ist: Die HTML-Datei ist keine neue inhaltliche Version. Sie ist eine Ausgabeform des Masterbuchs. Inhaltliche Ergänzungen werden weiterhin zuerst in Markdown geschrieben und geprüft. Erst danach entsteht eine neue HTML-Version.
---
2. Warum Single-File-HTML
Bei lokalen HTML-Dateien entstehen oft Probleme, wenn Bilder, CSS-Dateien oder JavaScript-Dateien in separaten Ordnern liegen. Besonders auf iPhone und iPad werden lokale Pfade nicht immer zuverlässig aufgelöst. Auch Messenger-Apps, die Dateien weiterleiten, verlieren manchmal Begleitordner oder blockieren Skripte.
Deshalb wird für dieses Projekt eine Single-File-HTML verwendet.
Das bedeutet:
Vorlage / Textauszug
CSS liegt direkt im HTML.
JavaScript liegt direkt im HTML.
SVG-Diagramme liegen direkt im HTML.
Es gibt keine externen CDN-Links.
Es gibt keine separaten Asset-Ordner.
Codeblöcke brauchen keine externe Highlighting-Bibliothek.
Der Nachteil ist eine größere HTML-Datei. Der Vorteil ist eine deutlich robustere Nutzung. Für ein Lernbuch ist das wichtiger als eine elegante technische Trennung.
---
3. Grundstruktur der finalen HTML-Datei
Die finale HTML-Datei verwendet eine einfache Struktur:
Diese Struktur ist bewusst konservativ. Sie vermeidet komplexe Frameworks und dynamische Seitenlogik. Das Buch soll zuerst lesbar sein. Komfortfunktionen kommen erst danach.
---
4. Navigation mit details und summary
Die Navigation wird nicht mit verschachtelten Buttons gebaut. Stattdessen verwendet sie native HTML-Elemente.
Der Inhalt ist dadurch nicht verschwunden. Er ist nur eingeklappt. Das ist wichtig, weil eine sehr große HTML-Datei sonst auf mobilen Geräten unübersichtlich wird.
Eine gute Regel lautet:
Vorlage / Textauszug
Navigation geschlossen.
Content-Kategorien geschlossen.
Angeklickter Zielbereich darf automatisch geöffnet werden.
Das automatische Öffnen ist Komfort. Ohne JavaScript kann der Nutzer den Bereich manuell öffnen.
---
6. Umgang mit Ankerlinks
Jedes Kapitel bekommt eine stabile ID. Diese IDs dürfen später nicht zufällig geändert werden, weil sonst interne Links brechen.
Gute IDs:
Vorlage / Textauszug
teil-1-unternehmenskontext
teil-5-kubernetes-openshift
teil-8-outbox-pattern
teil-10-disaster-recovery
teil-13-komplettes-beispielprojekt
Schlechte IDs:
Vorlage / Textauszug
section-1
block-42
anhang-16
praxisdurchlauf-3
integrierte-vertiefung-7
Stabile IDs sind Teil der Buchqualität. Wenn der Nutzer eine Stelle wiederfinden möchte, muss der Link auch in späteren Versionen möglichst erhalten bleiben.
---
7. Codeblöcke im JetBrains-Dark-Prinzip
Codeblöcke sind in diesem Projekt besonders wichtig. Deshalb bekommen sie ein einheitliches dunkles Design.
Anforderungen:
Vorlage / Textauszug
dunkler Hintergrund
gut lesbare helle Schrift
farbige Tokens für Keywords, Strings, Kommentare, Zahlen und Annotationen
horizontales Scrollen auf kleinen Bildschirmen
Copy-Button rechts oben, wo JavaScript funktioniert
Das Syntax-Highlighting kann durch einfache Vorverarbeitung beim HTML-Build entstehen. Es muss nicht im Browser zur Laufzeit berechnet werden. Dadurch bleibt die Datei stabiler.
Dieser Stil ist nicht identisch mit einer IDE, orientiert sich aber am JetBrains-Dark-Prinzip: dunkler Hintergrund, klare Kontraste und farbige syntaktische Signale.
---
9. Inline-SVG statt Bilddateien
Diagramme werden als Inline-SVG eingebettet. Dadurch gibt es keine fehlenden Bilddateien.
Beispiel:
html
class=
class
="str">"diagram" viewBox=
class
="str">"
0
0
900
420
" role=
class
="str">"img" aria-label=
class
="str">"Hybrid Enterprise Architektur">
class="str">"
40
" y=
class
="str">"
40
" width=
class
="str">"
190
" height=
class
="str">"
80
" rx=
class
="str">"
14
">
class="str">"
135
" y=
class
="str">"
85
" text-anchor=
class
="str">"middle">Customer Portal
SVGs müssen fachlich benannt werden. Ein Diagramm darf nicht nur dekorativ sein. Es soll einen Zusammenhang erklären, zum Beispiel:
Vorlage / Textauszug
Netzwerkzonen
OpenShift-Architektur
Outbox-Flow
Backup-und-Restore-Ablauf
GitOps-Promotion
Identity-Flow mit Keycloak
---
10. Suchfunktion als Komfortfunktion
Eine Suchfunktion ist hilfreich, aber sie darf nicht notwendig sein, um das Buch zu lesen.
Die Suchfunktion kann:
Vorlage / Textauszug
Text im Hauptbereich suchen
passende Kapitel öffnen
Treffer hervorheben
zur ersten Fundstelle springen
Aber ohne JavaScript muss das Buch weiterhin vollständig nutzbar sein. Deshalb darf kein Kapitel ausschließlich durch JavaScript geladen werden.
Nicht erlaubt:
Vorlage / Textauszug
Inhalte per JavaScript nachladen
Navigation nur mit onclick ohne href
Kapitel vollständig verstecken, wenn JS nicht läuft
localStorage als Pflicht für Grundfunktion
Erlaubt:
Vorlage / Textauszug
Copy-Button
Suchfeld
Zielkapitel automatisch öffnen
kleine Treffer-Hervorhebung
---
11. Build-Prozess
Der Build-Prozess besteht aus mehreren Schritten.
Vorlage / Textauszug
Markdown-Dateien einsammeln
Reihenfolge prüfen
verbotene Muster prüfen
doppelte Absätze prüfen
Codeblöcke erkennen
Codeblöcke in HTML-Karten umwandeln
Überschriften in stabile IDs umwandeln
Navigation erzeugen
Content-Kapitel als details/summary erzeugen
Inline-SVGs einbetten
CSS und Komfort-JavaScript einfügen
finale HTML schreiben
ZIP mit HTML, Markdown-Quelle, README und Quality-Report erstellen
Der wichtigste Schritt ist nicht die HTML-Formatierung. Der wichtigste Schritt ist die Prüfung vor dem Build.
---
12. Beispiel: Python-Build-Skelett
python
from pathlib import Path
import html
import re
SOURCE_DIR = Path(class="str">"mhepl_md_steps")
OUT_DIR = Path(class="str">"dist")
OUT_DIR.mkdir(exist_ok=True)
FORBIDDEN = [
class="str">"integrierte Vertiefung",
class="str">"Praxisdurchlauf",
class="str">"Anhang 16",
class="str">"Entscheidung 2",
class="str">"Risiko 2",
]
def read_parts():
files = sorted(SOURCE_DIR.glob(class="str">"*_Teil_*.md"))
return [(path.name, path.read_text(encoding=class="str">"utf-8")) for path in files]
def check_forbidden(parts):
errors = []
forname, text in parts:
for pattern in FORBIDDEN:
if pattern.lower() in text.lower():
errors.append(fclass="str">"{name}: verbotenes Muster gefunden: {pattern}")
return errors
def slugify(title):
value = title.lower()
value = value.replace(class="str">"ä", class="str">"ae").replace(class="str">"ö", class="str">"oe").replace(class="str">"ü", class="str">"ue").replace(class="str">"ß", class="str">"ss")
value = re.sub(rclass="str">"[^a-z0-9]+", class="str">"-", value).strip(class="str">"-")
return value or class="str">"abschnitt"
parts = read_parts()
errors = check_forbidden(parts)
if errors:
raise SystemExit(class="str">"\n".join(errors))
print(fclass="str">"OK: {len(parts)} Markdown-Dateien bereit für HTML-Build")
Dieses Skelett ersetzt keinen vollständigen Generator, zeigt aber die Richtung: Erst prüfen, dann bauen.
---
13. Qualitätsbericht als Pflichtdatei
Jede finale HTML-Ausgabe bekommt einen Quality-Report.
Der Report enthält:
Vorlage / Textauszug
Anzahl Markdown-Dateien
Anzahl Codeblöcke
Anzahl Diagramme
gefundene verbotene Muster
Prüfung doppelter Absätze
HTML-Dateigröße
ZIP-Prüfung
Datum der Erzeugung
bekannte Grenzen
Ein Beispiel:
Vorlage / Textauszug
Quality Report
Ergebnis
Status: bestanden
Prüfungen
Verbotene Muster: keine gefunden
Doppelte Absätze: keine kritischen Wiederholungen
Generische Titel: keine gefunden
Codeblöcke: vorhanden
Inline-SVGs: vorhanden
Navigation: details/summary
Content-Kategorien: standardmäßig geschlossen
Externe Assets: keine
Bekannte Grenzen
Die HTML-Datei ist groß. Auf älteren Mobilgeräten kann das erste Öffnen etwas dauern.
Dieser Bericht verhindert, dass später wieder unbemerkt mangelhafte HTML-Pakete entstehen.
---
14. Abnahme der finalen HTML-Datei
Die HTML-Datei gilt erst als abgenommen, wenn folgende Punkte erfüllt sind:
Vorlage / Textauszug
Öffnen auf Desktop-Browser funktioniert.
Öffnen auf iPhone/Safari funktioniert.
Navigation ist sichtbar und klappbar.
Kategorien im Content sind klappbar.
Standardzustand ist geschlossen.
Ankerlinks springen zum richtigen Bereich.
Codeblöcke sind lesbar und scrollbar.
SVGs werden angezeigt.
Keine externen Dateien fehlen.
Keine generischen Füllbegriffe sind sichtbar.
ZIP enthält HTML, Markdown-Quelle, README und Quality-Report.
Erst danach ist die Ausgabe eine echte Version.
---
15. Übung
Entwirf eine eigene Mini-Abnahme für die finale HTML-Datei.
Die Abnahme soll mindestens enthalten:
Vorlage / Textauszug
Navigationstest
Codeblock-Test
SVG-Test
Mobile-Test
Wiederholungsprüfung
ZIP-Prüfung
Beschreibe zu jedem Punkt, wie du den Test durchführen würdest.
---
16. Musterlösung
Vorlage / Textauszug
Navigationstest:
Ich öffne die HTML-Datei lokal im Browser. Danach öffne ich mehrere Navigationsgruppen und klicke auf interne Links. Der Zielbereich muss korrekt angesprungen werden.
Codeblock-Test:
Ich prüfe Java-, YAML-, SQL- und Bash-Codeblöcke. Die Schrift muss gut lesbar sein, der Hintergrund dunkel und horizontales Scrollen muss auf schmalem Bildschirm funktionieren.
SVG-Test:
Ich prüfe alle Diagramme im Buch. Jedes Diagramm muss sichtbar sein und darf nicht auf eine externe Datei verweisen.
Mobile-Test:
Ich öffne die HTML-Datei auf iPhone oder iPad. Navigation und Content-Kategorien müssen mit Tippen aufklappbar sein. Das Buch darf nicht von JavaScript abhängig sein.
Wiederholungsprüfung:
Ich führe ein Skript aus, das längere identische Absätze erkennt. Kritische Wiederholungen müssen vor der HTML-Erzeugung entfernt werden.
ZIP-Prüfung:
Ich öffne das ZIP und prüfe, ob HTML, Markdown-Quelle, README und Quality-Report enthalten sind. Danach teste ich das ZIP mit unzip -t oder einem vergleichbaren Tool.
---
17. Merksätze
Vorlage / Textauszug
HTML ist die Ausgabeform, nicht die Quelle der Wahrheit.
Die Quelle der Wahrheit bleibt Markdown.
Single-File-HTML ist für lokale Lernbücher robuster als viele getrennte Assets.
Navigation muss zuerst ohne JavaScript funktionieren.
Codeblöcke müssen auf Desktop und Mobilgerät lesbar sein.
Ein Quality-Report schützt vor Rückfällen in künstlich erzeugte Füllinhalte.
Finale Master-HTML, README, Quality-Report und Drive-Ablage
1. Ziel dieses Teils
Nach den bisherigen Teilen ist das Projekt nicht mehr nur eine Sammlung einzelner Lerntexte. Es ist ein vorbereitetes Fachbuch mit klaren Regeln, einer schrittweisen Markdown-Struktur und einer späteren HTML-Ausgabe. Dieser Teil beschreibt, wie aus dem bisherigen Material ein finales Delivery-Paket entsteht, ohne wieder in die Fehler der ersten Generator-Versionen zurückzufallen.
Die zentrale Idee bleibt: Das HTML darf nicht durch künstliche Wiederholungen wachsen. Es soll groß werden, weil die Inhalte fachlich stark sind. Es soll navigierbar sein, weil die Struktur sauber ist. Es soll auf iPhone, iPad und Desktop funktionieren, weil wichtige Funktionen nicht zwingend von JavaScript abhängen.
Der finale Auslieferungsstand besteht aus mehreren Bausteinen:
Vorlage / Textauszug
konsolidierte Markdown-Datei
einzelne Markdown-Teildateien
Single-File-HTML
README
Quality-Report
optionaler Build-Ordner mit Hilfsskripten
ZIP-Paket
Kopie in Google Drive
Dieser Teil ist also kein weiteres Fachkapitel zu Cloud oder Kubernetes. Er ist der Übergang vom geschriebenen Lernbuch zur kontrollierten Veröffentlichung.
---
2. Warum ein Quality-Report notwendig ist
In den ersten HTML-Fassungen sind mehrere typische Fehler entstanden: generische Titel, wiederholte Absätze, künstliche Tabellen, aufgeblasene Fülltexte und defekte Navigation. Genau deshalb braucht das Projekt eine formale Abnahme. Der Quality-Report ist kein Bürokratie-Dokument. Er ist der Nachweis, dass die Datei vor der Auslieferung geprüft wurde.
Ein guter Quality-Report beantwortet nicht nur die Frage „Wurde eine Datei erzeugt?“, sondern auch:
Vorlage / Textauszug
Wurde der Inhalt gegen Wiederholungen geprüft?
Sind die Navigationseinträge fachlich benannt?
Sind die Content-Kategorien standardmäßig geschlossen?
Funktionieren Ankerlinks ohne komplizierte JavaScript-Abhängigkeit?
Sind Codeblöcke lesbar?
Sind SVGs inline eingebettet?
Gibt es verbotene Muster wie „Praxisdurchlauf 3“?
Gibt es künstliche Tabellen mit nummerierten Füllzeilen?
Ist das ZIP vollständig?
Damit wird Qualität überprüfbar. Der Quality-Report ist besonders wichtig, wenn später HTML oder PDF aus dem Material erzeugt wird. Ohne diesen Schritt würde jede neue Ausgabe wieder riskieren, alte Fehler mitzunehmen.
---
3. Finale Delivery-Struktur
Das finale Paket sollte nicht aus vielen unklaren Dateien mit Namen wie final_fix_neu_v2_clean.html bestehen. Solche Namen zeigen meistens, dass die Ausgabe mehrfach repariert wurde und niemand mehr weiß, welche Datei gültig ist.
Für die laufenden Zwischenstände reicht weiterhin ein kompaktes ZIP mit den Markdown-Dateien. Für die finale Version wird diese Delivery-Struktur wichtig.
---
4. README für das finale Paket
Die README ist der Einstiegspunkt. Sie muss kurz erklären, was im Paket enthalten ist und welche Datei geöffnet werden soll. Sie ist nicht der Ort für lange Theorie. Sie ist die Gebrauchsanleitung.
Eine gute README sieht so aus:
Vorlage / Textauszug
Enterprise Platform Lab
Dieses Paket enthält das Lernbuch „Enterprise Platform Lab“.
Die HTML-Datei ist eine Single-File-Ausgabe ohne externe Assets.
SVGs, CSS und Codeblock-Darstellung sind inline enthalten.
Die Navigation nutzt native HTML-Elemente und bleibt auch ohne JavaScript grundsätzlich nutzbar.
Diese README verhindert, dass der Leser im ZIP suchen muss.
---
5. CHANGELOG-Regel
Ein Changelog beschreibt nicht jede kleine interne Änderung, sondern relevante Versionen. Für dieses Projekt reicht ein einfaches Format.
Vorlage / Textauszug
CHANGELOG
1.0.0
erste vollständige Fachbuchversion
Markdown-Teile 1 bis 25 konsolidiert
Single-File-HTML erzeugt
Quality-Report ergänzt
ZIP-Paket erstellt
0.9.0
Markdown-Grundstruktur abgeschlossen
Wiederholungsregeln definiert
HTML-Build-Regeln vorbereitet
Wichtig ist: Versionen sollen nachvollziehbar sein. Wenn später eine neue HTML-Datei erzeugt wird, soll klar sein, ob sie Version 1.0.0, 1.1.0 oder eine experimentelle Zwischenfassung ist.
---
6. Quality-Report-Vorlage
Der Quality-Report wird später automatisch oder manuell gefüllt. Eine Vorlage kann so aussehen:
Vorlage / Textauszug
QUALITY REPORT
Paket
Name: Modern_Hybrid_Enterprise_Platform_Lab
Version: 1.0.0
Datum: 2026-07-06
Dateien
Markdown Masterbook: vorhanden
einzelne Markdown-Dateien: vorhanden
Single-File-HTML: vorhanden
README: vorhanden
CHANGELOG: vorhanden
Inhaltsprüfung
keine generischen „Praxisdurchlauf X“-Titel gefunden
keine generischen „integrierte Vertiefung X“-Titel gefunden
keine generischen „Anhang 16“-Navigationseinträge gefunden
keine künstlichen Entscheidung-2/Risiko-2-Tabellen gefunden
keine stark wiederholten Absätze über Grenzwert gefunden
HTML-Prüfung
Navigation nutzt details/summary
Navigation standardmäßig geschlossen
Content-Kategorien standardmäßig geschlossen
Ankerlinks vorhanden
Codeblöcke mit dunklem Hintergrund vorhanden
SVGs inline eingebettet
keine externen CDN-Links gefunden
Mobile Prüfung
horizontales Scrollen für Codeblöcke aktiv
Tabellen brechen nicht das Layout
wichtige Inhalte ohne JavaScript lesbar
Ergebnis
Status: akzeptiert / nicht akzeptiert
Bemerkung:
Diese Vorlage kann später in das finale ZIP aufgenommen werden.
---
7. Prüfskript gegen verbotene Muster
Das folgende Skript prüft zentrale Begriffe, die in den früheren fehlerhaften Fassungen aufgetreten sind. Es ersetzt keine fachliche Prüfung, aber es verhindert bekannte Fehler.
python
from pathlib import Path
ROOT = Path(class="str">"markdown")
FORBIDDEN = [
class="str">"Praxisdurchlauf 1",
class="str">"Praxisdurchlauf 2",
class="str">"Praxisdurchlauf 3",
class="str">"integrierte Vertiefung",
class="str">"Anhang 16",
class="str">"Entscheidung 2",
class="str">"Entscheidung 3",
class="str">"Risiko 2",
class="str">"Risiko 3",
class="str">"Warum das im Lab wichtig ist: klare Nachvollziehbarkeit",
]
failed = False
for path in ROOT.glob(class="str">"*.md"):
text = path.read_text(encoding=class="str">"utf-8")
for pattern in FORBIDDEN:
if pattern in text:
print(fclass="str">"FEHLER: {path} enthält verbotenes Muster: {pattern}")
failed = True
if failed:
raise SystemExit(1)
print(class="str">"OK: Keine verbotenen Muster gefunden.")
Wichtig ist: Die Liste kann erweitert werden, wenn neue schlechte Muster erkannt werden. Qualität entsteht hier durch Lernen aus Fehlern.
---
8. Prüfskript gegen Absatzwiederholungen
Ein zweites Skript sucht nach mehrfach identischen langen Absätzen. Es erkennt nicht jede semantische Wiederholung, aber es findet Copy/Paste-Blöcke.
python
from pathlib import Path
from collections import Counter
import re
ROOT = Path(class="str">"markdown")
paragraphs = []
for path in ROOT.glob(class="str">"*.md"):
text = path.read_text(encoding=class="str">"utf-8")
chunks = re.split(rclass="str">"\n\s*\n", text)
for chunk in chunks:
normalized = re.sub(rclass="str">"\s+", class="str">" ", chunk.strip())
if len(normalized) > 180:
paragraphs.append((normalized, path.name))
counter = Counter(p for p, _ in paragraphs)
failed = False
for paragraph, count in counter.items():
if count >= 3:
print(class="str">"FEHLER: Absatz mehrfach vorhanden:")
print(class="str">"Anzahl:", count)
print(paragraph[:300], class="str">"...")
failed = True
if failed:
raise SystemExit(1)
print(class="str">"OK: Keine auffälligen Absatzwiederholungen gefunden.")
Dieses Skript schützt besonders gegen den Fehler, bei dem nur einzelne Wörter ausgetauscht wurden, der Absatz aber strukturell gleich blieb.
---
9. HTML-Navigation: finale Regel
Die Navigation darf nicht mehr kompliziert gebaut werden. Sie muss robust bleiben.
Richtig:
html
<nav class=class="str">"sidebar">
<details>
<summary>Teil 1: Unternehmenskontext und Zielbild</summary>
<a href=class="str">"#teil-1-ziel">Ziel des Kapitels</a>
<a href=class="str">"#teil-1-architektur">Zielarchitektur</a>
</details>
</nav>
Der Content dazu:
html
<main>
<details class=class="str">"content-section" id=class="str">"teil-1">
<summary>Teil 1: Unternehmenskontext und Zielbild</summary>
<section id=class="str">"teil-1-ziel">
<h2>Ziel des Kapitels</h2>
<p>...</p>
</section>
</details>
</main>
Nicht erlaubt:
Vorlage / Textauszug
Navigation über verschachtelte Buttons ohne Fallback.
Navigation, die nur mit JavaScript sichtbar wird.
Kapitel, die per display:none versteckt bleiben und nicht mehr erreichbar sind.
Links ohne passende Ziel-ID.
Diese Regel ist besonders wichtig für iPhone und lokale HTML-Dateien.
---
10. Codeblock-Regel für finale HTML
Codeblöcke müssen lesbar und konsistent sein. Das Projekt folgt dem JetBrains-Dark-Prinzip: dunkler Hintergrund, gute Kontraste, farbige Syntax, horizontales Scrollen und keine hellgraue Schrift auf hellem Grund.
Für Markdown bleibt normaler Codeblock erhalten. Die farbige Darstellung entsteht erst beim HTML-Build.
---
11. Inline-SVG-Regel
SVGs dürfen nicht als separate Dateien fehlen. Deshalb werden zentrale Diagramme inline in die HTML geschrieben. Für Markdown kann zusätzlich Mermaid verwendet werden. In der finalen HTML müssen wichtige Diagramme aber sichtbar sein, auch wenn kein externes Renderer-System geladen wird.
Geeignete Diagramme:
Vorlage / Textauszug
Gesamtarchitektur
Netzwerkzonen
OpenShift Deployment Flow
Outbox Event Flow
Backup/Restore Ablauf
GitOps Promotion Flow
Identity/OIDC Ablauf
Observability Pipeline
Ein SVG muss nicht künstlerisch perfekt sein. Es muss verständlich sein. Wichtiger als Dekoration ist die fachliche Aussage.
---
12. Google-Drive-Ablage
Das finale ZIP wird zusätzlich in Google Drive abgelegt. Der Zielordner ist der konfigurierte Projektordner chatgpt.
Die Ablage soll nicht nur „irgendwo“ erfolgen. Die Datei muss einen klaren Namen bekommen:
So bleibt klar, welche Datei nur Markdown-Schritte enthält und welche Datei die finale HTML-Ausgabe enthält.
---
13. Abnahme vor Google Drive Upload
Vor jedem Upload nach Google Drive muss geprüft werden:
Vorlage / Textauszug
ZIP existiert lokal.
ZIP lässt sich öffnen.
README ist enthalten.
neue Markdown-Datei ist enthalten.
alte Markdown-Dateien fehlen nicht.
Dateiname ist eindeutig.
Upload-Zielordner ist korrekt.
Upload liefert Datei-ID oder Link zurück.
Wenn der Upload keine Datei-ID oder keinen Link zurückgibt, gilt er nicht als sicher bestätigt. In diesem Fall wird erneut geprüft oder die lokale ZIP-Datei bleibt als primärer Download erhalten.
---
14. Runbook: Drive-Upload schlägt fehl
Vorlage / Textauszug
Runbook: Google-Drive-Upload schlägt fehl
Symptom
Die Datei soll nach Google Drive kopiert werden, aber es wird keine Datei-ID oder kein Link zurückgegeben.
Prüfung
Prüfen, ob die lokale ZIP-Datei existiert.
Prüfen, ob der Zielordner korrekt ist.
Upload erneut mit expliziter Parent-Folder-ID durchführen.
Nach Upload auf `success: true`, `id`, `title` und `parent_id` achten.
Wenn keine Bestätigung kommt, lokale Datei als Download-Link bereitstellen.
Akzeptanz
Der Upload gilt nur als erfolgreich, wenn eine Drive-Datei-ID vorliegt.
Dieses Runbook ist aus dem tatsächlichen Projektverlauf entstanden. Beim ersten Versuch gab es keine sichere Bestätigung. Erst ein erneuter Upload mit explizitem Zielordner war sauber nachvollziehbar.
---
15. Übung
Erstelle eine eigene Abnahmeliste für das finale HTML-Paket. Die Liste soll mindestens zehn Prüfpunkte enthalten und zwischen Inhalt, Technik, Navigation, Mobile und ZIP unterscheiden.
---
16. Musterlösung
Vorlage / Textauszug
Inhalt:
Keine künstlichen Wiederholungsabsätze.
Keine generischen Titel wie Praxisdurchlauf oder integrierte Vertiefung.
Jedes Hauptkapitel enthält Fließtext, Beispiel, Fehleranalyse und Betriebssicht.
Technik:
HTML ist eine Single-File-Datei ohne externe Assets.
Codeblöcke sind dunkel, farbig und horizontal scrollbar.
SVGs sind inline eingebettet.
Navigation:
Sidebar verwendet details/summary.
Content-Kategorien sind standardmäßig geschlossen.
Ankerlinks führen zu existierenden IDs.
Mobile:
Datei bleibt auf iPhone/Safari lesbar.
Wichtige Inhalte sind nicht von JavaScript abhängig.
ZIP:
README, Markdown, HTML und Quality-Report sind enthalten.
ZIP wurde mit einem Testlauf geprüft.
Dateiname ist eindeutig und ohne final_fix_v2-Chaos.
---
17. Merksätze
Vorlage / Textauszug
Ein Delivery-Paket ist erst fertig, wenn es lesbar, prüfbar und nachvollziehbar ist.
Eine große HTML-Datei ist nur dann wertvoll, wenn die Größe durch echten Inhalt entsteht.
Der Quality-Report schützt vor Wiederholung alter Fehler.
Google Drive Upload gilt erst als erledigt, wenn eine Datei-ID vorliegt.
Saubere Dateinamen sind Teil der Qualität.
Abschluss, Übergabe und nächste Projektphase
1. Zweck dieses Abschlussteils
Dieser Teil beschreibt, wie das bisherige Markdown-Mastermaterial geordnet abgeschlossen, an eine spätere HTML-/PDF-Erzeugung übergeben und in eine nächste Projektphase überführt wird. Der Schwerpunkt liegt nicht mehr darauf, neue Fachthemen künstlich hinzuzufügen. Der Schwerpunkt liegt auf Übergabefähigkeit.
Ein Lernbuch dieser Größe wird schnell unübersichtlich, wenn es nur aus vielen einzelnen Dateien besteht. Deshalb braucht der Abschluss klare Regeln: Was gilt als fertig? Was darf später ergänzt werden? Was muss vor einer HTML-Erzeugung geprüft werden? Welche Dateien gehören in das finale Paket? Welche Qualitätsgrenzen verhindern, dass die spätere Ausgabe wieder künstlich aufgeblasen wird?
Die wichtigste Abschlussregel lautet:
Vorlage / Textauszug
Das Mastermaterial ist nur dann reif für HTML, wenn der fachliche Inhalt stabil ist.
HTML ist Ausgabeformat, nicht Ersatz für fehlende Qualität.
2. Übergabestatus der bisherigen Teile
Die bisherigen Teile bilden eine vollständige Grundlage für das Enterprise Platform Lab. Sie decken nicht nur eine Anwendung ab, sondern die gesamte Umgebung: Unternehmenskontext, Infrastruktur, Cloud, VM, Bare Metal, Kubernetes/OpenShift, Security, moderne Anwendungen, Daten, Messaging, Observability, Backup, DevOps, AI-Unterstützung, Beispielprojekt, Übungen, Begriffe, Qualitätsprüfung und finale Ausgabevorbereitung.
Damit ist die erste große Inhaltsphase abgeschlossen. Die Inhalte sind als Markdown-Dateien getrennt gespeichert. Das ist sinnvoll, weil einzelne Teile später unabhängig verbessert werden können, ohne das ganze Buch neu anfassen zu müssen.
Die aktuelle Materialsammlung besteht aus:
Vorlage / Textauszug
01 Unternehmenskontext und Zielbild
02 Infrastruktur-Fundament
03 Cloud-Architektur
04 VM- und Bare-Metal-Betrieb
05 Kubernetes- und OpenShift-Plattform
06 Identity, Security und Governance
07 Moderne Anwendungen
08 Daten, Messaging und Integration
09 Observability und Betrieb
10 Backup, Restore und Disaster Recovery
11 DevOps, GitOps und Release Management
12 Codex und Claude Code im Enterprise-Projekt
13 Komplettes Beispielprojekt
14 Übungen, Runbooks und Musterlösungen
15 Integrierte Begriffserklärungen und Fachindex
16 Qualitätsprüfung, Konsolidierung und HTML-Vorbereitung
17 Finale Markdown-Konsolidierung und Masterbuch-Aufbau
18 Finale HTML-Erzeugung aus Markdown
19 Finale Delivery-Struktur, ZIP und Abnahmeprüfung
20 Versionierung, Pflegeplan und Weiterentwicklung
21 Übergang von Markdown zum finalen HTML-Masterbuch
22 Finale HTML-Build-Vorlage und Generator-Regeln
23 Finale Abnahme vor der HTML-Erzeugung
24 Finale HTML-Erzeugung als Single-File-Masterbuch
25 Finale Master-HTML, README, Quality-Report und Drive-Ablage
26 Abschluss, Übergabe und nächste Projektphase
3. Was jetzt nicht mehr passieren darf
Nach so vielen Teilen ist die Versuchung groß, einfach weiter Kapitel anzuhängen. Genau das soll vermieden werden. Ab jetzt darf kein Inhalt mehr ergänzt werden, nur um die Datei größer wirken zu lassen.
Nicht mehr erlaubt sind:
Vorlage / Textauszug
künstliche Praxisdurchläufe mit Nummern
generische Vertiefungsblöcke
Anhänge ohne fachlichen Zweck
Tabellen als Ersatz für Erklärung
Glossarlisten als Hauptinhalt
wiederholte Absätze mit ausgetauschten Begriffen
HTML-Aufblähung durch Copy/Paste
Diagramme ohne Bezug zum Kapitel
Code ohne Einordnung
Erlaubt sind nur fachliche Ergänzungen, die eine konkrete Lücke schließen. Eine Ergänzung muss erklären, warum sie nötig ist, in welchen Teil sie gehört und welchen vorhandenen Abschnitt sie verbessert.
4. Übergabepaket für die nächste Phase
Das Übergabepaket soll nicht chaotisch wachsen. Es braucht eine feste Struktur:
Für die aktuelle Schritt-ZIP reicht weiterhin die einfache Struktur mit den Markdown-Dateien und einer README. Für die finale Ausgabephase wird daraus ein vollständiges Delivery-Paket mit HTML, PDF, Quality-Report und optionaler Google-Drive-Ablage.
5. Abnahme vor der finalen HTML-Erzeugung
Bevor HTML erzeugt wird, muss das Markdown-Material geprüft werden. Die Prüfung soll nicht nur technische Fehler suchen, sondern auch inhaltliche Schwächen erkennen.
Die wichtigsten Prüffragen sind:
Vorlage / Textauszug
Gibt es wiederholte Absätze?
Gibt es künstliche Serientitel?
Besteht ein Kapitel hauptsächlich aus Tabellen?
Sind Begriffe im Kontext erklärt?
Sind Praxisabschnitte in Fachkapitel integriert?
Sind Codebeispiele erklärt?
Sind Runbooks konkret genug?
Sind Übungen mit Musterlösungen vorhanden?
Sind Navigationstitel fachlich?
Wenn eine dieser Fragen negativ beantwortet wird, soll nicht sofort HTML gebaut werden. Dann muss zuerst das Markdown-Material korrigiert werden.
6. Qualitätsprüfung mit einfachem Musterkatalog
Für die nächste Phase wird ein Musterkatalog verwendet. Er enthält Begriffe und Formulierungen, die in der finalen HTML nicht vorkommen dürfen.
Vorlage / Textauszug
Praxisdurchlauf 1
Praxisdurchlauf 2
integrierte Vertiefung
Anhang 16
Entscheidung 2
Risiko 2
Warum das im Lab wichtig ist: klare Nachvollziehbarkeit
Bei Security, Hardening und Audit beginnt die Arbeit mit
Diese Muster sind nicht deshalb verboten, weil die Wörter grundsätzlich falsch wären. Sie sind verboten, weil sie im bisherigen Projekt als Hinweis auf künstlich generierten Fülltext aufgetreten sind.
Die finale Markdown-Konsolidierung darf nicht einfach alle Dateien aneinanderkleben. Sie muss Übergänge prüfen.
Beispiel: Teil 5 erklärt OpenShift, Teil 6 erklärt Security, Teil 7 erklärt moderne Anwendungen. In der finalen Fassung müssen diese Teile aufeinander aufbauen. Es sollte nicht so wirken, als wären drei separate Artikel nebeneinandergelegt worden.
Gute Übergänge sind zum Beispiel:
Vorlage / Textauszug
Nachdem die Plattformgrundlagen beschrieben wurden, wird im nächsten Teil erklärt, wie Identität und Security darauf aufbauen.
Oder:
Vorlage / Textauszug
Die vorherige Security-Sicht wird nun auf konkrete Anwendungen angewendet: Customer Portal, Order Service und Billing Service.
Solche Übergänge machen aus einer Sammlung ein Buch.
8. HTML-Zielzustand
Die finale HTML-Ausgabe soll eine einzige robuste Datei sein. Sie soll offline funktionieren, auf iPhone/Safari stabil sein und keine externen Assets benötigen.
Die technische Zielstruktur lautet:
Vorlage / Textauszug
Single HTML
Inline CSS
Inline SVG
native details/summary Navigation
Content-Kategorien standardmäßig geschlossen
Codeblöcke mit dunklem JetBrains-Dark-Prinzip
Copy-Button nur als Komfortfunktion
Suche nur als Komfortfunktion
keine Pflichtabhängigkeit von JavaScript
Wichtige Funktionen dürfen nicht davon abhängen, dass JavaScript perfekt funktioniert. Das war eine zentrale Lehre aus den früheren iPhone-/Safari-Problemen.
9. PDF-Zielzustand
Eine spätere PDF-Ausgabe muss andere Regeln erfüllen als HTML. PDF ist nicht interaktiv. Deshalb dürfen klappbare Bereiche nicht einfach geschlossen exportiert werden. Für PDF müssen alle Inhalte sichtbar sein.
PDF-Regeln:
Vorlage / Textauszug
alle Kapitel sichtbar
Inhaltsverzeichnis mit Hierarchie
Codeblöcke gut lesbar
dunkler Codehintergrund mit hohem Kontrast
keine abgeschnittenen langen Zeilen ohne Alternative
Diagramme sichtbar und eingebettet
Seitenumbrüche nicht mitten in Überschriften
Die PDF-Ausgabe darf nicht aus einer kaputten HTML-Ansicht erzeugt werden, bei der Inhalte eingeklappt bleiben.
10. Google-Drive-Ablage
Für die Drive-Ablage gilt: Nur geprüfte ZIPs sollen hochgeladen werden. Ein Upload ist erst abgeschlossen, wenn Drive eine Datei-ID und einen Link zurückgibt.
Ein erfolgreicher Upload muss mindestens dokumentieren:
Vorlage / Textauszug
Dateiname
Google-Drive-Datei-ID
Zielordner-ID
Upload-Zeitpunkt
lokale ZIP-Version
Damit lässt sich später nachvollziehen, welche Version tatsächlich abgelegt wurde.
11. Nächste Projektphase
Die nächste sinnvolle Projektphase ist nicht weiteres Schreiben, sondern Produktion der finalen Ausgabe.
Empfohlene Reihenfolge:
Vorlage / Textauszug
Alle Markdown-Dateien zu einem Master-Markdown konsolidieren
Wiederholungsprüfung durchführen
verbotene Muster prüfen
Master-Markdown korrigieren
Single-File-HTML erzeugen
HTML-Navigation prüfen
Codeblöcke prüfen
mobile Darstellung prüfen
ZIP mit HTML, MD, README und Quality-Report erzeugen
ZIP optional in Google Drive hochladen
Erst danach sollte über PDF nachgedacht werden. PDF wird besser, wenn die HTML- und Markdown-Grundlage stabil ist.
12. Übung
Erstelle eine eigene Abnahmeliste für das Projekt. Die Liste soll mindestens zehn Punkte enthalten und unterscheiden zwischen:
Vorlage / Textauszug
Inhalt
Technik
Navigation
Codeblöcke
Mobile Darstellung
Ablage
13. Musterlösung
Eine mögliche Abnahmeliste:
Vorlage / Textauszug
Alle Kapitel haben fachliche Überschriften.
Keine verbotenen Muster kommen vor.
Keine wiederholten Absätze mit nur ausgetauschten Begriffen kommen vor.
Tabellen sind nur ergänzend, nicht Hauptinhalt.
Codeblöcke sind farbig und lesbar.
SVGs sind inline eingebettet.
Navigation funktioniert mit nativen details/summary.
Content-Kategorien sind standardmäßig geschlossen.
HTML funktioniert ohne externe Assets.
README erklärt Startdatei und Paketinhalt.
Quality-Report dokumentiert Prüfungen.
ZIP lässt sich fehlerfrei entpacken.
Optionaler Drive-Upload liefert Datei-ID und Zielordner.
14. Abschlussmerksätze
Vorlage / Textauszug
Ein großes Lernbuch braucht nicht nur Umfang, sondern Struktur.
HTML ist erst dann sinnvoll, wenn der Inhalt sauber ist.
Qualitätsprüfung verhindert, dass frühere Generatorfehler zurückkommen.
Eine robuste Offline-HTML muss ohne externe Assets funktionieren.
Drive-Ablage ist erst bestätigt, wenn eine Datei-ID vorliegt.
Die nächste Phase ist die finale Ausgabeproduktion, nicht weiteres künstliches Anhängen.
Vorbereitung der finalen HTML-Erzeugung aus allen Markdown-Teilen
1. Ziel dieses Teils
Dieser Teil bereitet die finale HTML-Erzeugung praktisch vor. Bis hierher wurden die Inhalte bewusst als getrennte Markdown-Schritte aufgebaut. Das war wichtig, weil die vorherigen HTML-Fassungen zu stark durch automatische Wiederholung, künstliche Tabellen und generische Überschriften geprägt waren. Die neue Arbeitsweise trennt zuerst den fachlichen Inhalt von der späteren Darstellung.
Der nächste große Schritt ist nicht einfach „Markdown in HTML umwandeln“. Eine gute HTML-Ausgabe braucht eine saubere Konsolidierung. Dabei werden alle Markdown-Dateien in eine fachlich stabile Reihenfolge gebracht, Überschriften vereinheitlicht, Codeblöcke geprüft, interne Links vorbereitet und Qualitätsregeln angewendet. Erst danach darf die Single-File-HTML erzeugt werden.
Das Ziel lautet:
Vorlage / Textauszug
Aus vielen geprüften Markdown-Kapiteln entsteht ein robustes, offlinefähiges HTML-Masterbuch.
Dieses Masterbuch soll nicht wieder künstlich aufgeblasen werden. Umfang entsteht nur durch echten Inhalt, Beispiele, Erklärungen, Diagramme und Code.
---
2. Warum keine direkte Sofort-HTML-Erzeugung
Eine direkte Sofort-HTML-Erzeugung klingt praktisch, führt aber oft zu Fehlern. Wenn der Generator direkt HTML schreibt, entstehen schnell kaputte Navigationen, doppelte IDs, falsche Anker, uneinheitliche Codeblöcke oder überladene Abschnitte. Besonders bei iPhone/Safari und lokalen HTML-Dateien sind komplizierte JavaScript-Navigationen anfällig.
Deshalb wird die finale HTML-Datei nicht als neues Inhaltsprojekt betrachtet, sondern als Rendering des geprüften Markdown-Materials.
Die Regel lautet:
Vorlage / Textauszug
Markdown ist Quelle.
HTML ist Ausgabe.
ZIP ist Delivery.
Wenn später ein Fehler gefunden wird, wird nicht direkt wild in der HTML-Datei repariert. Stattdessen wird zuerst die Markdown-Quelle korrigiert und danach die HTML-Ausgabe neu erzeugt. Dadurch bleibt das Projekt wartbar.
---
3. Konsolidierungsreihenfolge
Die finale Zusammenführung verwendet eine feste Reihenfolge. Diese Reihenfolge folgt dem Lernpfad: zuerst Unternehmenskontext, dann Infrastruktur, dann Plattform, Anwendungen, Betrieb, Delivery und Übergabe.
Vorlage / Textauszug
01 Unternehmenskontext und Zielbild
02 Infrastruktur-Fundament
03 Cloud-Architektur
04 VM- und Bare-Metal-Betrieb
05 Kubernetes- und OpenShift-Plattform
06 Identity, Security und Governance
07 Moderne Anwendungen
08 Daten, Messaging und Integration
09 Observability und Betrieb
10 Backup, Restore und Disaster Recovery
11 DevOps, GitOps und Release Management
12 Codex und Claude Code im Enterprise-Projekt
13 Komplettes Beispielprojekt
14 Übungen, Runbooks und Musterlösungen
15 Integrierte Begriffserklärungen und Fachindex
16 Qualitätsprüfung, Konsolidierung und HTML-Vorbereitung
17 Finale Markdown-Konsolidierung und Masterbuch-Aufbau
18 Finale HTML-Erzeugung aus Markdown
19 Finale Delivery-Struktur, ZIP und Abnahmeprüfung
20 Versionierung, Pflegeplan und Weiterentwicklung
21 Übergang von Markdown zum finalen HTML-Masterbuch
22 Finale HTML-Build-Vorlage und Generator-Regeln
23 Finale Abnahme vor der HTML-Erzeugung
24 Finale HTML-Erzeugung als Single-File-Masterbuch
25 Finale Master-HTML, README, Quality-Report und Drive-Ablage
26 Abschluss, Übergabe und nächste Projektphase
27 Vorbereitung der finalen HTML-Erzeugung aus allen Markdown-Teilen
Diese Reihenfolge wird im finalen Inhaltsverzeichnis und in der Sidebar gespiegelt. Die Navigation darf keine technischen Dateinamen zeigen, sondern fachliche Titel.
---
4. Fachliche Kapitel statt technische Dateinamen
Im ZIP dürfen Dateinamen nummeriert sein, weil das Sortierung und Pflege erleichtert. In der HTML-Navigation sollen jedoch fachliche Namen stehen.
Nicht gut:
Vorlage / Textauszug
01_Teil_1_Unternehmenskontext_und_Zielbild.md
02_Teil_2_Infrastruktur_Fundament.md
Besser in der HTML-Navigation:
Vorlage / Textauszug
Unternehmenskontext und Zielbild
Infrastruktur-Fundament
Cloud-Architektur
VM- und Bare-Metal-Betrieb
Kubernetes- und OpenShift-Plattform
Die Dateinummern bleiben nur im ZIP sichtbar. Die Leserführung im HTML bleibt fachlich.
---
5. HTML-Struktur der finalen Ausgabe
Die finale HTML-Datei soll eine einfache, robuste Struktur verwenden.
Wichtig ist: Die Inhalte müssen auch ohne JavaScript erreichbar bleiben. JavaScript darf Copy-Buttons, Suche oder sanftes Öffnen von Zielbereichen verbessern, aber nicht die Grundfunktion tragen.
---
6. Navigation mit details/summary
Die Navigation wird mit nativen HTML-Elementen aufgebaut.
Alle Navigationsgruppen sind standardmäßig geschlossen. Der Leser öffnet nur den Bereich, den er braucht.
---
7. Content-Kategorien standardmäßig geschlossen
Auch der Hauptinhalt wird mit details/summary aufgebaut.
html
<details class=class="str">"chapter" id=class="str">"teil-05-kubernetes-und-openshift-plattform">
<summary>
<h2>Kubernetes- und OpenShift-Plattform</h2>
</summary>
<section>
<h3>Warum Kubernetes im Enterprise-Kontext wichtig ist</h3>
<p>...</p>
</section>
</details>
Diese Struktur vermeidet riesige Scrollwände. Das ist besonders wichtig bei einer großen HTML-Datei über 2 MB. Der Inhalt bleibt vollständig vorhanden, aber optisch kontrollierbar.
Wichtig: Der summary darf nicht mit komplexen Buttons verschachtelt werden. Native Interaktion bleibt stabiler.
---
8. Regeln für Überschriften und IDs
Jede Überschrift bekommt eine stabile ID. Die ID wird aus dem Titel erzeugt.
Beispiel:
Vorlage / Textauszug
Titel: Kubernetes- und OpenShift-Plattform
ID: teil-05-kubernetes-und-openshift-plattform
Regeln:
Skizze / Textauszug
- alles kleinschreiben
- Umlaute umwandeln: ä → ae, ö → oe, ü → ue, ß → ss
- Leerzeichen durch Bindestriche ersetzen
- Sonderzeichen entfernen
- doppelte Bindestriche reduzieren
- Nummer des Teils vorne behalten
Dadurch bleiben Links stabil und lesbar.
---
9. Codeblock-Regeln
Codeblöcke sind ein zentraler Bestandteil des Lernbuchs. Sie müssen lesbar, farbig und mobil nutzbar sein.
Der Copy-Button kann per JavaScript ergänzt werden, aber der Code selbst bleibt auch ohne Button lesbar.
---
10. SVG-Regeln
Diagramme werden inline eingebettet. Dadurch gibt es keine fehlenden Bilddateien im ZIP und keine kaputten relativen Pfade.
Beispiel:
html
<figure
class
=
class
="str">"diagram">
class="str">"
0
0
900
360
" role=
class
="str">"img" aria-labelledby=
class
="str">"arch-title">
class="str">"arch-title">Hybrid-Architektur
<figcaption>Vereinfachte Hybrid-Zielarchitektur</figcaption>
</figure>
Regeln:
Vorlage / Textauszug
SVG inline
keine externen Bilder
klare Beschriftungen
gute Lesbarkeit im hellen und dunklen Modus
nicht zu dekorativ
Diagramm muss fachlich helfen
---
11. Suchfunktion als Komfort
Die Suchfunktion darf die Nutzbarkeit verbessern, aber nicht notwendig sein. Wenn sie ausfällt, muss die Navigation trotzdem funktionieren.
Zulässige Komfortfunktionen:
Vorlage / Textauszug
Suchbegriff markieren
passende Kapitel öffnen
Trefferanzahl anzeigen
zum ersten Treffer springen
Nicht zulässig:
Vorlage / Textauszug
Inhalte nur über Suche sichtbar machen
Kapitel per JavaScript vollständig aus dem DOM entfernen
Navigation nur dynamisch erzeugen
Hash-Routing als Pflichtfunktion
Diese Regel kommt direkt aus den bisherigen iPhone-/Safari-Problemen.
---
12. Qualitätsprüfung vor dem HTML-Build
Vor dem finalen HTML-Build wird das Markdown-Material geprüft.
Prüfkriterien:
Vorlage / Textauszug
keine generischen Serientitel
keine Praxisdurchlauf-X-Blöcke
keine Anhang-X-Navigation
keine integrierte-Vertiefung-X-Titel
keine künstlichen Entscheidung-2/Risiko-2-Tabellen
keine stark wiederholten Absätze
keine leeren Kapitel
keine Kapitel, die nur aus Glossar bestehen
keine Kapitel, die nur aus Tabellen bestehen
Dazu wird ein kleiner Prüfbericht erzeugt.
---
13. Beispiel: Prüfskript gegen verbotene Muster
python
from pathlib import Path
base = Path(class="str">"mhepl_md_steps")
forbidden = [
class="str">"Praxisdurchlauf",
class="str">"integrierte Vertiefung",
class="str">"Anhang 16",
class="str">"Entscheidung 2",
class="str">"Entscheidung 3",
class="str">"Risiko 2",
class="str">"Risiko 3",
]
failed = []
for md in sorted(base.glob(class="str">"*.md")):
text = md.read_text(encoding=class="str">"utf-8")
for pattern in forbidden:
if pattern in text:
failed.append((md.name, pattern))
if failed:
print(class="str">"Verbotene Muster gefunden:")
for file, pattern in failed:
print(fclass="str">"- {file}: {pattern}")
raise SystemExit(1)
print(class="str">"OK: Keine verbotenen Muster gefunden.")
Dieses Skript ersetzt keine fachliche Prüfung, aber es verhindert bekannte Fehler.
---
14. Beispiel: Prüfung auf Absatzwiederholungen
python
from pathlib import Path
from collections import defaultdict
import re
base = Path(class="str">"mhepl_md_steps")
paragraphs = defaultdict(list)
for md in sorted(base.glob(class="str">"*.md")):
text = md.read_text(encoding=class="str">"utf-8")
raw_paragraphs = re.split(rclass="str">"\n\s*\n", text)
for p in raw_paragraphs:
normalized = re.sub(rclass="str">"\s+", class="str">" ", p.strip())
if len(normalized) > 280:
paragraphs[normalized].append(md.name)
duplicates = {
paragraph: files
for paragraph, files in paragraphs.items()
if len(files) > 1
}
if duplicates:
print(class="str">"Mögliche Wiederholungen gefunden:")
for paragraph, files in list(duplicates.items())[:20]:
print(class="str">"---")
print(files)
print(paragraph[:300])
raise SystemExit(1)
print(class="str">"OK: Keine langen identischen Absätze gefunden.")
Diese Prüfung ist bewusst streng. Sie soll verhindern, dass die finale HTML-Datei wieder durch Copy/Paste-Absätze aufgeblasen wird.
---
15. Build-Ausgabe
Die finale Build-Ausgabe soll später mindestens enthalten:
Das ZIP enthält also nicht nur die HTML-Datei, sondern auch die Quelle und den Qualitätsbericht.
---
16. Abnahmekriterien für den nächsten Schritt
Bevor die finale HTML wirklich erzeugt wird, müssen diese Punkte erfüllt sein:
Vorlage / Textauszug
Alle Markdown-Dateien sind im ZIP enthalten.
README beschreibt Struktur und Startpunkt.
Keine verbotenen Muster werden gefunden.
Keine langen identischen Absätze werden gefunden.
Codeblöcke sind sprachlich markiert.
Die spätere Navigation verwendet fachliche Namen.
Content-Kategorien werden standardmäßig geschlossen.
HTML bleibt offlinefähig.
SVGs werden inline erzeugt.
JavaScript bleibt Komfort, nicht Pflicht.
Wenn diese Punkte erfüllt sind, kann die finale HTML-Erzeugung sauber beginnen.
---
17. Übung
Beschreibe, warum es besser ist, zuerst Markdown-Dateien zu prüfen und erst danach HTML zu erzeugen.
Beantworte:
Vorlage / Textauszug
Welche Fehler werden dadurch vermieden?
Warum ist HTML als direkte Arbeitsquelle schwieriger?
Warum ist eine Single-File-HTML trotzdem als Ausgabe sinnvoll?
Welche Rolle spielt der Quality-Report?
---
18. Musterlösung
Eine mögliche Antwort:
Vorlage / Textauszug
Markdown ist als Quelle besser wartbar, weil Inhalte klar getrennt, einfacher vergleichbar und leichter prüfbar sind. Wiederholungen, verbotene Muster und leere Kapitel lassen sich in Markdown einfacher erkennen als in fertigem HTML.
HTML als direkte Arbeitsquelle ist schwieriger, weil Inhalt, Layout, Navigation, CSS und JavaScript vermischt werden. Kleine Reparaturen können dabei schnell neue Fehler erzeugen, zum Beispiel kaputte Navigation, doppelte IDs oder unlesbare Codeblöcke.
Eine Single-File-HTML ist trotzdem als Ausgabe sinnvoll, weil sie leicht weitergegeben werden kann, offline funktioniert und keine externen Assets benötigt. Sie sollte aber aus einer sauberen Quelle gebaut werden.
Der Quality-Report dokumentiert, welche Prüfungen durchgeführt wurden. Dadurch wird sichtbar, dass die Datei nicht nur erzeugt, sondern auch kontrolliert wurde.
---
19. Merksätze
Vorlage / Textauszug
Markdown ist die Quelle, HTML ist das Produkt.
Eine große HTML-Datei darf groß sein, aber nicht künstlich aufgeblasen.
Navigation muss robust sein, nicht spektakulär.
Qualität entsteht vor dem Build, nicht durch nachträgliches Reparieren.
Ein gutes Delivery-Paket enthält Quelle, Ausgabe, README und Qualitätsbericht.
Finale HTML-Erzeugung praktisch durchführen
1. Ziel dieses Teils
In den vorherigen Teilen wurde festgelegt, wie die finale HTML-Ausgabe aussehen soll. Dieser Teil beschreibt nun den praktischen Ablauf: Aus den vorhandenen Markdown-Dateien wird ein einziges robustes HTML-Masterbuch erzeugt. Dabei bleibt die Markdown-Sammlung weiterhin die Quelle der Wahrheit. Die HTML-Datei ist die lesbare Auslieferungsform für Browser, iPhone, iPad und Desktop.
Der wichtigste Grundsatz lautet:
Vorlage / Textauszug
Markdown bleibt fachliche Quelle.
HTML ist eine abgeleitete Ausgabe.
Wenn später Inhalt geändert wird, wird zuerst Markdown geändert und danach HTML neu erzeugt.
Dadurch vermeiden wir, dass Inhalte in mehreren Versionen auseinanderlaufen. Besonders bei großen Lernbüchern entsteht sonst schnell Chaos: eine korrigierte Markdown-Datei, eine ältere HTML-Datei, ein halbfertiges PDF und ein ZIP mit falschem Stand. Die finale Pipeline verhindert genau das.
---
2. Eingangsdateien
Die finale HTML-Erzeugung verwendet alle Markdown-Teile in numerischer Reihenfolge.
Die Reihenfolge ist wichtig, weil die Navigation später daraus aufgebaut wird. Dateinamen dienen dabei nur als technische Sortierung. In der HTML-Navigation sollen fachliche Titel stehen, nicht rohe Dateinamen.
Jeder Schritt hat einen Zweck. Die Pipeline soll nicht nur HTML erzeugen, sondern auch verhindern, dass frühere Qualitätsprobleme wieder auftreten: künstliche Wiederholungen, generische Überschriften, kaputte Navigation oder Inhalte, die hauptsächlich aus Glossar und Tabellen bestehen.
Alle CSS-Regeln, kleinen Komfort-Skripte und SVGs liegen direkt in der Datei. Dadurch gibt es keine fehlenden Assets, keine CDN-Abhängigkeiten und keine kaputten relativen Pfade.
---
5. Robuste Navigation
Die Navigation wird mit nativen HTML-Elementen gebaut.
Der Vorteil: Diese Navigation funktioniert auch ohne JavaScript. Besonders auf iPhone/Safari ist das wichtig, weil lokale HTML-Dateien je nach Öffnungsweg JavaScript-Funktionen unzuverlässig ausführen können.
JavaScript darf nur Komfort bieten, zum Beispiel:
Vorlage / Textauszug
Zielbereich beim Anklicken automatisch öffnen
Suchtreffer markieren
Copy-Button für Codeblöcke
Es darf aber nicht notwendig sein, damit der Inhalt überhaupt lesbar ist.
---
6. Content-Kategorien standardmäßig geschlossen
Auch im Hauptinhalt werden die großen Teile als details dargestellt.
Standardmäßig bleiben die Kategorien geschlossen. Der Leser öffnet gezielt den Teil, den er braucht. Das ist bei einer großen HTML-Datei wichtig, weil sonst eine sehr lange Seite entsteht.
Trotzdem muss der Inhalt per Suche und Ankerlink erreichbar bleiben. Wenn ein Link auf einen geschlossenen Bereich zeigt, kann JavaScript den Bereich zusätzlich öffnen. Ohne JavaScript kann der Benutzer den Bereich manuell öffnen.
---
7. ID-Regeln für Ankerlinks
Jede Überschrift bekommt eine stabile ID.
Beispiel:
Vorlage / Textauszug
Teil 8: Daten, Messaging und Integration
wird zu:
Vorlage / Textauszug
teil-8-daten-messaging-und-integration
Regeln:
Vorlage / Textauszug
alles klein schreiben
Umlaute umwandeln
Sonderzeichen entfernen
Leerzeichen durch Bindestriche ersetzen
doppelte IDs mit Suffix eindeutig machen
Doppelte IDs sind gefährlich. Wenn zwei Abschnitte dieselbe ID haben, springt der Browser möglicherweise zur falschen Stelle. Deshalb muss der Build doppelte IDs erkennen und korrigieren.
---
8. Codeblock-Darstellung
Codeblöcke sind ein Kernbestandteil des Lernbuchs. Sie müssen gut lesbar sein.
Die farbliche Darstellung kann CSS-basiert erfolgen. Für eine robuste Offline-Datei wird keine externe Highlighting-Bibliothek verwendet.
---
9. Beispiel: einfacher HTML-Generator in Python
Der Generator darf nicht versuchen, fachlichen Inhalt zu erfinden. Er darf nur vorhandenes Markdown technisch umwandeln.
python
from pathlib import Path
import html
import re
SOURCE_DIR = Path(class="str">"mhepl_md_steps")
OUTPUT = Path(class="str">"Modern_Hybrid_Enterprise_Platform_Lab_MASTER.html")
def slugify(text: str) -> str:
replacements = {
class="str">"ä": class="str">"ae", class="str">"ö": class="str">"oe", class="str">"ü": class="str">"ue", class="str">"ß": class="str">"ss",
class="str">"Ä": class="str">"ae", class="str">"Ö": class="str">"oe", class="str">"Ü": class="str">"ue",
}
for source, target in replacements.items():
text = text.replace(source, target)
text = text.lower()
text = re.sub(rclass="str">"[^a-z0-9]+", class="str">"-", text)
return text.strip(class="str">"-")
def read_parts() -> list[Path]:
return sorted(SOURCE_DIR.glob(class="str">"[0-9][0-9]_Teil_*.md"))
def extract_title(markdown: str) -> str:
for line in markdown.splitlines():
if line.startswith(class="str">"# "):
return line[2:].strip()
returnclass="str">"Ohne Titel"
def escape_text(value: str) -> str:
return html.escape(value, quote=False)
Dieses Beispiel ist bewusst klein. Es zeigt: Der Generator sammelt, sortiert, benennt und escaped. Er ersetzt keine fachliche Redaktion.
---
10. Prüfung gegen verbotene Muster
Vor dem HTML-Build muss geprüft werden, ob verbotene Muster vorkommen.
python
FORBIDDEN_PATTERNS = [
class="str">"Praxisdurchlauf",
class="str">"integrierte Vertiefung",
class="str">"Anhang 16",
class="str">"Entscheidung 2",
class="str">"Entscheidung 3",
class="str">"Risiko 2",
class="str">"Risiko 3",
]
def check_forbidden_patterns(text: str) -> list[str]:
hits = []
for pattern in FORBIDDEN_PATTERNS:
if pattern.lower() in text.lower():
hits.append(pattern)
return hits
Wenn Treffer gefunden werden, darf die HTML-Datei nicht als final gelten. Der Build kann zwar technisch erzeugt werden, aber der Quality-Report muss den Status auf „nicht abgenommen“ setzen.
---
11. Prüfung gegen Wiederholungen
Die frühere schlechte Version hatte viele nahezu gleiche Absätze. Deshalb braucht der neue Prozess eine Wiederholungsprüfung.
Eine einfache Prüfung kann Absätze normalisieren und zählen.
python
from collections import Counter
def normalize_paragraph(paragraph: str) -> str:
paragraph = paragraph.lower()
paragraph = re.sub(rclass="str">"\s+", class="str">" ", paragraph)
paragraph = re.sub(rclass="str">"\b\d+\b", class="str">"<num>", paragraph)
return paragraph.strip()
def find_repeated_paragraphs(text: str, min_length: int = 180) -> list[tuple[str, int]]:
paragraphs = [p.strip() for p in text.split(class="str">"\n\n")]
normalized = [normalize_paragraph(p) for p in paragraphs if len(p) >= min_length]
counts = Counter(normalized)
return [(paragraph, count) for paragraph, count in counts.items() if count > 1]
Diese Prüfung ersetzt keine menschliche Qualitätskontrolle. Sie erkennt aber typische Generatorfehler schnell.
---
12. Prüfung gegen tabellenlastigen Inhalt
Tabellen sind erlaubt, aber sie dürfen nicht den Hauptinhalt ersetzen. Eine einfache Kennzahl ist das Verhältnis von Tabellenzeilen zu normalen Absätzen.
python
def table_line_ratio(text: str) -> float:
lines = [line for line in text.splitlines() if line.strip()]
if not lines:
return0.0
table_lines = [line for line in lines if line.strip().startswith(class="str">"|")]
return len(table_lines) / len(lines)
Wenn der Anteil sehr hoch ist, muss geprüft werden, ob der Teil wirklich als Lernbuch lesbar ist oder nur aus Listen und Tabellen besteht.
So bleibt die Ausgabe nachvollziehbar. Die HTML-Datei ist bequem zum Lesen. Die Markdown-Dateien bleiben bearbeitbar. Der Quality-Report dokumentiert die Prüfung.
---
15. Typische Fehler beim finalen Build
Ein häufiger Fehler ist, die HTML-Datei manuell zu bearbeiten. Dadurch stimmt sie nicht mehr mit Markdown überein. Besser ist: Markdown ändern, Build neu ausführen.
Ein zweiter Fehler ist, CSS oder JavaScript aus externen Quellen einzubinden. Das macht die Datei abhängig von Internetverbindung und CDN-Verfügbarkeit.
Ein dritter Fehler ist, die Navigation durch komplexes JavaScript zu steuern. Wenn JavaScript auf iPhone oder bei lokalen Dateien nicht sauber läuft, wirkt die ganze Datei defekt. Native details/summary ist stabiler.
Ein vierter Fehler ist, Inhalte künstlich aufzublasen, um eine Dateigröße zu erreichen. Die Dateigröße darf nur durch echten Inhalt entstehen.
Ein fünfter Fehler ist, Markdown-Codeblöcke unescaped in HTML zu schreiben. Dann können Zeichen wie <, > oder & die HTML-Struktur beschädigen.
---
16. Übung
Entwirf eine eigene Build-Checkliste für die finale HTML-Ausgabe.
Die Checkliste soll enthalten:
Vorlage / Textauszug
Prüfung der Markdown-Dateien
Prüfung der verbotenen Muster
Prüfung der Navigation
Prüfung der Codeblöcke
Prüfung der mobilen Nutzbarkeit
Prüfung der ZIP-Struktur
Prüfung des Quality-Reports
---
17. Musterlösung
Vorlage / Textauszug
Vor dem Build werden alle Markdown-Dateien numerisch sortiert und auf Vollständigkeit geprüft. Danach wird der gesamte Text gegen verbotene Muster wie Praxisdurchlauf, integrierte Vertiefung und Anhang 16 geprüft.
Anschließend wird geprüft, ob Absätze mehrfach vorkommen. Auffällige Wiederholungen müssen redaktionell bewertet werden. Danach wird die HTML-Datei erzeugt.
Die Navigation wird im Browser getestet. Alle Hauptteile müssen standardmäßig geschlossen sein und sich über details/summary öffnen lassen. Ankerlinks müssen zur richtigen Stelle springen.
Codeblöcke werden auf Lesbarkeit geprüft. Sie brauchen dunklen Hintergrund, ausreichenden Kontrast und horizontales Scrollen.
Auf dem iPhone wird geprüft, ob die Datei ohne externe Ressourcen lesbar ist. JavaScript darf nur Komfort bieten.
Zum Schluss wird das ZIP geöffnet und geprüft, ob HTML, Markdown, README, CHANGELOG und Quality-Report enthalten sind.
---
18. Merksätze
Vorlage / Textauszug
Der HTML-Build darf kein Autor sein.
Er darf nur vorhandenes Fachmaterial sauber ausliefern.
Markdown ist die Quelle der Wahrheit.
HTML ist die lesbare Ausgabe.
Robuste Navigation ist wichtiger als optisch komplexe Navigation.
Eine große Datei ist nur dann gut, wenn der Inhalt wirklich fachlich stark ist.
Quality-Reports verhindern, dass alte Fehler unbemerkt zurückkommen.
Erstellung des finalen Single-File-HTML-Masterbuchs
1. Ziel dieses Teils
Nachdem die Markdown-Teile einzeln aufgebaut, geprüft und in mehreren Schritten gegen künstliche Wiederholungen abgesichert wurden, geht es jetzt um den eigentlichen Übergang zum finalen HTML-Masterbuch. Dieser Teil beschreibt nicht nur, dass HTML erzeugt werden soll, sondern wie die Erzeugung kontrolliert, nachvollziehbar und reproduzierbar ablaufen muss.
Das Ziel ist eine einzelne HTML-Datei, die auf Desktop, Tablet und iPhone lesbar bleibt. Die Datei soll ohne externe Bibliotheken funktionieren. Sie soll keine CDN-Abhängigkeiten haben, keine fehlenden Bilddateien referenzieren und keine Navigation verwenden, die nur durch JavaScript bedienbar ist. JavaScript darf Komfort liefern, aber der Inhalt muss auch ohne JavaScript erreichbar bleiben.
Das finale HTML-Masterbuch ist damit kein zufälliger Export. Es ist ein bewusst gebautes Artefakt mit klarer Struktur:
Dieser Ablauf schützt vor den Fehlern, die in früheren Fassungen aufgetreten sind: kaputte Navigation, künstlich aufgeblasene Inhalte, Tabellen als Hauptinhalt, generische Titel und wiederholte Absätze mit nur ausgetauschten Schlagworten.
---
2. Unterschied zwischen Markdown-Quelle und HTML-Ausgabe
Die Markdown-Dateien bleiben die fachliche Quelle. Sie sind leicht lesbar, versionierbar und können einzeln gepflegt werden. Das HTML ist die nutzerfreundliche Leseausgabe. Es bekommt Navigation, Design, Codeblock-Darstellung, Suchfeld, mobile Optimierung und inline SVGs.
Die wichtigste Regel lautet:
Vorlage / Textauszug
Inhalt wird in Markdown gepflegt.
Darstellung wird im HTML gelöst.
Das bedeutet: Die Markdown-Dateien dürfen keine HTML-Tricks enthalten, die später die Darstellung zerstören. Umgekehrt darf die HTML-Erzeugung keine neuen fachlichen Inhalte erfinden. Sie darf Inhalte strukturieren, aber nicht künstlich erweitern.
Wenn später ein Kapitel verbessert wird, wird zuerst die passende .md-Datei geändert. Danach wird das HTML neu gebaut. Dadurch bleibt die Quelle sauber.
---
3. Zielstruktur der finalen HTML-Datei
Die finale HTML-Datei besteht aus vier großen Bereichen.
Vorlage / Textauszug
Kopfbereich
Seitenleiste mit Navigation
Hauptbereich mit Kapiteln
eingebettete Hilfslogik und Styles
Der Kopfbereich enthält Titel, Projektbeschreibung, Versionshinweis und Suchfeld. Die Seitenleiste enthält die Navigation. Der Hauptbereich enthält die eigentlichen Kapitel. Styles und kleine Komfortfunktionen werden direkt in die Datei eingebettet.
Die Datei darf keine externen CSS- oder JavaScript-Dateien benötigen.
Dadurch kann die HTML-Datei lokal geöffnet, verschoben, gezippt und weitergegeben werden, ohne dass Assets fehlen.
---
4. Navigation mit nativen HTML-Elementen
Die Navigation muss robust sein. Deshalb wird sie mit details und summary gebaut. Diese Elemente funktionieren in modernen Browsern ohne eigenes JavaScript. Sie sind besonders sinnvoll für lokale HTML-Dateien auf iPhone und Safari, weil dort komplexe JavaScript-Navigationen oft fehleranfällig sind.
Wichtig: Die Navigation ist standardmäßig geschlossen. Das hält die Oberfläche kompakt. Der Nutzer öffnet nur den Bereich, den er gerade braucht.
Keine Navigationseinträge dürfen generisch heißen:
Vorlage / Textauszug
Anhang 16
Praxisdurchlauf 4
integrierte Vertiefung 7
Abschnitt 12
Stattdessen muss jeder Eintrag fachlich benannt sein:
Vorlage / Textauszug
OpenShift Namespace-Strategie
Outbox Backlog analysieren
Keycloak Rollenmodell
PostgreSQL Restore-Test
Argo CD Rollback
---
5. Content-Kategorien standardmäßig geschlossen
Nicht nur die Navigation, sondern auch der Hauptinhalt wird mit klappbaren Bereichen organisiert. Dadurch bleibt eine große HTML-Datei auf mobilen Geräten bedienbar.
Dabei ist wichtig: Im summary steht eine echte Überschrift. Der Bereich ist ohne open-Attribut standardmäßig geschlossen.
Nicht empfohlen:
html
<details open>
Empfohlen:
html
<details class=class="str">"chapter">
So bleibt die Seite beim Öffnen übersichtlich.
---
6. Stabile Ankerlinks
Jedes Kapitel und jeder wichtige Unterabschnitt bekommt eine stabile ID. Diese IDs dürfen nicht automatisch aus dem kompletten Titel mit Sonderzeichen erzeugt werden, weil dadurch fehlerhafte Links entstehen können.
Besser ist eine kontrollierte Slug-Strategie:
Skizze / Textauszug
Teil 5: Kubernetes- und OpenShift-Plattform
→ teil-5-kubernetes-und-openshift-plattform
ServiceMonitor und PrometheusRule
→ teil-9-servicemonitor-und-prometheusrule
Runbook: Outbox Backlog
→ teil-13-runbook-outbox-backlog
Ein Link ist nur gültig, wenn genau eine passende Ziel-ID existiert. Deshalb muss die HTML-Erzeugung nach dem Build prüfen:
Vorlage / Textauszug
Jeder href=class="str">"#..." zeigt auf eine vorhandene ID.
Keine ID kommt doppelt vor.
Keine Navigation zeigt auf einen gelöschten Abschnitt.
Ein einfaches Prüfskript kann diese Fehler finden, bevor die Datei verteilt wird.
---
7. Codeblöcke nach JetBrains-Dark-Prinzip
Die Codeblöcke müssen gut lesbar sein. Der Nutzer hatte mehrfach bemängelt, dass Codebereiche zu hell, zu grau oder nicht farbig genug waren. Deshalb wird ein einheitliches dunkles Codeblock-Design verwendet.
Der Copy-Button ist nur Komfort. Wenn JavaScript nicht funktioniert, bleibt der Code trotzdem lesbar.
---
8. Inline-SVG statt externe Bilder
Alle Diagramme werden inline eingebettet. Das verhindert fehlende Bilddateien im ZIP.
Beispiel für ein einfaches Zielarchitektur-SVG:
html
class=
class
="str">"diagram" viewBox=
class
="str">"
0
0
900
360
" role=
class
="str">"img" aria-label=
class
="str">"Hybrid Enterprise Zielarchitektur">
class="str">"
30
" y=
class
="str">"
40
" width=
class
="str">"
180
" height=
class
="str">"
70
" rx=
class
="str">"
14
">
class="str">"
120
" y=
class
="str">"
82
" text-anchor=
class
="str">"middle">Customer Portal
class="str">"
330
" y=
class
="str">"
40
" width=
class
="str">"
200
" height=
class
="str">"
70
" rx=
class
="str">"
14
">
class="str">"
430
" y=
class
="str">"
82
" text-anchor=
class
="str">"middle">OpenShift APIs
class="str">"
660
" y=
class
="str">"
40
" width=
class
="str">"
190
" height=
class
="str">"
70
" rx=
class
="str">"
14
">
class="str">"
755
" y=
class
="str">"
82
" text-anchor=
class
="str">"middle">PostgreSQL
class="str">"
210
" y1=
class
="str">"
75
" x2=
class
="str">"
330
" y2=
class
="str">"
75
">
class="str">"
530
" y1=
class
="str">"
75
" x2=
class
="str">"
660
" y2=
class
="str">"
75
">
Die SVGs sollen nicht dekorativ sein. Sie müssen fachlich helfen. Gute Diagramme zeigen:
Vorlage / Textauszug
Systemgrenzen
Datenflüsse
Sicherheitszonen
Deployment-Flüsse
Backup-/Restore-Flüsse
Observability-Flüsse
Ein Diagramm pro großem Hauptteil ist sinnvoller als viele kleine Deko-Grafiken.
---
9. Suchfunktion als Komfort, nicht als Pflicht
Eine Suchfunktion ist nützlich, aber sie darf nicht die einzige Möglichkeit sein, Inhalte zu finden. Navigation und Überschriften müssen auch ohne Suche funktionieren.
Eine robuste Suchfunktion kann so arbeiten:
javascript
function searchContent(term) {
const normalized = term.trim().toLowerCase();
document.querySelectorAll(class="str">'.search-hit').forEach(el => el.classList.remove(class="str">'search-hit'));
if (!normalized) return;
document.querySelectorAll(class="str">'main section, main details.chapter').forEach(el => {
const text = el.textContent.toLowerCase();
if (text.includes(normalized)) {
el.classList.add(class="str">'search-hit');
const parent = el.closest(class="str">'details');
if (parent) parent.open = true;
}
});
}
Wenn JavaScript nicht läuft, bleibt die Seite trotzdem nutzbar. Der Nutzer kann die Browser-Suche verwenden.
---
10. Qualitätsprüfung vor dem HTML-Build
Vor der HTML-Erzeugung muss geprüft werden, ob die Markdown-Dateien verbotene Muster enthalten.
Verbotene Muster:
Vorlage / Textauszug
Praxisdurchlauf
integrierte Vertiefung
Anhang 16
Entscheidung 2
Risiko 3
Warum das im Lab wichtig ist: klare Nachvollziehbarkeit und reproduzierbare Umsetzung
Prüfskript:
python
from pathlib import Path
root = Path(class="str">"mhepl_md_steps")
forbidden = [
class="str">"Praxisdurchlauf",
class="str">"integrierte Vertiefung",
class="str">"Anhang 16",
class="str">"Entscheidung 2",
class="str">"Risiko 3",
class="str">"Warum das im Lab wichtig ist: klare Nachvollziehbarkeit und reproduzierbare Umsetzung",
]
failed = False
for file in sorted(root.glob(class="str">"*.md")):
text = file.read_text(encoding=class="str">"utf-8")
for pattern in forbidden:
if pattern in text:
print(fclass="str">"FEHLER: {pattern} in {file}")
failed = True
if failed:
raise SystemExit(1)
print(class="str">"OK: Keine verbotenen Muster gefunden.")
Diese Prüfung verhindert, dass alte Fehler wieder in die finale Ausgabe gelangen.
---
11. Prüfung gegen Absatzwiederholungen
Zusätzlich wird geprüft, ob identische Absätze mehrfach vorkommen. Nicht jede Wiederholung ist falsch, aber lange identische Absätze deuten auf künstliche Generierung hin.
Ein einfacher Ansatz:
python
from pathlib import Path
from collections import Counter
import re
root = Path(class="str">"mhepl_md_steps")
paragraphs = []
for file in sorted(root.glob(class="str">"*.md")):
text = file.read_text(encoding=class="str">"utf-8")
blocks = re.split(rclass="str">"\n\s*\n", text)
for block in blocks:
clean = class="str">" ".join(block.split())
if len(clean) > 180:
paragraphs.append(clean)
counter = Counter(paragraphs)
for paragraph, count in counter.items():
if count > 1:
print(class="str">"DOPPELTER ABSATZ", count, paragraph[:160])
Diese Prüfung soll nicht jeden wiederkehrenden Merksatz verbieten. Sie soll große Copy/Paste-Blöcke sichtbar machen.
---
12. Build-Reihenfolge
Die finale HTML-Erzeugung folgt dieser Reihenfolge:
Vorlage / Textauszug
alle Markdown-Dateien nach Nummer sortieren
README ausnehmen oder separat behandeln
Überschriften analysieren
Kapitelstruktur erzeugen
Navigation aus echten Überschriften erzeugen
Markdown in HTML umwandeln
Codeblöcke in Code-Cards umwandeln
Diagramme inline einfügen
Ankerlinks prüfen
verbotene Muster prüfen
Wiederholungen prüfen
HTML-Dateigröße prüfen
ZIP mit HTML, Markdown, README und Quality-Report erzeugen
Wichtig: Wenn die HTML-Datei zu klein ist, darf sie nicht künstlich aufgeblasen werden. Stattdessen muss fachlicher Inhalt ergänzt werden. Umfang entsteht durch Substanz, nicht durch Wiederholung.
Der Quality-Report dokumentiert, was geprüft wurde.
Vorlage / Textauszug
Quality Report
Datei
Modern_Hybrid_Enterprise_Platform_Lab_MASTER.html
Strukturprüfung
Navigation mit details/summary: OK
Content-Kategorien standardmäßig geschlossen: OK
keine externen Assets: OK
inline SVGs vorhanden: OK
Codeblöcke vorhanden: OK
Musterprüfung
keine Praxisdurchlauf-Titel: OK
keine integrierte Vertiefung-Titel: OK
keine Anhang-Nummerntitel: OK
keine künstlichen Entscheidung/Risiko-Tabellen: OK
Wiederholungsprüfung
keine langen identischen Absätze über Schwellwert: OK
Mobile Prüfung
Codeblöcke horizontal scrollbar: OK
Navigation ohne JavaScript nutzbar: OK
Hauptbereiche klappbar: OK
Der Bericht ist wichtig, weil er nicht nur behauptet, dass die Datei gut ist, sondern die Prüfung dokumentiert.
---
15. Typische Fehler bei der finalen HTML-Erzeugung
Ein häufiger Fehler ist, die Navigation aus Dateinamen statt aus fachlichen Überschriften zu erzeugen. Dann entstehen technische oder unlesbare Einträge.
Ein zweiter Fehler ist, alle Kapitel standardmäßig geöffnet auszugeben. Bei großen Dateien führt das auf mobilen Geräten zu einer kaum bedienbaren Wand aus Text.
Ein dritter Fehler ist, Codeblöcke ohne horizontales Scrollen darzustellen. Dann sprengen lange Java- oder YAML-Zeilen das Layout.
Ein vierter Fehler ist, Mermaid-Code als Diagramm zu erwarten, obwohl in einer lokalen HTML ohne externe Library kein Mermaid gerendert wird. Wenn Mermaid ohne Library eingebettet wird, sieht der Nutzer nur Code. Für die finale HTML sind deshalb inline SVGs stabiler.
Ein fünfter Fehler ist, beim Build neue Füllinhalte zu erzeugen. Der Build darf formatieren, aber nicht fachlich erfinden.
---
16. Übung
Entwerfe eine finale HTML-Abnahmeliste für dieses Projekt. Die Liste soll mindestens zehn Punkte enthalten und prüfen, ob die Datei wirklich benutzbar ist.
Berücksichtige:
Vorlage / Textauszug
Navigation
Content-Klappbarkeit
Codeblöcke
SVGs
mobile Lesbarkeit
verbotene Muster
Wiederholungen
ZIP-Struktur
README
Quality-Report
---
17. Musterlösung
Eine mögliche Abnahmeliste:
Vorlage / Textauszug
Die HTML-Datei öffnet lokal ohne Server.
Die Navigation ist mit nativen details/summary-Elementen klappbar.
Alle Navigationslinks zeigen auf vorhandene IDs.
Alle Hauptkapitel sind standardmäßig geschlossen.
Codeblöcke haben dunklen Hintergrund, gute Lesbarkeit und horizontales Scrollen.
Copy-Buttons sind nur Komfort und blockieren nicht die Lesbarkeit.
SVG-Diagramme sind inline eingebettet und benötigen keine externen Dateien.
Die HTML-Datei enthält keine generischen Titel wie Praxisdurchlauf oder integrierte Vertiefung.
Die HTML-Datei enthält keine künstlichen Entscheidung/Risiko-Fülltabellen.
Die Wiederholungsprüfung meldet keine langen identischen Absätze.
Die README erklärt Startdatei, Inhalt und Nutzung.
Der Quality-Report dokumentiert Prüfungen und Ergebnis.
Das ZIP enthält HTML, Master-Markdown, Einzelschritte, README, CHANGELOG und Quality-Report.
Die Datei ist auf Desktop und iPhone lesbar.
Die Browser-Suche funktioniert auch ohne eigenes JavaScript.
Diese Liste ist bewusst praktisch. Sie prüft nicht nur technische Korrektheit, sondern auch Nutzbarkeit.
---
18. Merksätze
Vorlage / Textauszug
Das finale HTML ist eine Leseausgabe, nicht die fachliche Quelle.
Markdown bleibt die pflegbare Wahrheit.
Navigation muss ohne JavaScript nutzbar sein.
Große HTML-Dateien brauchen geschlossene Kapitelbereiche.
Codeblöcke müssen lesbar, farbig und horizontal scrollbar sein.
SVGs werden inline eingebettet, damit keine Assets fehlen.
Umfang darf nur durch echten Inhalt entstehen.
Ein Quality-Report schützt vor wiederholten alten Fehlern.
Großer Schritt – Finaler Buildlauf, Master-Markdown und HTML-Abnahme
1. Ziel dieses großen Schritts
Dieser Schritt ist bewusst größer als die vorherigen Einzelteile. Bisher wurden die Inhalte kapitelweise aufgebaut: Unternehmenskontext, Infrastruktur, Cloud, VM und Bare Metal, OpenShift, Security, Anwendungen, Daten, Betrieb, Backup, DevOps, AI-Unterstützung, Beispielprojekt, Übungen, Begriffe und mehrere Abnahmeregeln. Jetzt wird daraus ein zusammenhängender Buildlauf gedacht.
Der Zweck dieses Schritts ist nicht, noch ein weiteres loses Kapitel anzuhängen. Der Zweck ist, die bisherige Arbeit in eine belastbare Übergabeform zu bringen. Das bedeutet: Die Markdown-Dateien bleiben die Quelle. Daraus entsteht ein Master-Markdown. Aus dem Master-Markdown kann später eine Single-File-HTML entstehen. Jede Ausgabe wird gegen Qualitätsregeln geprüft, bevor sie als Version akzeptiert wird.
Wichtig ist dabei eine klare Grenze:
Vorlage / Textauszug
Quelle: Markdown-Dateien je Teil
Konsolidierung: Master-Markdown
Ausgabe: Single-File-HTML
Nachweis: Quality-Report
Archiv: ZIP-Paket
Die Quelle darf nicht durch eine zufällige HTML-Reparatur ersetzt werden. Wenn später im HTML etwas falsch ist, wird nicht wild im HTML geflickt. Stattdessen wird die passende Markdown-Quelle verbessert und danach erneut gebaut.
---
2. Warum dieser Schritt notwendig ist
Die vorherigen schlechten HTML-Versionen hatten ein wiederkehrendes Problem: Sie wurden größer gemacht, ohne fachlich besser zu werden. Dadurch entstanden Tabellen mit ähnlichen Zeilen, generische Überschriften, wiederholte Absätze und künstliche Praxisblöcke. Die Datei war groß, aber der Inhalt war nicht wirklich ein Fachbuch.
Ein sauberes Buildmodell verhindert genau das. Es trennt drei Aufgaben voneinander:
Vorlage / Textauszug
Fachinhalt schreiben
Ausgabeformat erzeugen
Qualität prüfen
Wenn diese drei Aufgaben vermischt werden, entstehen typische Fehler:
Vorlage / Textauszug
HTML wird repariert, aber Markdown bleibt falsch.
Navigation wird korrigiert, aber Content wird beschädigt.
Inhalt wird aufgeblasen, aber Wiederholungen bleiben drin.
Tabellen werden erzeugt, obwohl Fließtext benötigt wird.
Glossar wird separat angehängt, obwohl Begriffe im Kontext erklärt werden sollen.
Der neue Ablauf ist strenger. Jede spätere HTML-Datei muss aus dem Master-Markdown nachvollziehbar erzeugt werden. Jede Änderung muss in der Quelle landen. Jede Ausgabe bekommt einen Quality-Report.
---
3. Zielstruktur des finalen Delivery-Pakets
Das finale Paket soll nicht aus vielen unklaren Dateinamen bestehen. Es soll eine klare Struktur haben.
Für die laufenden Zwischenschritte reicht weiterhin das ZIP mit allen Markdown-Dateien. Für die finale Version wird aber zusätzlich eine Delivery-Struktur erzeugt. Diese Trennung hilft, weil man jederzeit weiß, was Quelle, was Ausgabe und was Werkzeug ist.
---
4. Master-Markdown: Konsolidierung ohne Informationsverlust
Der Master-Markdown ist eine einzige große Markdown-Datei, die alle Teile in der richtigen Reihenfolge enthält. Er ist wichtig für spätere HTML- und PDF-Erzeugung.
Beim Zusammenführen gelten diese Regeln:
Vorlage / Textauszug
Reihenfolge der Teile bleibt erhalten.
Überschriften werden nicht automatisch umbenannt.
Codeblöcke bleiben unverändert.
Mermaid-Blöcke bleiben erhalten.
Übungen und Musterlösungen bleiben im passenden Teil.
Begriffserklärungen bleiben dort, wo sie fachlich passen.
Keine generischen Sammelanhänge werden erzeugt.
Nicht erlaubt ist ein Konsolidierungsschritt, der die Datei künstlich verlängert. Der Master-Markdown darf nicht automatisch zusätzliche Absätze erzeugen, die nicht in den Quellen stehen.
---
5. Regeln für die spätere HTML-Ausgabe
Die HTML-Ausgabe muss robust sein. Sie soll auf Desktop, iPad und iPhone nutzbar sein. Besonders wichtig ist, dass die Datei auch dann lesbar bleibt, wenn JavaScript auf einem lokalen iPhone/Safari-Kontext unzuverlässig ist.
Deshalb gilt:
Vorlage / Textauszug
Navigation: native details/summary
Content-Kategorien: native details/summary
Standardzustand: geschlossen
Ankerlinks: echte id-Attribute
Suche: optionaler Komfort, nicht notwendig
Copy-Button: optionaler Komfort, nicht notwendig
Dark Mode: CSS-basiert, nicht abhängig von localStorage
SVGs: inline
Codeblöcke: inline CSS, keine CDN-Abhängigkeit
Die HTML darf nicht auf externe Dateien zeigen. Bilder, Diagramme, CSS und JavaScript müssen entweder inline sein oder weggelassen werden. Für dieses Projekt ist Single-File wichtiger als perfekte Web-App-Funktionalität.
---
6. Navigation: fachlich statt technisch
Die Navigation darf keine Dateinamen oder künstlichen Titel anzeigen. Sie soll fachlich lesen wie ein Inhaltsverzeichnis.
Gut:
Vorlage / Textauszug
Unternehmenskontext und Zielbild
Infrastruktur-Fundament
Cloud-Architektur
VM- und Bare-Metal-Betrieb
Kubernetes- und OpenShift-Plattform
Identity, Security und Governance
Moderne Anwendungen
Daten, Messaging und Integration
Observability und Betrieb
Backup, Restore und Disaster Recovery
DevOps, GitOps und Release Management
Codex und Claude Code im Enterprise-Projekt
Komplettes Beispielprojekt
Übungen, Runbooks und Musterlösungen
Integrierte Begriffserklärungen und Fachindex
Schlecht:
Vorlage / Textauszug
Teil 16
Anhang 16
Praxisdurchlauf 4
integrierte Vertiefung 7
Referenzkarte 12
Erweiterung 3
Die Navigation muss für Menschen gedacht sein, nicht für den Generator.
---
7. Content-Kategorien: geschlossen, aber sinnvoll
Die Content-Kategorien werden standardmäßig geschlossen. Das hat zwei Vorteile. Erstens bleibt eine große HTML-Datei übersichtlich. Zweitens funktioniert die Struktur auf mobilen Geräten besser.
Jede Hauptkategorie bekommt einen klaren Einstieg. Nach dem Öffnen soll der Leser sofort erkennen:
Vorlage / Textauszug
Worum geht es?
Warum ist es wichtig?
Welche Systeme sind betroffen?
Welche Beispiele enthält der Abschnitt?
Welche Artefakte werden gezeigt?
Ein guter Kategorieeinstieg ist ein kurzer fachlicher Absatz, nicht eine Tabelle und nicht ein Glossarblock.
---
8. Codeblöcke: fachlich eingebettet
Codeblöcke dürfen nicht lose im Dokument stehen. Jeder Codeblock braucht Kontext.
Ein guter Codeblock hat davor:
Vorlage / Textauszug
Welche Aufgabe löst der Code?
In welchem Teil der Architektur liegt er?
Welche Annahmen gelten?
Was ist produktionsnah und was ist Lab-Vereinfachung?
Dieser kleine Ausschnitt ist nur sinnvoll, wenn erklärt wird, dass der Use Case die fachliche Eingangsstelle bildet und nicht direkt HTTP, Datenbank oder Messaging kennt.
---
9. Qualitätsprüfung: verbotene Muster
Vor jeder finalen Ausgabe wird auf verbotene Muster geprüft.
Verboten sind:
Vorlage / Textauszug
integrierte Vertiefung
Praxisdurchlauf
Anhang 16
Entscheidung 2
Entscheidung 3
Risiko 2
Risiko 3
Warum das im Lab wichtig ist: klare Nachvollziehbarkeit
Bei Security, Hardening und Audit beginnt die Arbeit mit einer konkreten Fragestellung
Diese Muster stehen stellvertretend für künstlich erzeugte Wiederholungen. Wenn eines davon auftaucht, darf die Ausgabe nicht akzeptiert werden.
---
10. Qualitätsprüfung: Absatzwiederholungen
Nicht jede Wiederholung ist schlecht. Ein Fachbuch darf Begriffe wieder aufnehmen. Aber ganze Absätze dürfen nicht mehrfach mit nur einem ausgetauschten Wort vorkommen.
Die Prüfung soll deshalb Absätze normalisieren:
Vorlage / Textauszug
Kleinbuchstaben
mehrere Leerzeichen entfernen
Zahlen teilweise neutralisieren
sehr kurze Absätze ignorieren
Codeblöcke separat behandeln
Wenn ein langer Absatz mehrfach vorkommt, ist das ein Warnsignal. Dann muss man prüfen, ob der Inhalt wirklich notwendig ist oder ob der Generator nur Text recycelt hat.
---
11. Beispiel: Python-Prüfung gegen verbotene Muster
python
from pathlib import Path
FORBIDDEN = [
class="str">"integrierte Vertiefung",
class="str">"Praxisdurchlauf",
class="str">"Anhang 16",
class="str">"Entscheidung 2",
class="str">"Entscheidung 3",
class="str">"Risiko 2",
class="str">"Risiko 3",
class="str">"Warum das im Lab wichtig ist: klare Nachvollziehbarkeit",
class="str">"Bei Security, Hardening und Audit beginnt die Arbeit mit einer konkreten Fragestellung",
]
def check_forbidden_patterns(path: Path) -> list[str]:
text = path.read_text(encoding=class="str">"utf-8", errors=class="str">"ignore")
findings = []
for pattern in FORBIDDEN:
if pattern.lower() in text.lower():
findings.append(pattern)
return findings
if __name__ == class="str">"__main__":
target = Path(class="str">"Modern_Hybrid_Enterprise_Platform_Lab_MASTER.md")
findings = check_forbidden_patterns(target)
if findings:
print(class="str">"Verbotene Muster gefunden:")
for item in findings:
print(fclass="str">"- {item}")
raise SystemExit(1)
print(class="str">"Keine verbotenen Muster gefunden.")
Dieses Skript ist einfach, aber nützlich. Es verhindert, dass bekannte schlechte Muster unbemerkt wieder in die finale Ausgabe gelangen.
---
12. Beispiel: Python-Prüfung gegen Absatzwiederholungen
python
from pathlib import Path
from collections import Counter
import re
CODE_FENCE = re.compile(rclass="str">"```.*?```", re.DOTALL)
def normalize(paragraph: str) -> str:
paragraph = paragraph.lower()
paragraph = re.sub(rclass="str">"\d+", class="str">"#", paragraph)
paragraph = re.sub(rclass="str">"\s+", class="str">" ", paragraph)
return paragraph.strip()
def extract_paragraphs(text: str) -> list[str]:
text = CODE_FENCE.sub(class="str">"", text)
raw = re.split(rclass="str">"\n\s*\n", text)
result = []
for paragraph in raw:
clean = normalize(paragraph)
if len(clean) >= 240:
result.append(clean)
return result
if __name__ == class="str">"__main__":
path = Path(class="str">"Modern_Hybrid_Enterprise_Platform_Lab_MASTER.md")
text = path.read_text(encoding=class="str">"utf-8", errors=class="str">"ignore")
paragraphs = extract_paragraphs(text)
counts = Counter(paragraphs)
duplicates = [(p, c) for p, c in counts.items() if c > 1]
if duplicates:
print(class="str">"Mögliche Absatzwiederholungen gefunden:")
for paragraph, count in duplicates[:20]:
print(class="str">"---")
print(fclass="str">"Anzahl: {count}")
print(paragraph[:500])
raise SystemExit(1)
print(class="str">"Keine langen doppelten Absätze gefunden.")
Diese Prüfung ist nicht perfekt, aber sie ist genau für dieses Projekt sinnvoll. Sie schützt vor dem Fehler, der zuvor aufgetreten ist: lange, fast identische Absätze mit kleinen Wortwechseln.
---
13. Beispiel: HTML-Build-Grundstruktur
Die HTML-Erzeugung soll nicht versuchen, eine komplexe Web-App zu bauen. Sie soll eine stabile Lesedatei erzeugen.
Der wichtige Punkt ist nicht dieses konkrete Skript. Der wichtige Punkt ist die Architektur des Buildprozesses: Quelle lesen, prüfen, strukturieren, HTML schreiben, erneut prüfen.
---
14. Umgang mit Mermaid und SVG
Mermaid ist für Markdown gut lesbar. In einer lokalen Single-File-HTML ohne externe Bibliotheken ist Mermaid aber schwierig, weil ein Browser Mermaid nicht automatisch rendert. Deshalb gibt es zwei Möglichkeiten:
Vorlage / Textauszug
Option A: Mermaid-Codeblock anzeigen
Option B: Diagramm als inline SVG nachbauen
Für das finale HTML ist Option B besser, wenn das Diagramm zentral ist. Für ergänzende Diagramme reicht Option A.
Ein inline SVG muss direkt im HTML stehen:
html
class="str">"
0
0
900
260
" role=
class
="str">"img" aria-label=
class
="str">"Hybrid Platform Overview">
class="str">"
20
" y=
class
="str">"
40
" width=
class
="str">"
160
" height=
class
="str">"
70
" rx=
class
="str">"
14
">
class="str">"
100
" y=
class
="str">"
82
" text-anchor=
class
="str">"middle">Customer Portal
So vermeidet man kaputte Bildpfade auf iPhone, in Messenger-Apps oder bei lokal geöffneten Dateien.
---
15. Was der Quality-Report enthalten muss
Der Quality-Report ist kein Marketingtext. Er ist ein Nachweis.
Er enthält:
Vorlage / Textauszug
Build-Datum
Quell-Dateien
erzeugte Dateien
Dateigrößen
Prüfung gegen verbotene Muster
Prüfung gegen Absatzwiederholungen
Prüfung der Navigation
Prüfung der Codeblöcke
Prüfung der inline SVGs
bekannte Grenzen
Beispiel:
Vorlage / Textauszug
Quality Report
Ergebnis
Status: bestanden
Quellmaterial
30 Markdown-Dateien
Master-Markdown erzeugt
Single-File-HTML erzeugt
Prüfungen
verbotene Muster: keine Treffer
lange doppelte Absätze: keine kritischen Treffer
Navigation: details/summary vorhanden
Content-Kategorien: standardmäßig geschlossen
externe Assets: keine
Codeblöcke: vorhanden
inline SVGs: vorhanden
Bekannte Grenzen
Copy-Button ist Komfortfunktion
Suche ist Komfortfunktion
Mermaid wird nur angezeigt oder als SVG nachgebaut
---
16. Abnahmeentscheidung
Eine Ausgabe darf nur als finale Version gelten, wenn folgende Aussagen wahr sind:
Vorlage / Textauszug
Die Inhalte stammen aus Markdown-Quellen.
Die Navigation ist fachlich und stabil.
Die Content-Kategorien sind standardmäßig geschlossen.
Es gibt keine bekannten Füllmuster.
Es gibt keine langen doppelten Absätze aus Generator-Recycling.
Codeblöcke sind lesbar und farblich konsistent.
SVGs sind inline oder bewusst als Codeblock belassen.
Das ZIP enthält README und Quality-Report.
Die Datei ist lokal nutzbar.
Wenn eine dieser Aussagen nicht stimmt, wird nicht improvisiert. Dann wird die Quelle korrigiert und der Build wiederholt.
---
17. Großer Praxisblock: vollständiger Ablauf
Der gesamte Ablauf sieht so aus:
Vorlage / Textauszug
Markdown-Dateien sammeln
Dateinamen prüfen
Reihenfolge bestimmen
Master-Markdown erzeugen
verbotene Muster prüfen
doppelte lange Absätze prüfen
HTML aus Master-Markdown erzeugen
Navigation prüfen
Content-Kategorien prüfen
Codeblöcke prüfen
SVGs prüfen
Quality-Report schreiben
Delivery-ZIP bauen
ZIP testen
optional in Google Drive kopieren
Dieser Ablauf ist bewusst unspektakulär. Genau das ist seine Stärke. Er ist wiederholbar.
---
18. Beispiel: Release-Checkliste
Vorlage / Textauszug
[ ] Alle Markdown-Dateien vorhanden
[ ] README aktuell
[ ] Master-Markdown erzeugt
[ ] Keine verbotenen Muster gefunden
[ ] Keine kritischen Absatzwiederholungen gefunden
[ ] HTML erzeugt
[ ] Navigation funktioniert ohne JavaScript
[ ] Content-Kategorien sind geschlossen
[ ] Codeblöcke sind lesbar
[ ] Tabellen sind nicht Hauptinhalt
[ ] Glossar ist nicht Hauptinhalt
[ ] SVGs sind inline
[ ] ZIP enthält alle relevanten Dateien
[ ] ZIP lässt sich entpacken
[ ] Optional: Drive-Upload erfolgreich
---
19. Typische Fehler beim großen Buildschritt
Ein typischer Fehler ist, die HTML-Datei manuell nachzubessern und danach die Markdown-Quelle zu vergessen. Beim nächsten Build ist der Fehler wieder da.
Ein zweiter Fehler ist, beim Erzeugen der Navigation technische Dateinamen direkt zu übernehmen. Dadurch entstehen Einträge, die für Leser unschön sind.
Ein dritter Fehler ist, Diagramme als externe Dateien abzulegen. Lokal funktionieren sie vielleicht, aber auf iPhone oder nach dem Teilen per Messenger fehlen sie.
Ein vierter Fehler ist, die Datei künstlich über eine Zielgröße zu bringen. Die Größe ist kein Qualitätskriterium, wenn sie durch Wiederholungen entsteht.
Ein fünfter Fehler ist, den Quality-Report nur positiv zu formulieren. Ein guter Quality-Report nennt auch Grenzen und offene Punkte.
---
20. Ergebnis dieses Schritts
Nach diesem Schritt hat das Projekt eine klare technische Übergabelogik. Die Inhalte sind nicht mehr nur einzelne Kapitel. Sie sind Teil eines kontrollierten Buildsystems.
Das wichtigste Ergebnis lautet:
Vorlage / Textauszug
Ab jetzt ist nicht mehr die HTML-Datei die Wahrheit.
Die Markdown-Quelle ist die Wahrheit.
HTML, PDF und ZIP sind reproduzierbare Ausgaben daraus.
Damit kann die nächste große Phase sauber beginnen: die echte finale HTML-Erzeugung aus dem konsolidierten Master-Markdown mit Quality-Report und Delivery-ZIP.
---
21. Übung
Beschreibe in eigenen Worten, warum es gefährlich ist, eine große HTML-Datei direkt zu reparieren, ohne die Markdown-Quelle zu ändern.
Eine direkte Reparatur an der HTML-Datei ist gefährlich, weil HTML nur die Ausgabe ist. Wenn die Markdown-Quelle unverändert bleibt, wird der gleiche Fehler beim nächsten Build erneut erzeugt. Dadurch entstehen zwei Wahrheiten: eine korrigierte HTML-Datei und eine falsche Quelle. Später weiß niemand mehr, welche Version korrekt ist.
Ein Master-Markdown hilft, weil alle Inhalte an einer nachvollziehbaren Stelle zusammengeführt werden. Der Quality-Report dokumentiert, welche Prüfungen durchgeführt wurden und ob verbotene Muster oder Wiederholungen gefunden wurden. Dadurch wird die Ausgabe nicht nur erzeugt, sondern auch überprüfbar gemacht.
Die richtige Arbeitsweise lautet daher: Quelle korrigieren, Master-Markdown neu erzeugen, HTML neu bauen, Quality-Report schreiben und ZIP neu packen.
---
23. Merksätze
Vorlage / Textauszug
Die Quelle ist Markdown, nicht HTML.
Eine HTML-Reparatur ohne Quellenänderung ist nur Kosmetik.
Ein großes Dokument braucht Buildregeln, nicht Zufall.
Qualität entsteht durch Inhalt, Struktur und Prüfung.
Ein ZIP ohne README und Quality-Report ist keine saubere Übergabe.
Eine große Datei ist nur dann wertvoll, wenn sie fachlich dicht und nachvollziehbar ist.
Vollständiger HTML-Rebuild ohne Inhaltsverlust
Ziel dieses Schritts
Dieser Schritt korrigiert den Fehler aus dem vorherigen HTML-Build: Die Markdown-Quelle war gewachsen, aber die erzeugte HTML-Datei wurde kleiner. Das ist ein klares Signal, dass der Build nicht alle Formatierungs- und Inhaltsbestandteile sauber übernommen hat. Der neue Build behandelt das Master-Markdown als verbindliche Quelle und erzeugt daraus eine vollständige Single-File-HTML mit stabiler Navigation, Inline-SVGs, dunklen Codeblöcken und sichtbarer Inhaltsstruktur.
Wichtig ist: Dieser Schritt ergänzt nicht künstlich Text, um eine Dateigröße zu erreichen. Er stellt sicher, dass der vorhandene Inhalt vollständig im HTML sichtbar wird. Die Größe darf durch echte HTML-Struktur, Codeblock-Formatierung, Inline-SVGs und Syntax-Markup wachsen, aber nicht durch sinnlose Wiederholungen.
Build-Entscheidung
Die HTML-Datei wird aus allen nummerierten Markdown-Teilen erzeugt. Die Quelle bleibt Markdown. Die HTML-Ausgabe ist eine Lesefassung mit Navigation, Abschnitten, Codeblock-Kacheln und mobilen Layoutregeln.
Der neue Build übernimmt:
alle Fachkapitel von Teil 1 bis Teil 35
große Praxis-Szenarien aus Teil 34
kompakte SVGs aus Teil 32 und Teil 33
großen Fachglossar und Querverweise
Codebeispiele aus allen Kapiteln
Quality-Regeln und Abnahmeabschnitte
README- und Delivery-Hinweise
Nicht übernommen werden künstliche Füllmuster. Wenn verbotene Begriffe in Negativlisten vorkommen, werden sie im Quality-Report markiert und nicht als fachliche Kapitel interpretiert.
HTML-Regel
Die Navigation nutzt native details/summary-Elemente. Dadurch funktioniert die Datei auch lokal auf iPhone und Safari zuverlässiger als eine rein JavaScript-basierte Navigation. JavaScript wird nur als Komfort verwendet, zum Beispiel für Copy-Buttons und automatisches Öffnen eines Zielabschnitts beim Anklicken eines Ankerlinks.
Content-Kategorien bleiben standardmäßig geschlossen. Dadurch lädt die Seite übersichtlich und der Leser entscheidet selbst, welchen Teil er öffnet. Die Inhalte werden nicht per JavaScript nachgeladen oder versteckt. Sie sind vollständig im HTML vorhanden.
Codeblock-Regel
Codeblöcke werden als dunkle Kacheln dargestellt. Sie bekommen horizontales Scrollen, Copy-Button und sprachabhängige Klassen. Java, YAML, SQL, Bash, HCL, Markdown und Text werden unterscheidbar behandelt. Das Styling orientiert sich am JetBrains-Dark-Prinzip: dunkler Hintergrund, helle Grundschrift, farbige Keywords, Strings, Zahlen, Kommentare und Schlüssel.
SVG-Regel
Alle SVGs bleiben inline. Es gibt keinen externen Asset-Ordner. Dadurch entstehen keine kaputten Bildpfade, wenn die HTML-Datei lokal, auf iPhone, aus Google Drive oder aus einem ZIP geöffnet wird.
Prüfregel
Nach dem Build wird geprüft:
Anzahl der Markdown-Teile
Größe des Master-Markdowns
Größe der Single-File-HTML
Anzahl der Codeblöcke
Anzahl der Inline-SVGs
verbotene Muster
ZIP-Test
Ergebnis dieses Schritts
Dieser Schritt erzeugt eine neue HTML-Version auf Basis des vollständigen Master-Markdowns 1 bis 35. Die HTML darf nicht kleiner sein als die vorherige bessere Version aus Teil 33. Wenn sie kleiner wäre, gilt der Build als nicht abgenommen.