Im letzten Blog Post zum Thema ServiceMesh und ServiceDiscovery wurden die Grundlagen dieser Themtik beschrieben.
Die wesentlichen, technischen Herausforderungen sind hier noch einmal aufgelistet:
Service Discovery - Wie finden sich die Services?
Sicherheit (Security) - Welcher Service darf mit welchem sprechen (über sicheres mTLS)?
Routing - Wie wird zu den einzelnen Services geroutet?
Resilienz - Wie kann die Widerstandsfähigkeit eines Softwaresystems mit Mitteln der Infrastruktur verbessert werden (bspw. circuit breaker)?
Was ist ein ServiceMesh?
Dieser Abschnitt erklärt die grundlegenden, fundamentalen Komponenten und deren Funktionsweise im Service Mesh.
Control Plane
Die zentrale Control Plane eines Service Mesh hat folgende Aufgaben:
Service Discovery und Service Catalog
Autorisierung und Konfiguration der Proxies der Data Plane.
Data Plane
Die verteilte Data-Plane ist für die Verbindung und das Routing zwischen den Services zuständig.
Funktionsweise
Ein Proxy wird zusammen mit der Service-Instanz platziert, welcher den eingehenden Verkehr regelt (SideCar)
Der Client-Agent instanziert den Proxy und registriert ihn als Service
Der Proxy wird mit einem Port konfiguriert, der für den Dienst verwendet wird, sowie mit Ports für alle Upstream-Ziele, mit denen der Dienst eine Verbindung herstellen möchte.
Anmerkung: Es gibt auch ServiceMesh Implementierungen, welche ohne einen sog. SideCar-Proxy auskommen. In manchen Umgebungen kann dies ein valider und sinnvoller Ansatz sein - wir sehen in unseren Projekten hinsichtlich der Anforderungen an Multi-Plattform, Security & Governance sowie Compliance (z.B. ein Cert der eigenen CA für jeden Service) den SideCar-Ansatz jedoch in der Regel als den passendstem.
Service Discovery
Erklärung von "Service Discovery" - also wie finden Services zueinander - an Hand eines simplen Beispiels mit 2 Services: "web" und "db":
Der Proxy des Service “web” verwendet die den Namen des Service “db”, um den Standort der DB abzufragen
Der lokale Agent gibt dem Proxy die IP-Adresse/Port einer gesunden DB-Instanz zurück.
Security
Wie war es früher (und oftmals heute noch)?
Firewalls regeln auf Basis von IP und Ports welche Kommunikation (Traffic Pattern) erlaubt ist:
Wie könnte es für ein Service Mesh aussehen?
In dynamischen Multi-Plattform oder Multi-Cloud Umgebungen wird die Pflege von Firewall-Regeln (ACL) zu einer nahezu unmöglichen Aufgabe. Von der Herausforderung “East-West” vs. “North-South” Traffic einmal ganz abgesehen:
Besser: Service Based Security - Intentions
Über einen Service Graphen wird geregelt, welcher Service mit welchem anderen Service kommunizieren darf. Unabhängig wo diese Services betrieben werden. Es wird die Identität eines Services verifiziert (dazu ist eine hochgradig automatisierte TLS CA in ein Mesh integriert - Basis: SPIFFE).
Best-Practice Tipp: HashiCorp Vault kann eine (eigene) und hochgradig automatisierte CA für das ServiceMesh darstellen.
Diese Berechtigungen bezeichnet man als "Intention". Sie kann bis auf die Semantik von OSI Layer 7 (z.B. einem API Call) parametrisiert werden.
Service Based Security
Der lokale Agent gibt auch den URI für die erwartete Identität des Dienstes zurück, mit dem er verbunden ist.
Proxies zwischen Web und Datenbank starten TLS-Handshake zur Authentifizierung der Identität.
Der DB-Proxy sendet die Authorisierungsanfrage an seinen lokalen Agenten.
Der lokale Agent autorisiert die Verbindung auf der Grundlage der lokal zwischengespeicherten Intention.
mTLS wird aufgebaut
Routing
Multi Plattform
Die zentralen Herausforderungen sind
Überlappende IP Ranges
Mix / Integration von Kubernetes mit VM oder Bare-Metal Workloads
Security (nicht alle Ports öffnen müssen, etc.)
Multi Cloud
Wie zu Beginn bereits erwähnt, ist Multi Cloud Networking noch härter…
Direct Connect, Express Route, BGP und dann noch ein VPN darüber?
Wirklich? Eher nicht!
Dieses Thema behandeln wir in einem der folgenden Blog Posts, da die Komplexität und der Umfang dieses Bereichs diesen Artikel sprengen würde.
Resilienz
Jede Kette ist nur so stark wie ihr schwächstes Glied
Dieses weitbekannte Zitat gilt natürlich auch für Software Systeme. Im schlimmsten Fall kann ein Teilsystem zum Ausfall des gesamten Systems führen, wenn nicht entsprechende Maßnahmen bereits im Vorfeld getroffen wurden.
Bevor Service Meshes populär wurden, konnten Entwickler mit unterschiedlichen Frameworks Maßnahmen treffen. Eines der wohl bekanntesten Beispiele war Hystrix welches jedoch nicht mehr aktiv weiter entwickelt wird. Je nach Framework können unterschiedliche Resilienzpatterns wie Retries, Fallbacks oder Circuit Breaker imTeilsystem berücksichtigt werden (konfigurativ oder programmatisch).
Das der ausschließliche Einsatz eines Frameworks bereits die Resilienz des Gesamtsystems erhöht kann jedoch ein Trugschluss sein. Ist nur ein Teilsystem nicht entsprechend konfiguriert, kann dies die Maßnahmen die in den anderen Teilsystemen getroffen wurden wirkungslos machen.
An dieser Stelle kommt nun ein Service Mesh ins Spiel. Viele Resilienzpatterns sind unter anderem aus dem genannten Grund in der Infrastruktur sinnvoller angesiedelt. Die so konfigurierten Maßnahmen sind transparent für die Teilsysteme und können unabhängig von diesen parametriert werden. Daraus ergibt sich der weitere Vorteil, dass Anpassungen an den Resilienzpattern flexibler und unabhängig von Applikationsreleases durchgeführt werden können.
Sind durch den Einsatz eines Service Mesh die Frameworks nun obsolet geworden? Diese Frage kann klar mit Nein beantwortet werden. Manche Patterns können nämlich nicht auf sinnvolle Art und Weise auf Infrastrukturebene zur Verfügung gestellt werden. Das klassische Beispiel dazu sind Fallbacks, da es sich bei der Entscheidung über den konkreten Fallback in der Regel um eine fachliche Entscheidung handelt, die im Applikationscode berücksichtigt wird.
Die Empfehlung ist daher, sämtliche Resilienzpatterns die besser auf Infrasturkturebene aufgehoben sind, auch genau dort zur Verfügung zu stellen. Bei Patterns die besser im Teilsystem direkt implementiert werden, sollte darauf geachtet werden das auf standardisierte Frameworks - wie beispielsweise MicroProfile Fault Tolerance - im Java-Fall - gesetzt wird.
Abschliessend wollen wir ein Summary geben und Fazit ziehen:
Warum Service Mesh - und warum Consul?
Warum entwickeln wir uns hin zu nativen Cloud-Anwendungen?
Wir wollen in der Lage sein, Funktionen schneller zu entwickeln und bereitzustellen, um schneller auf die Bedürfnisse unserer Kunden reagieren können.
Wir wollen alles automatisieren, um Risiken zu verringern und die Ausfallsicherheit zu erhöhen.
Und schließlich wollen wir die Anwendung überall ausführen können, ohne sie dafür verändern zu müssen - kein Lock-In und ein echtes “RUN ANYWHERE”.
Schnelles Erstellen und Bereitstellen von Anwendungen
Automatisieren von Abläufen, um das Risiko von Fehlern
Architektur für Ausfallsicherheit
Vermeidung von Lock In eines Plattformbetreibers
Auswahl der besten und wirtschaftlichsten Services
Failover zwischen Plattformen oder Cloud-Anbietern
HashiCorp Consul deckt genau diese (und viele weitere Punkte) optimal ab. Mit höchster Security, Governance und Compliance. Natürlich auch mit voller Observability und Telemetrie.
Und genau hier zahlt ein ServiceMesh auf die Unternehmensziele ein.
Warum HashiCorp Consul?
Das aus unserer Sicht ausgereifteste ServiceMesh (Connect)
Single GO Binary, läuft in Bare Metal, VM, Container und Cloud (z.B AWS Lambda)
SPIFFE/SIRE
Intent based Networking & Security
Optimales Tracing
Features wie z.B. :
Canary Deployments
Splitter / Circuit Breaker
API Gateway
Rate Limiting
Blue / Green Deployments
Bestens in Hashicorp Ecosystem (z.B. Vault und Terraform) integriert
Eignet sich ideal für einen modernen, probaten "Plattform Ops"-Ansatz
Enterprise Support durch Hersteller HashiCorp
Design & Implementation auf höchstem Niveau durch FullStackS
Comments