Softwarearchitektur verstehen und entscheiden

Aaron KreisÜber mich
Integration

Service Mesh

Netzwerkfunktionen in eine eigene Infrastrukturschicht verlagern

Die Idee und ihr Nutzen

Der Schadendienst, der Vertragsdienst, der Zahlungsdienst und weitere Programme einer Versicherung rufen einander ständig über das Netzwerk auf. Die Versicherung möchte alle Verbindungen nach denselben Regeln verschlüsseln und messen, wie lange jeder Aufruf dauert, ohne dass jedes Team dieselbe Netzwerktechnik in sein Programm einbauen muss. Dafür bekommt jedes Programm einen Proxy, also einen Vermittler, der den Netzwerkverkehr des Programms entgegennimmt und weiterleitet. Alle Proxys sind Exemplare desselben Programms. Weil ein Proxy nur den Netzwerkverkehr weiterleitet, spielt es keine Rolle, in welcher Programmiersprache das Programm geschrieben ist, dessen Netzwerkverkehr er weiterleitet. Eine zentrale Steuerung, die Mesh-Steuerung, verteilt die Regeln an alle Proxys, und die Proxys verschlüsseln die Verbindungen untereinander und messen jeden Aufruf. Proxys und Mesh-Steuerung zusammen heißen Service Mesh, auf Deutsch etwa Dienstgeflecht. „Geflecht“ meint die vielen Verbindungen, über die jeder Proxy mit den Proxys der anderen Programme verbunden ist.

Bausteine: Mesh-Steuerung: verteilt die Regeln an alle Proxys; Schadendienst: fragt nach der Deckung für 4711; Proxy A: übernimmt den Netzwerkverkehr des Schadendienstes; Proxy B: übernimmt den Netzwerkverkehr des Vertragsdienstes; Vertragsdienst: entscheidet fachlich. Verbindungen: Schadendienst — Proxy A; Proxy A — Proxy B (verschlüsselt, gemessen); Proxy B — Vertragsdienst; Mesh-Steuerung → Proxy A; Mesh-Steuerung → Proxy B. Jedes Programm spricht nur über seinen Proxy; die Mesh-Steuerung verteilt die Regeln an alle Proxys.

Wie funktioniert es?

Die Mesh-Steuerung verteilt an Proxy A, den Vermittler des Schadendienstes, und an Proxy B, den Vermittler des Vertragsdienstes, die Regel, nur verschlüsselt zu übertragen und den Ausweis der Gegenseite zu prüfen. Proxy A und Proxy B weisen sich gegenseitig mit digitalen Ausweisen aus. Ein digitaler Ausweis ist ein Zertifikat, also eine elektronisch unterschriebene Bescheinigung, welches Programm eine Verbindung aufbaut oder annimmt. Prüfen beide Proxys den Ausweis des jeweils anderen, spricht man von gegenseitiger Prüfung, englisch mutual TLS; TLS ist das übliche Verfahren zum Verschlüsseln von Netzwerkverbindungen. Dann fragt der Schadendienst wie gewohnt beim Vertragsdienst „Deckt der Vertrag Fall 4711?“. Die Anfrage läuft zuerst durch Proxy A, und Proxy A schickt sie verschlüsselt an Proxy B. Proxy B reicht die Anfrage an den Vertragsdienst weiter. Der Vertragsdienst prüft den Vertrag und trifft die fachliche Entscheidung „gedeckt“. Die Antwort läuft in umgekehrter Richtung über Proxy B verschlüsselt zu Proxy A und von Proxy A zum Schadendienst zurück. Zum Schluss melden Proxy A und Proxy B als Messwerte, wie lange der Aufruf gedauert hat und ob er technisch gelungen ist.

Alle Proxys zusammen bezeichnet man auch als Datenebene, englisch data plane. Häufig läuft neben jedem Programm ein eigener Proxy; diese Anordnung heißt Sidecar, englisch für Beiwagen. Manche Produkte setzen stattdessen einen gemeinsamen Proxy je Server ein. Die Mesh-Steuerung ist ein eigenes Programm und leitet selbst keine Aufrufe weiter; sie heißt auch Steuerungsebene, englisch control plane. Ändern sich Regeln oder Programme, schickt die Mesh-Steuerung allen Proxys die geänderten Regeln. Neben der Verschlüsselung legen die Regeln auch fest, welche Programme miteinander sprechen dürfen, und die Proxys prüfen diese Erlaubnis bei jedem Aufruf. Die Programme selbst müssen für das Service Mesh meist nicht geändert werden. Fachliche Regeln enthält das Service Mesh nicht: Ob ein Vertrag einen Schaden deckt oder eine Zahlung erlaubt ist, entscheidet weiterhin das jeweilige Programm.

Erlaubt die Regel der Mesh-Steuerung die Verbindung nicht oder fehlt ein gültiger Ausweis, weist Proxy B die Anfrage ab, bevor sie den Vertragsdienst erreicht. Wird der Aufruf langsam oder scheitert er technisch, zeigen die Messwerte, zwischen welchen beiden Proxys der Aufruf langsam war oder scheiterte. Lehnt der Vertragsdienst die Deckung dagegen fachlich ab, weil der Vertrag den Schaden nicht abdeckt, ist das für die Proxys ein erfolgreicher Aufruf, und die Messwerte zeigen davon nichts. Baut ein Programm an seinem Proxy vorbei eine Verbindung zu einem Ziel ohne Proxy auf, etwa zu einem fremden Dienst, bleibt diese Verbindung unverschlüsselt und ungemessen.

Service Mesh: die Deckungsanfrage läuft verschlüsselt über zwei Proxys

Beteiligte: Mesh-Steuerung: verteilt Regeln an alle Proxys; Schadendienst: fragt nach der Deckung für 4711; Proxy A: Vermittler des Schadendienstes; Proxy B: Vermittler des Vertragsdienstes; Vertragsdienst: entscheidet fachlich; Messwerte: Dauer und technische Fehler je Aufruf. Ablauf: 1. Die Mesh-Steuerung verteilt an Proxy A die Regel, nur verschlüsselt zu übertragen und den Ausweis der Gegenseite zu prüfen. 2. Die Mesh-Steuerung verteilt dieselbe Regel an Proxy B. Proxy A und Proxy B weisen sich gegenseitig mit digitalen Ausweisen aus. 3. Der Schadendienst fragt wie gewohnt beim Vertragsdienst „Deckt der Vertrag Fall 4711?“. Die Anfrage läuft zuerst durch Proxy A. 4. Proxy A schickt die Anfrage verschlüsselt an Proxy B. 5. Proxy B reicht die Anfrage an den Vertragsdienst weiter. 6. Der Vertragsdienst trifft die fachliche Entscheidung „gedeckt“, nicht das Service Mesh. 7. Die Antwort des Vertragsdienstes läuft über Proxy B verschlüsselt zurück zu Proxy A. 8. Der Schadendienst erhält die Antwort von Proxy A. 9. Proxy A und Proxy B melden Dauer und technische Fehler des Aufrufs. Eine fachliche Ablehnung durch den Vertragsdienst wäre für die Proxys ein erfolgreicher Aufruf.

Wann ist es sinnvoll und wann nicht?

Ein Service Mesh lohnt sich

  • Viele Programme brauchen einheitliche Regeln für ihre Kommunikation. Dazu gehören durchgängige Verschlüsselung und die gegenseitige Prüfung der Ausweise. Baut jedes Team diese Regeln selbst in sein Programm ein, setzt zum Beispiel das Team des Schadendienstes die Verschlüsselung in Java um und das Team des Vertragsdienstes in Python, und beide Teams müssen ihre Umsetzung aktuell halten. Die Umsetzungen weichen dann oft voneinander ab, und eine unverschlüsselte Verbindung fällt womöglich niemandem auf.
  • Regeln sollen sich ändern lassen, ohne dass jedes Team sein Programm anpasst. Steckt die Verschlüsselung in den Programmen, müssen bei einer neuen Art der Verschlüsselung die Teams von Schadendienst, Vertragsdienst und Zahlungsdienst ihre Programme ändern und neu ausliefern. Mit Service Mesh ändert das Team, das das Service Mesh betreibt, nur die Regel in der Mesh-Steuerung.
  • Programme in verschiedenen Programmiersprachen sollen dieselben Messwerte liefern, ohne dass jedes Team die Messung selbst einbaut. Baut jedes Team die Messung selbst ein, misst jedes Programm auf eigene Weise, und die Dauer der Aufrufe lässt sich zwischen den Programmen nicht vergleichen. Im Service Mesh messen alle Proxys auf dieselbe Weise, weil sie Exemplare desselben Programms sind.

Ein Service Mesh ist nicht das Richtige

  • Es gibt nur wenige Programme, etwa nur den Schadendienst und den Vertragsdienst. Proxys und Mesh-Steuerung wären dann zusätzliche Programme, die rund um die Uhr laufen müssen, nur um zwei Programme zu verbinden. Dann binden das Team des Schadendienstes und das Team des Vertragsdienstes eine gemeinsame Programmbibliothek für Verschlüsselung und Messung in ihre Programme ein. Eine Programmbibliothek ist fertiger Code, den ein Programm einbindet. Proxys und Mesh-Steuerung muss dann niemand betreiben. Die Programmbibliothek muss allerdings in jeder verwendeten Programmiersprache vorhanden sein, und beide Teams müssen sie in ihrem Programm aktualisieren.
  • Es geht vor allem um Anfragen von außen, etwa aus dem Kundenportal. Ein Service Mesh regelt aber die Aufrufe der Programme untereinander. Dann richtet die Versicherung ein API Gateway ein, einen einzelnen geschützten Eingang. Das Kundenportal schickt jede Anfrage an das API Gateway, und das API Gateway prüft die Anfrage und leitet sie an das zuständige Programm weiter. Proxys für jedes Programm und eine Mesh-Steuerung entfallen.
  • Nur ein einzelnes Programm braucht einen Proxy für Verschlüsselung und Messung, etwa nur der Zahlungsdienst. Eine Mesh-Steuerung hätte dann Regeln für einen einzigen Proxy zu verteilen. Dann startet das Team des Zahlungsdienstes auf demselben Rechner einen einzelnen Sidecar, ein Hilfsprogramm, über das der Netzwerkverkehr des Zahlungsdienstes läuft. Die Regeln trägt das Team in die Einstellungsdatei des Sidecars ein. Eine Mesh-Steuerung, die rund um die Uhr betrieben werden muss, entfällt.
  • Kein Team kann die Proxys und die Mesh-Steuerung rund um die Uhr betreiben. Dann bauen die Teams Verschlüsselung und Messung mit einer gemeinsamen Programmbibliothek in ihre Programme ein, und jedes Team betreut nur sein eigenes Programm. Ein Service Mesh ohne Betreuung rund um die Uhr würde Störungen verursachen: Verteilt die Mesh-Steuerung eine falsche Regel oder läuft ein Ausweis ab, scheitern Aufrufe zwischen fehlerfreien Programmen, bis jemand eingreift.
  • Die Programme laufen nicht auf einer Plattform, die das Einsetzen und Aktualisieren der Proxys übernimmt. Eine solche Plattform ist Kubernetes, eine verbreitete Plattform zum Betrieb von Anwendungen auf vielen Servern. Dann bauen die Teams Verschlüsselung und Messung mit einer gemeinsamen Programmbibliothek in ihre Programme ein, und die Programmbibliothek wird mit jeder neuen Version des Programms ausgeliefert. Ohne eine solche Plattform müsste das Betriebsteam jeden Proxy von Hand einrichten und bei jeder neuen Version aktualisieren, und ein vergessener Proxy bliebe veraltet.

Nachteile und typische Fehler

Proxys und Mesh-Steuerung sind zusätzliche Programme, die das Team des Service Mesh einrichten, überwachen und zusammen mit den Ausweisen aktuell halten muss. Scheitert ein Aufruf, muss die Fehlersuche neben Schadendienst und Vertragsdienst auch Proxy A und Proxy B einbeziehen. Jeder Proxy fügt eine kleine Verzögerung hinzu und verbraucht Rechenzeit und Arbeitsspeicher; bei vielen Programmen summiert sich das zu spürbaren Serverkosten. Verteilt die Mesh-Steuerung eine falsche Regel, scheitern Aufrufe zwischen Programmen, die selbst fehlerfrei sind. Weist Proxy B wegen einer falschen Regel zum Beispiel die Anfragen des Schadendienstes ab, können weder das Team des Schadendienstes noch das Team des Vertragsdienstes den Fehler selbst beheben. Beide Teams warten, bis das Team, das das Service Mesh betreibt, die Regel berichtigt.

Typische Fehler und woran man sie erkennt:

  • Doppelte Ausführung durch Wiederholung: Manche Service Meshes wiederholen gescheiterte Aufrufe automatisch in den Proxys, und die Regel gilt auch für Anfragen, die etwas verändern. Der Schadendienst schickt über Proxy A eine Zahlungsanweisung an den Zahlungsdienst. Der Zahlungsdienst legt die Zahlung an, doch seine Antwort geht bei einer kurzen Netzstörung verloren. Proxy A wertet den Aufruf deshalb als gescheitert und schickt dieselbe Zahlungsanweisung noch einmal. Der Zahlungsdienst legt dieselbe Zahlung ein zweites Mal an. Erkennbar ist das an doppelten Zahlungen nach kurzen Netzstörungen.
  • Programm ohne Proxy: Ein Programm wird ohne Proxy gestartet, etwa weil es außerhalb der Plattform des Service Mesh läuft. Ruft das Programm ein anderes Programm ohne Proxy auf, ist die Verbindung weder verschlüsselt noch gemessen, und weil sie in den Messwerten fehlt, fällt das niemandem auf. Ruft das Programm den Vertragsdienst auf, weist Proxy B die Anfrage ab, weil ihr ein gültiger Ausweis fehlt. Erkennbar ist das an Programmen, die in der Übersicht der Mesh-Steuerung fehlen.
  • Abgelaufene Ausweise: Die digitalen Ausweise gelten nur eine begrenzte Zeit, und der Ausweis von Proxy A wird nicht rechtzeitig erneuert. Proxy B prüft bei der nächsten Anfrage den abgelaufenen Ausweis und weist die Anfrage ab, obwohl Schadendienst und Vertragsdienst fehlerfrei sind. Erkennbar ist das an vielen gleichzeitig abgewiesenen Verbindungen ohne Änderung an den Programmen.
  • Fachliche Fehler übersehen: Die Versicherung wertet nur die Messwerte der Proxys aus. Lehnt der Vertragsdienst viele Deckungen zu Unrecht ab, erscheinen diese Aufrufe in den Messwerten als erfolgreich. Erkennbar ist das erst an Beschwerden oder an fachlichen Auswertungen außerhalb des Service Mesh.

Weiterführend

Verwandte Ansätze

  • Distributed Tracing: verfolgt einen Vorgang über viele Programme hinweg. Die Proxys eines Service Mesh können dafür Messpunkte liefern, die Programme müssen die Kennung des Vorgangs aber oft selbst weiterreichen.
  • Zero Trust: ein Sicherheitsgrundsatz, nach dem jede Verbindung geprüft wird, auch innerhalb des eigenen Netzes. Ein Service Mesh kann diesen Grundsatz für Aufrufe zwischen Programmen umsetzen.
  • Retry with Backoff: wiederholt gescheiterte Aufrufe nach wachsenden Pausen. Manche Service Meshes bieten solche Wiederholungen in den Proxys an.

Quellen

  • Istio: What is Istio?: Projektdokumentation eines verbreiteten Service Mesh; beschreibt Proxys und Steuerung, den Betrieb mit einem Proxy je Programm oder je Server, gegenseitige Prüfung der Ausweise und automatische Messwerte.
  • Linkerd: What is a service mesh?: erklärt Datenebene und Steuerungsebene, Proxys neben jedem Programm, verschlüsselte Verbindungen mit gegenseitiger Prüfung und Wiederholungen, die nur bei wiederholbaren Anfragen erfolgen sollen.