Start / Seminare / Jakarta EE modernisieren

Modul

Containerisierung und Plattformbetrieb

4 Kapitel in diesem Modul-Video · Laufzeit

Vertonung mit synthetischer Stimme · Inhalte redaktionell verantwortet · © 2026 HECKER CONSULTING, alle Rechte vorbehalten

Transkript

Der gesprochene Text dieses Moduls zum Mitlesen, Überfliegen und Durchsuchen. Ein Klick auf einen Zeitstempel springt an die Stelle im Video.

Containerisierung und Plattformbetrieb

0:00 Der Pilot ist migriert und durch Tests abgesichert. Jetzt muss er in Betrieb — und dabei gilt ein Satz, den man sich merken sollte: Ein Container ist erst dann fertig, wenn er sich beenden lässt, ohne Arbeit zu verlieren. Wir sehen uns an, wie aus derselben Anwendung zwei Arten von Images entstehen, wie Konfiguration und Geheimnisse im Betrieb ankommen und wie der Dienst auf Kubernetes oder OpenShift landet.

0:23 Vieles davon kennen Sie aus Modul fünf — dort ging es um den Application Server, hier um den migrierten Dienst. Die Fragen sind dieselben, die Antworten teilweise einfacher.

Containerisierung und Plattformbetrieb

0:34 Wir sind im Betriebsteil des dritten Tages. Nach den Tests folgt der Weg auf die Plattform, danach die Beobachtbarkeit und die Entscheidung zwischen JVM und nativem Betrieb. Was hier entsteht — Image, Manifeste, Grenzen —, ist die Grundlage für die Messungen in Modul sechzehn und für den schrittweisen Übergang in Modul siebzehn.

Images bauen

0:53 Fangen wir beim Artefakt an. Aus einer Anwendung entstehen zwei sehr unterschiedliche Images — und beide Wege sollten Sie einmal gebaut haben. Aus einer Anwendung entstehen zwei sehr unterschiedliche Images, und beide Wege sollten Sie einmal gebaut haben — entschieden wird erst danach. Aus derselben Anwendung entstehen zwei Arten von Images: eines mit JVM und Anwendungsarchiv, eines mit einem nativ übersetzten Prozess.

1:18 Der Bau läuft entweder über die Container-Image-Erweiterungen der Anwendung selbst — die Anwendung baut ihr eigenes Image — oder über einen mehrstufigen Container-Build. Beides hat seine Berechtigung: Der erste Weg ist bequem und gut in die Entwicklung integriert, der zweite passt besser, wenn die Bauumgebung standardisiert ist und in einer Pipeline läuft.

1:38 Wichtig ist, dass Sie sich für einen entscheiden und ihn dann konsequent nutzen. Die Logik dieser Tabelle ist ein Tauschgeschäft: Was Sie an Startzeit und Speicher gewinnen, zahlen Sie an Bauzeit und Vertrautheit. Besonders die letzte Zeile verdient Aufmerksamkeit — beim JVM-Image sind die Fehlerbilder vertraut, beim nativen zeigen sie sich erst zur Laufzeit und sehen zunächst rätselhaft aus.

2:01 Und wie die Fußzeile sagt: Die Entscheidung fällt in Modul sechzehn, mit Messwerten. Hier bauen wir nur den Weg für beide Varianten. Das ist ohnehin die richtige Reihenfolge — erst die Möglichkeit schaffen, dann anhand von Zahlen entscheiden. Worauf es hier ankommt, ist die letzte Zeile: der Blick in das erzeugte Verzeichnis.

2:20 Denn die Kubernetes-Erweiterung erzeugt nicht nur ein Image, sondern gleich die passenden Manifeste — Deployment, Service, auf Wunsch mehr. Und wie die Fußzeile sagt: Diese Dateien gehören ins Repository. Das ist ein zentraler Punkt für den Betrieb. Erzeugte Manifeste, die niemand ansieht und niemand versioniert, sind eine Blackbox; versionierte Manifeste sind der beschriebene Sollzustand Ihres Dienstes.

2:44 Sehen Sie sie sich einmal vollständig an, bevor Sie sie anwenden. Vier Gründe, und der erste ist auch ein Sicherheitsargument: Übersetzungswerkzeuge gehören nicht in das ausgelieferte Image. Jedes Werkzeug im Image ist eine Bibliothek mehr, für die Schwachstellen gemeldet werden können — und die jemand nutzen kann, der im Container landet.

3:04 Punkt zwei ist der praktische Effekt: kleinere Images laden schneller und starten schneller, was bei jedem Rollout und jeder Skalierung zählt. Und Punkt drei ist der, der Diskussionen beendet: Die Bauumgebung ist reproduzierbar, unabhängig davon, was auf welchem Arbeitsplatz installiert ist. Punkt zwei ist der Fehler, der sich als sporadischer Absturz zeigt: Die Speichergrenze des Containers und die Einstellungen der JVM widersprechen sich.

3:31 Die Plattform erlaubt 512 Megabyte, die JVM will mehr — und der Container wird beendet, ohne dass in Ihren Logs etwas steht. Prüfen Sie also nicht nur, ob Grenzen gesetzt sind, sondern ob sie zusammenpassen. Punkt drei ist der aus Modul sechs bekannte Fast-JAR-Fehler: Der Ordner wird unvollständig kopiert. Und Punkt vier ist Betriebsalltag: Ein Image ohne aussagekräftiges Etikett ist in drei Monaten nicht mehr zuzuordnen.

Konfiguration im Betrieb

3:56 Kommen wir zur Konfiguration. Die Regel kennen Sie aus Modul fünf — hier sehen wir, wie sie in die Manifeste kommt. Die Regel kennen Sie aus Modul fünf. Hier sehen wir, wie sie in die Manifeste kommt, ohne dass jemand sie doppelt pflegen muss. Die Anwendung liest ihre Konfiguration aus Umgebungsvariablen, ConfigMaps und Secrets.

4:16 Der angenehme Unterschied zum Application Server: Die Kubernetes-Erweiterung erzeugt die passenden Einträge in den Manifesten selbst. Sie beschreiben also einmal in der Anwendungskonfiguration, welches Secret gebraucht wird — und das Deployment-Manifest enthält den passenden Verweis. Damit stammen Konfiguration und Deployment aus derselben Quelle und können nicht mehr auseinanderlaufen.

4:39 Das ist genau die Art von Vereinfachung, die im Betriebsalltag Fehler vermeidet. Vier Zeilen mit zwei verschiedenen Aufgaben. Die ersten beiden binden ein Secret und setzen eine Umgebungsvariable — Zugangsdaten und Fremdsystem-Adresse. Die letzten beiden setzen Speicheranforderung und Speichergrenze. Und die Fußzeile ist eine Warnung aus dem Betrieb: Ohne Grenzen belegt eine Instanz so viel, wie der Knoten hergibt — bis der Knoten ausfällt und andere Anwendungen mit umreißt.

5:07 Setzen Sie beides, Anforderung und Grenze, und setzen Sie sie nicht nach Gefühl, sondern nach einer Messung unter Last. Dazu kommen wir gleich in der Übung. Das ist der Punkt, der bei migrierten Enterprise-Anwendungen am häufigsten unbeachtet bleibt. Punkt eins nennt die Ursache: Die Plattform beendet Instanzen bei jedem Rollout und bei jeder Skalierung — also nicht im Ausnahmefall, sondern regelmäßig.

5:31 Punkt zwei ist der konkrete Schaden bei Zählwerk: Ein laufender Ableselauf darf nicht mitten im Schritt abbrechen. Punkt drei knüpft an Modul elf an — Nachrichten müssen bestätigt oder wieder freigegeben werden. Und Punkt vier ist die Folge: Ohne geordnetes Ende entstehen halbe Vorgänge, die niemand aufräumt und die erst beim Abgleich auffallen.

5:51 Die drei Prüfungen kennen Sie aus Modul fünf, hier noch einmal aus Sicht des migrierten Dienstes. Die Startprüfung gibt langsam startenden Anwendungen Zeit — bei einem nativen Prozess weniger relevant, bei einem JVM-Dienst mit Datenbankmigration durchaus. Die Bereitschaftsprüfung hält Verkehr fern, solange Abhängigkeiten fehlen. Die Lebendprüfung startet nur neu, wenn wirklich nichts mehr geht.

6:14 Und Punkt vier ist praktisch: Die Pfade liegen unter einem gemeinsamen Präfix und sind einzeln abrufbar — Sie können also jede Prüfung getrennt aufrufen und sehen, welche Aussage sie liefert. Punkt eins ist ein Fund, den Sicherheitsprüfungen regelmäßig machen: Ein Secret wird als Umgebungsvariable im Manifest im Klartext hinterlegt — und das Manifest liegt im Repository.

6:36 Damit ist das Geheimnis öffentlich, jedenfalls für alle mit Leserechten. Punkt zwei ist der Fehler aus Modul fünf, den ich hier wiederhole, weil er so folgenreich ist: Die Lebendprüfung fragt die Datenbank ab und startet bei jeder Störung neu. Punkt drei ist die ungemessene Grenze. Und Punkt vier ist der Datenverlust beim Herunterfahren — bestätigte, aber unverarbeitete Nachrichten sind weg.

Auf die Plattform bringen

6:59 Bleibt der letzte Schritt: vom Image zum laufenden Dienst im Cluster. Und ein Blick auf die Unterschiede zwischen Kubernetes und OpenShift. Und dazu ein Blick auf die Unterschiede zwischen Kubernetes und OpenShift — sie sind kleiner, als man denkt, und treffen Migrationen trotzdem. Aus der Anwendung entstehen Deployment, Service und auf Wunsch ein Zugang von außen.

7:21 Für OpenShift gibt es eine eigene Erweiterung, die statt eines Ingress eine Route erzeugt und den plattformeigenen Bauweg nutzt. Das ist mehr als ein Namensunterschied: Der Bauweg im Cluster ändert, wo Ihr Image entsteht und wer Zugriff darauf hat. Wenn Ihr Betrieb OpenShift einsetzt, lohnt es sich, diese Erweiterung von Anfang an zu verwenden statt selbst gebaute Manifeste anzupassen — sonst pflegen Sie zwei Varianten.

7:45 Vier Schritte, und der letzte ist der, der gern zur Formalie wird: prüfen. Damit ist nicht gemeint, ob der Pod läuft — das sagt die Plattform ohnehin. Gemeint ist: Antwortet der Dienst fachlich richtig, sind die Prüfpunkte korrekt, greift die Konfiguration aus ConfigMap und Secret wirklich? Ein Pod im Zustand laufend kann durchaus mit falscher Datenbankadresse arbeiten und alles ablehnen.

8:08 Machen Sie deshalb nach jedem Ausrollen mindestens einen fachlichen Aufruf — bei Zählwerk etwa das Lesen eines bekannten Ableseauftrags. Die Logik dieser Tabelle: dieselben Konzepte, andere Namen und andere Voreinstellungen. Und wie die Fußzeile sagt, trifft die letzte Zeile Migrationen häufig: OpenShift hat strengere Rechtevorgaben.

8:28 Ein Image, das als Wurzelbenutzer laufen will — und ältere Application-Server-Images wollen das oft —, startet dort schlicht nicht. Das ist kein Fehler der Plattform, sondern eine bewusste Absicherung. Aber es ist ein Punkt, den man besser früh entdeckt: nämlich beim ersten Versuch im Entwicklungscluster und nicht in der Abnahme drei Tage vor dem Termin.

8:49 Vier Gründe, und der letzte ist der, der im Betriebsalltag am meisten Ärger erspart: Handeingriffe im Cluster gehen beim nächsten Rollout verloren. Jemand korrigiert unter Zeitdruck eine Umgebungsvariable direkt im Cluster, es funktioniert, alle sind zufrieden — und beim nächsten Ausrollen ist die Korrektur weg, weil das Manifest sie nicht kennt.

9:09 Punkt drei ist der praktische Nutzen: Ein Rückweg besteht darin, den alten Stand erneut anzuwenden. Das ist schnell, nachvollziehbar und braucht keinen Build — genau das, was man im Ernstfall will. Punkt zwei ist der, den wir gerade besprochen haben: Die Anwendung läuft lokal und scheitert an den Rechtevorgaben der Plattform. Probieren Sie das früh aus.

9:30 Punkt drei ist ein Reihenfolgefehler mit unmittelbarer Wirkung: Der Zugang von außen wird eingerichtet, bevor die Bereitschaftsprüfung steht — dann bekommt eine startende Instanz sofort echten Verkehr. Und Punkt vier ist der organisatorische, der jede Reproduzierbarkeit aushebelt: Konfiguration wird direkt im Cluster geändert.

9:49 Einmal ist Notfall, zweimal ist Gewohnheit, dreimal ist Ihr Repository nur noch Dekoration.

Übung

9:55 In der Übung bringen Sie den Dienst in den Cluster. Und der letzte Schritt wird Ihnen zeigen, was in Modul elf offen geblieben ist. Der letzte Schritt der Übung wird Ihnen zeigen, was in Modul elf offen geblieben ist. Er dauert eine Minute und ist der lehrreichste. Sie paketieren und konfigurieren den migrierten Dienst so, dass er ohne Handeingriff auf der Plattform läuft und sich sauber beenden lässt.

10:18 Das Lernziel ist genau diese Betriebsreife — nicht, dass etwas startet, sondern dass es sich im laufenden Betrieb beherrschen lässt. Erfolgreich sind Sie, wenn der Dienst mit gesetzten Grenzen läuft, alle umgebungsabhängigen Werte aus ConfigMap und Secret kommen und ein laufender Ableselauf beim Herunterfahren nicht abbricht.

10:36 Zwei Umgebungen genügen: dasselbe Image, unterschiedliche Konfiguration — das ist die Probe aufs Exempel. Fünf Schritte, und Schritt vier enthält die eigentliche Ingenieursarbeit: Grenzen setzen und den Speicherbedarf unter Last messen. Nicht schätzen — messen, mit einer Last, die Ihrem Lastprofil ähnelt. Und Schritt fünf ist der lehrreichste: Herunterfahren im laufenden Ableselauf auslösen.

10:59 Wie die Fußzeile sagt, deckt das regelmäßig auf, was in Modul elf offen geblieben ist — nämlich ob Nachrichten sauber bestätigt oder freigegeben werden. Es ist ein sehr wirksamer Test: Er dauert eine Minute und findet Fehler, die sonst erst im Produktivbetrieb auffallen. Punkt eins und zwei gehören zusammen und sind der häufigste Betriebsfehler bei migrierten Anwendungen: Der Speicherbedarf wird geschätzt, und die Grenze liegt unter dem, was die JVM beim Start anfordert.

11:27 Das Ergebnis ist ein Container, der beim Start beendet wird — ohne verständliche Meldung. Punkt drei ist der Abbruch beim Herunterfahren, den Schritt fünf der Übung aufdeckt. Und Punkt vier ist der, der die Reproduzierbarkeit kostet: Die Manifeste bleiben lokal, der Cluster wird von Hand gepflegt. Damit ist der Sollzustand nirgends beschrieben — und ein Rückweg nicht möglich.

Lieber mit Trainer? Dieses Modul ist Teil unserer Team-Schulungen — mit Übungen, Ihrem eigenen Code und Fragen, die ein Video nicht beantwortet. Mehr erfahren →