© Liashko/Shutterstock.com
Hochdynamische Anwendungen mit Containern und Service Meshes

Java Microservices: ab in die Cloud


Microservices-basierte Anwendungen in Java zu realisieren, ist dank Spring Boot und Eclipse MicroProfile denkbar einfach. Das gilt sowohl für die Implementierung der Services selbst als auch für die grundlegende Unterstützung notwendiger Querschnittsdienste wie Logging, Tracing und Security. Was aber, wenn zusätzliche Flexibilität bezüglich Skalierung und Plattform gefragt ist? Bevor es mit der Anwendung in die Cloud geht, müssen zunächst noch ein paar Hausaufgaben erledigt werden.

Beim Umstieg von monolithischen Architekturen hin zu Microservices müssen Enterprise-Java-Entwickler mit vielfältigen Herausforderungen rechnen. Mit Hilfe von Spring Boot oder MicroProfile können diesen Herausforderungen technologisch begegnet werden. Doch welche zusätzlichen infrastrukturellen Hilfsmittel werden benötigt, um eine Microservices-basierte Anwendung – beispielsweise in der Cloud – sinnvoll betreiben zu können? Wie hoch ist die Zunahme der Komplexität? Oder ist der Aufwand am Ende gar nicht so groß wie gedacht? Schauen wir uns diese Fragen einmal genauer an.

Flexibilität und Agilität

Einen einzelnen Microservice zu implementieren und alleinstehend zum Laufen zu bekommen, ist heutzutage dank guter Framework-Unterstützung kein wirkliches Problem mehr. Die eigentliche Herausforderung besteht darin, eine fachlich komplexe Anwendung als Netz von Dutzenden von Microservices inklusive der dafür notwendigen Infrastruktur dynamisch aufzubauen und zu betreiben. Steigt die Last, sollen die Services automatisch skalieren. Fallen Service aus oder werden gerade unter geänderter Adresse neu gestartet, sollen potenzielle Consumer davon nichts mitbekommen, sondern automatisch an die neue Adresse geroutet oder mit alternativen Services verbunden werden.

Aber nicht nur die Technologie bringt neue Herausforderungen mit sich, sondern auch der damit einhergehende agile Entwicklungsprozess und die durch ihn ermöglichte Geschwindigkeit von der Anforderung bis hin zur Bereitstellung und Liveschaltung eines neuen fachlichen Features. Langwierig beim Operation-Team zu beantragende Plattformkomponenten sind ebenso tabu wie ressourcen- und zeitfressende, anwendungsweite Test- oder Integration-Stages.

Um dieser Anforderungen Herr zu werden, bedarf es einer leichtgewichtigen Virtualisierung der Anwendungskomponenten, die es den Entwicklern erlaubt, die von ihnen implementierte Software in kurzen Iterationen produktionsnah zu testen und bereitzustellen. Zusätzlich wird ein Mechanismus benötigt, der die virtualisierten Komponenten automatisiert orchestriert, überwacht und bei Bedarf korrigierend eingreift. Und letztendlich gilt es noch, die Inter-Service-Kommunikation in den Griff zu bekommen.

Für die erste Herausforderung – leichtgewichtige Virtualisierung – haben sich in den letzten Jahren Container hervorgetan. Die zweite Herausforderung wird entsprechend von Werkzeugen zur Containerorchestrierung und deren Management übernommen. Als dritte und letzte Infrastrukturkomponente kommen sogenannte Service Meshes ins Spiel, die die Aufgabe eines Infrastrukturlayers für Inter-Service-Kommunikation übernehmen.

Container, wohin man schaut

Seit 2013 das Open-Source-Projekt Docker veröffentlicht wurde, sind Container nicht mehr wegzudenken. Aber warum brauchen wir überhaupt Container? Und welchen Vorteil bringen sie uns speziell im Umfeld von Microservices? Schließlich gibt es doch seit Jahren Virtualisierung.

Zunächst einmal soll die Frage geklärt werden, warum wir überhaupt Virtualisierung im Umfeld von Microservices benötigen. Die Grundidee der Virtualisierung besteht darin, den Anwendungs- und Plattformkomponenten eine identische und stabile Ablaufumgebung von der Entwicklung bis hin zur Produktion zur Verfügung zu stellen und so negative Seiteneffekte bei der Übergabe der Software von einer Stage zur nächsten zu vermeiden. Ohne Virtualisierung müssten entweder alle Stages – inklusive OS, Plattformkomponenten und Zugriffsrechten – identisch aufgebaut sein, was faktisch kaum zu realisieren ist, oder es müsste ein nicht zu unterschätzender manueller Aufwand bei der Migration der Komponenten von einer Stage zur nächsten betrieben werden. Genau das widerspricht aber dem agilen Konzept und macht alle Vorteile der Microservices in Hinblick auf eine schnelle Umsetzung und Bereitstellung neuer Features zunichte.

So weit, so gut. Welchen Vorteil bringen dann aber Container im Vergleich zur klassischen Virtualisierung mit sich? Bei der Virtualisierung besteht das Gesamtpaket aus einer VM, inklusive Betriebssystem und Anwendung. Ein physikalischer Server mit mehreren virtuellen Maschinen würde also entsprechend aus einem Hypervisor und mehreren darauf aufsetzenden Gastbetriebssystemen bestehen (Abb. 1). Diese strikte Trennung der einzelnen VMs inklusive all ihrer Komponenten hat aus Sicht der Sicherheit durchaus ihre Vorteile. Betrachtet man dagegen die benötigten Ressourcen, kommt dieses Modell allerdings relativ schwergewichtig daher und scheint somit für Microservices-basierte Anwendungen mit sehr, sehr vielen zu virtualisierenden Komponenten nicht wirklich gut geeignet zu sein.

limburg_roewekamp_microservices_03_1.tif_fmt1.jpgAbb. 1: Virtualisierung vs. Container

Hier kommen nun Container ins Spiel. Im Gegensatz zur klassischen Virtualisierung teilen sich Container den Betriebssystemkernel untereinander lesend. Zusätzlich erhält jeder Container Zugriff auf einen eigenen, schreibenden Bereich. Container benötigen somit kein Gastbetriebssystem und sind daher deutlich leichtgewichtiger. Dies bringt nicht nur zur Laufzeit Vorteile mit sich, sondern hilft auch dabei, den Container einfacher von A nach B zu verschieben.

Ein weiterer Vorteil der Container ergibt sich durch deren schnelle Bootsequenz. Je nach Aufbau stehen die innerhalb der Container beherbergten Microservices binnen Sekunden zur Verfügung, was dem agilen Vorgehen mit seinen sehr kurzen Testiterationen sehr entgegenkommt. VMs dagegen benötigen teilweise Minuten zum Hochfahren.

Container können aus mehreren Layern aufgebaut sein, von denen alle bis auf den obersten immutable sind. Dies hilft dabei, das Risiko einer Manipulation der Container zu minimieren, und kann die Build-Geschwindigkeit deutlich erhöhen, da beim Neubau des Containers lediglich der Writable-Layer ausgetauscht werden muss. Wie immer steckt natürlich auch bei der Verwendung von Containern der Teufel im Detail. Da die Container von der Entwicklung bis zur Produktion zum Einsatz kommen, sollte man sich vor deren Einsatz ausgiebig mit der Materie auseinandersetzen. Zwar gibt es mittlerweile – insbesondere für Docker – sehr viele offene Repositories mit vorgefertigten Containern, diese entsprechen aber nicht immer den eigenen (Sicherheits-)Anforderungen.

Bedeutet das nun, dass jeder Entwickler auch automatisch zum Container- bzw. Docker-Spezi...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Gewinner-Teams

Wir bieten Lizenz-Lösungen für Teams jeder Größe: Finden Sie heraus, welche Lösung am besten zu Ihnen passt.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang