Anatomie eines Microservice

Ein Microservice muss an vielen Stellen mit seiner Umwelt (bzw. Infrastruktur) reden, was die Entwicklung ohne Planung zu einem gefährlichen Unterfangen bzgl. der späteren Wartbarkeit macht! In diesem Artikel sollen die typischen Abhängigkeiten eines Microservice zu seiner Umgebung dargestellt werden.

1) Container und Laufzeit-Umgebung

Typischerweise wird ein Microservice (im folgenden als gelbe Wabe dargestellt) nie direkt auf ein Cloud-System (VM) kopiert. In vielen Fällen kommt für den Transport Docker oder ein ähnliches System zur Applikations-Virtualisierung zum Einsatz.

Ein Container basiert immer auf einer vorinstallierten Laufzeit-Umgebung (z. B. ein Java 8-Container).

Der Beispiel-Service in unserer obigen Abbildung wurde in Javascript geschrieben und wird von nodeJS interpretiert (nodeJS ist vergleichbar mit dem Java-Interpreter). Damit ist der Microservice für sich ablauffähig. Kommt es allerdings im Betrieb zu unvorhergesehenen Problemen und der Microservice stürzt ab, ist ein weiterer Bestandteil notwendig: PM2 (bzw. nodemon, forever) kommt als Prozessüberwachungs- und -skalierungs-Instanz zum Einsatz. Damit wird der Service nach einem Absturz sofort wieder gestartet.

2) Monitoring: Schlüssel für die Überwachbarkeit unseres Systems

Da Microservices keine UI (außer der Konsole) besitzen, ist es die erste Aufgabe, einen Microservice an ein zentrales Logging-/Monitoring-System anzuschließen: Nach dem Starten sollte der Microservice melden, dass er erfolgreich gestartet wurde bzw. im Fehlerfall anzeigen was fehlt.

In unserer nodeJS-Implementierung möchten wir natürlich das Logging nicht selbst implementieren, denn es gibt viele Log-Bibliotheken zur Auswahl. Wir verwenden die Open Source Bibliothek Winston, um die Log-Ausgaben an unser Loggin-/Monitoring-System weiterzuleiten (ELK-Stack: Elasticsearch/Logstash/Kibana).

Tipp: Ein White-Box-Ansatz („ausgewählte Werte nach außen legen“) ist einem konventionellen Black-Box-Ansatz (z. B. Nagios) bei weitem überlegen und steht jeder Microservice Umgebung gut zu Gesicht.

3) Configuration Management: Ohne Passwörter kein Datenbankzugriff

Nachdem ein Microservice erfolgreich gestartet wurde, benötigt er in der Regel die Zugangsdaten zu seiner Datenbasis (z. B. ein MongoDB NoSQL-Cluster). Diese Informationen kommen entweder aus der Container-Umgebung (Docker-Environment) oder aus einem zentral gepflegten und gesicherten Configuration Management System:

Als Configuration Management System verwenden unsere Microservice-Templates die Open Source Komponente Spring Boot Config. Diese wird z. B. in Cloud Foundry Umgebungen verwendet – in unserem Setup läuft sie aber genauso in einer Microsoft Azure-Umgebung. Wenn Credentials (Anmeldeinformationen an interne Systeme) in der Konfiguration enthalten sind, dann fügt das System HashiCorp Vault diese transparent in die Konfiguration ein. Sicheres und auditierbares Credential-Management ist für die Sicherheit des Gesamtsystems von großer Bedeutung.

Tipp: Ohne geplantes Configuration Management versinkt eine Microservice-Umgebung in kürzester Zeit im operativen Chaos.

4) Außensicht: Service Registry & API Gateway

Der wahre Vorteil von Microservices ist ihr kommunikatives Wesen: über REST-Schnittstellen legen Sie eine API für andere Microservices, Web-Oberflächen oder auch Kunden-Hardware offen. Doch bevor diese Clients die API unserer Microservices verwenden können, muss dieser überhaupt in der Cloud auffindbar sein: Dazu registriert sich der Service direkt nach dem Start bei einer Service Registry:

Als Service Registry kommt in unserer Standard-Systemumgebung Spring Cloud Eureka (aus dem Neflix-Stack) zum Einsatz. Wie immer kann diese Komponente aber auch durch andere Produkte, wie z. B. HashiCorp Consul, ersetzt werden.

Ein API-Gateway ist in Form eines Reverse-Proxy allen Microservices vorgeschaltet, so dass z. B. auch fremde Microservices leicht intergrierbar sind oder Zugriffe zentral umgeleitet werden können (Service Redirect). Der API-Gateway schützt die Gesamtinfrastruktur durch Methoden wie Circuit Breaker auch in Fehlersituationen: kurzzeitige Nichtverfügbarkeit einzelner Services kann durch einstellbare Wiederholungen ausgeglichen werden.

5) Benutzer, Berechtigungen & Rollen

Das Thema Sicherheit kann im Cloud-Umfeld gar nicht hoch genug bewertet werden. Deshalb besteht einer der zentralen Punkte einer Microservice-Architektur in der Auswahl einer geeigneten übergreifenden Benutzer-Verwaltung, die im allgemeinen als IAM (Identity and Access Management) bezeichnet wird:

Der Microservice kann alle oder einzelne seiner REST-Schnittstellen über JWTs, die vom IAM-System erzeugt werden, absichern. Dabei transportiert ein JWT (JSON Web Token) die notwendigen Authentifizierungs- und Authorisierungs-Informationen und macht damit performance-mindernde Lookups oder skalierungs-hemmende Server-Sessions überflüssig.

JWTs basieren auf OAUTH2-Protokollen und werden heute in einer Vielzahl von Authentifizierungs-Szenarien eingesetzt. Die bekannte Bibliothek express-jwt bietet eine solide Basis für den internen Umgang mit JWTs.

Im Sicherheitsumfeld sind aus unserer Erfahrung viele weitere Themen zu klären, wie z. B.

  • Single-Sign-On: Unternehmensweit ein Login für alle Apps
  • Social-Login: Verwenden eines Facebook- oder Amazon-Accounts anstatt
    neues Login und Password
  • Federation: Einbinden von bereits bestehenden ActiveDirectory oder LDAP
    Benutzerverzeichnissen
  • Multi-Faktor-Auth: Verwenden von SMS- oder Einmal-Passwörtern zusätzlich zu Login
    und Password

Wir empfehlen in diesem Zusammenhang IAM nicht selbst zu implementieren, sondern auf etablierte Lösungen wie z. B. AUTH0 oder Security-Appliances von Hardwareherstellern zuzugreifen. In der Regel können nur Konzerne den laufenden Aufwand, der durch ständig neu auftretenden Bedrohungen im Sicherheitsbereich verursacht wird, finanzieren.

6) Nur gemeinsam stark: Microservice:Microservice-Kommunikation

In jeder Microservice-Umgebung spielt die Entkopplung der Services voneinander durch asynchrone Kommunikation eine große Rolle für die Fehlertoleranz und Skalierbarkeit.

Jede Cloud-Umgebung bietet (mindestens) einen proprietären Technologie-Vorschlag für das Thema MQ (Message Queue): AWS mit SQS, Azure mit Service Bus und CloudFoundry mit NATS. In unserer Referenz-Architektur haben wir uns für RabbitMQ entschieden, da es bereits viele OpenSource-Bibliotheken gibt, die dieses MQ-Produkt unterstützen: z. B. hase für nodeJS-Projekte.

Zusammenfassung: Herausforderungen beim Design von Microservices

Wie wir gesehen haben, liegt die Schwierigkeit beim Design von Microservices in der Anpassung an die Betriebsumgebung: als Software-Entwickler hat man oft die Qual der Wahl zwischen dutzenden von Open-Source-Paketen oder kommerziellen Software-Komponenten um eine bestimmte Anbindung zu realisieren.

Ohne eine einzige Zeile fachlichen Code zu implementieren, haben wir schon 10 Open Source Bausteine/Technologien verbauen müssen, bevor unser Microservice überhaupt ein Bestandteil der Microservice-Infrastruktur werden konnte. In High-End-Architekturen kommen noch weitere Schichten hinzu, wie z. B. Protokolle für die Echtzeit-Kommunikation mit Clients oder sogenannte Stellschrauben-Schnittstellen (Actuator-Endpoints).

Was auf den ersten Blick wie ein großer Nachteil aussieht, ist in Wirklichkeit der große Vorteil von Microservices: Eine skalierbare und aus verschiedenen Security-Aspekten ständig beleuchtete Infrastruktur als Basis für unternehmenskritische Anwendungen, entsteht durch Kombination verschiedener hersteller-unabhängiger Industrie-Standards (REST, 0AUTH, …) und sichert zudem durch ihre Micro-Modularität langfristig die Agilität bei neuen Kundenanforderungen.

Unsere Consort Microservice Experience stellt erprobte Kombinationen von Technologien zur Verfügung und unsere Experten stehen Ihren Entwicklern im Rahmen unserer Academy-Programme in jeder Projektphase mit Tipps & Tricks zur Seite:

Consort hilft Ihrem Unternehmen bei der Realisierung heterogener Microservice-Architekturen nach dem Motto AnyCloud:AnyLanguage!

Kommentar schreiben

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.