Löst die Service Mesh Platform Istio all meine Probleme?

12.05.2021Tom Trapp
Cloud Service Mesh kubernetes Istio Hands-on

In diesem TechUp wollen wir uns in die Cloud Dev Ops Richtung bewegen und den Service Mesh Provider Istio genauer unter die Lupe nehmen. Zu Beginn analysieren wir ein zugrundeliegendes Problem und wie uns das Service Mesh Prinzip helfen soll.

Das zu lösende Problem

Nehmen wir an, wir haben einen Onlineshop mit unterschiedlichen MicroServices, welche alle miteinander kommunizieren und so voneinander abhängig sind. Beispielsweise kann ein Produkt nur in den Warenkorb gelegt werden, wenn der Cart MS, der Inventory MS und den Price MS korrekt antworten.

In der aktuellen Implementation gibt es viele bewegliche Teile, die alle starr voneinander abhängig sind. Die einzelnen MicroServices kommunizieren direkt und ungesichert per Urls oder gar IP-Adresse miteinander, es besteht kein Loadbalancing und es herrscht keine Ausfallsicherheit. Jeder dieser MicroServices ist eigen implementiert, folgende Dinge sind direkt im Microservice implementiert:

  • Communication Configs (Endpoints, Ports etc.)
  • Security Handling (Authorization, Authentication)
  • Retry Logic
  • Logging
  • Metrics & Tracing

Das grosse Problem hinter dieser Architektur liegt auf der Hand, alles ist eigen implementiert und die MicroServices sind nicht mehr schlank, sondern beinhalten viel Overhead. Entwickler von MicroServices können sich nicht mehr auf die reine Businesslogik konzentrieren, sondern müssen Sachen die Logging, Tracing usw. implementieren.

Selbstverständlich konnte man hier Frameworks einsetzen, die alle diese Funktionalitäten bieten, man wäre dann aber weiterhin nicht Technologie und Sprachen unabhängig.

Der Lösungsansatz – Service Mesh

Service Mesh ist ein Pattern bzw. ein Paradigma welches in komplexen Microservice Architekturen zum Einsatz kommt.

Generell beschreibt das Pattern, dass sämtliche Kommunikation über eine dedizierte, voll integrierte Infrastruktur-Schicht kommunizieren. So kann man beispielsweise Traffic steuern, Loadbalancing implementieren oder genaue Überwachungsmetriken analysieren. Diese Implementation sind neu Teil der Infrastruktur-Schicht des Clusters, somit sind neu unsere Microservices auch Technologie und Sprachen unabhängig.

Ein zweiter grosser Vorteil dieses Paradigmas ist, dass die MicroServices sehr schlank sind, nur Business Logik enthalten und Entwickler sich nicht mehr um nicht business relevante Implementationen kümmern müssen.

In einem Service Mesh wird zu jedem Microservice ein sogenannter Sidecar (dt. Beiwagen) Container gestartet, welcher mit dem eigentlichen Container über localhost kommuniziert. So laufen beide Container im gleichen Pod, jeglicher Netzwerktraffic (Incoming & outgoing) läuft über den Sidecar Proxy.

Wie funktioniert Service Mesh

Wie in der oberen Grafik zu sehen ist, lässt sich ein Service Mesh in drei Teile aufteilen:

  • Control Plane – die Management- und Konfigurationsschicht der Service Mesh Architektur, deployed und konfiguriert die Sidecar Proxies und sammelt alle Daten
  • Data Plane – die Proxy Schicht, wo intelligenten Sidecar Proxies die Kommunikation zwischen MicroServices übernehmen
  • Anwendungen – die Anwendungsschicht, wo die eigentlichen Microservices laufen

Welche genauen Vorteile bietet ein Service Mesh aber nun in der Praxis?

  • Canary Releasing – bei neuen Versionen nur einen Teil der Benutzer auf die neue Version leiten, um neue Funktionalitäten isoliert zu testen, beispielsweise nur eine bestimmte Browserversion
  • A/B-Testing – einfaches Routing von bestimmten Benutzern in bestimmten Fällen zu einer anderen Version, Routing kann auf Basic von Urls oder gar HTTP Headern gemacht werden
  • Sicherheit – sämtlicher Datenverkehr im Cluster ist verschlüsselt, jeder ist korrekt authentifiziert und autorisiert
  • Transparenz – umfangreiches Monitoring, Logging und Tracing aller Calls im Cluster sowie der Kommunikation zwischen Microservices (Stichwort Bottleneck erkennen)
  • Robustheit – Timeout Handling, Retry Mechanismus, Circuit Breaking etc.

Selbstverständlich ist das Service Mesh Pattern nicht der einzige Ansatz zur Lösung des Problems, andere Ansätze wie z. B. ein API Gateway verfolgen aber nicht den dezentralisierten Ansatz von Microservices.

Istio

Istio ist eine Open Source Service Mesh Plattform, welche steuern, wie Microservices Daten miteinander teilen.

Der Grundstein wurde mit dem ersten Commit am 19.11.2016 im Zusammenspiel von Google, IBM und Lyft (Uber Konkurrent) gelegt. Heute, über 15'000 Commits später ist Istio in der Version 1.9 veröffentlicht und wird von einer breiten Community stetig weiterentwickelt. Riskiert man einen Blick unter die Haube sieht man, das Istio selbst fast ausschliesslich in Go geschrieben ist.

Aktuell gibt es viele unterschiedliche Service Mesh-Implementationen bzw. Plattformen, wobei Istio sich immer mehr durchsetzt und als beliebteste Service Mesh-Platform bekannt ist.

Was macht Istio genau?

Einfach gesagt hängt Istio an jeden MicroService einen kleinen Sidecar Container an, welcher sich um Themen wie Kommunikation, Sicherheit, Metriken & Logging usw. kümmern. Istio selbst ist nicht nur mit Kubernetes nutzbar, beispielsweise kann Istio auch in kombination mit Nomad und Consul bzw. sogar mit on-premise Systemen wie VMs genutzt werden.

Die Platform besteht im Grund aus zwei Komponenten, dem istiod Control Plan und dem Envoy Proxy. Das komplette Konstrukt bietet aber zahlreiche Integrationsmöglichkeiten, so kann beispielsweise ein Monitoring-System wie Prometheus, ein Dashboard wie Grafana oder ein Tracing System wie Jaeger eingebunden werden.

#Istio in der Praxis Nun wagen wir den ‘Deep Dive’ in die Praxis und installieren uns das Beispielprojekt von Istio, wir nutzen hier die latest Istio Version 1.9.4

Folgen wir den Steps auf der Getting Started Page von Istio selbst haben wir innerhalb weniger Minuten ein Istio Service Mesh ‘up and running’. Wir haben hierfür unsere Kubernetes Spielwiese auf einem Digital Ocean Cluster verwendet.

In diesem Beispiel nutzen wir das ‘bookinfo’ Example von Istio selbst, dies ist ein gutes Beispiel um Istio mit all seinen Komponenten kennenzulernen.

Grundsätzlich kann jedes Kubernetes Microservice Projekt in ein Istio Service Mesh umgewandelt werden. Dies geschieht über ein bestimmtes Label auf dem Namespace, damit Istio weiss, dass Envoy Sidecar Proxies injected werden sollen. Hier im Beispiel aktivieren wir die Istio-Injection für den default Namespace :

1
kubectl label namespace default istio-injection=enabled

Generell muss hier nicht an den eigentlichen K8s Ressourcen bzw. der Applikation angepasst werden. Es muss lediglich sichergestellt werden, dass die K8s Ressourcen immer über das Label app identifizierbar sind.

Sobald nun das komplette ‘bookinfo’-Beispiel läuft, wollen wir uns zwei Istio-Ressourcen genauer anschauen:

  • Gateway: der Einstiegspunkt von Aussen in den Service Mesh, genauer gesagt ist dies der Istio-Ingress Gateway
  • VirtualService: – zuständig für das Routing innerhalb des Service Meshes

Im bookinfo Beispiel finden wir diese beiden Ressourcen in der Datei samples/bookinfo/networking/bookinfo-gateway.yaml wieder, standardmässig wird dort ein Gateway nach Aussen auf Port 80 geöffnet. Mit dem VirtualService werden bestimmte Routen an unseren K8s productpage Service auf Port 9080 weitergeleitet. Dieses Beispiel wollen wir nun anpassen und erreichen, das unsere Beispielanwendung nur von einem bestimmten Host und nur mit einem bestimmten Cookie aufgerufen werden darf.

Hierfür müssen wir lediglich die Virtual Service Definition anpassen, unsere match Clause macht neu ein Regex Matching auf den HTTP Header cookie. Ausserdem schränken wir die hosts ein, dass nur ein bestimmter Host die Anwendung aufrufen kann.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# samples/bookinfo/networking/bookinfo-gateway.yaml
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: bookinfo
spec:
  hosts:
    - "test.techup.xy"
  gateways:
    - bookinfo-gateway
  http:
    - match:
        - headers:
            cookie:
              regex: "^(.*;?)?(user=b-nova)(;.*)?"
      route:
        - destination:
            host: productpage
            port:
              number: 9080

Nachdem die neue Konfiguration mit kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml applied haben ist unsere Beispielanwendung nur noch über einen speziellen Command aufrufbar. Wir nutzen hier ein HTTP Scratch File in IntelliJ, dies sieht wie folgt aus:

1
2
3
GET http://<external IP>/productpage
Host: test.techup.xy
Cookie: user=b-nova

Damit erfüllen wir beide Bedingungen unseres VirtualServices und werden korrekt zu unserer productpage Anwendung weitergeleitet.

Sollte es hier Fehler geben hilft uns das Kiali-Dashboard des Beispiels weiter, um genauere Logs, Traces o. ä. einsehen zu können. Dieses Dashboard können wir nach dem Rollout starten mit:

1
istioctl dashboard kiali

Ein weiteres nützliches Feature von Istio ist die Analyze Funktion, welche uns Fehler oder Probleme in unsere Konfiguration aufzeigt:

1
istioctl analyze

#Gibt es einen Haken? Es klingt super, ist schnell installiert und sieht sehr praktisch aus – wo ist der Haken?

Der Haken bei jeder Service Mesh Implementation ist der mentale, physische und logische Mehraufwand, welcher durch den Einsatz von z. B. Istio entsteht. Nicht ausser Acht zu lassen ist ebenfalls der Fakt, dass sich die Performance verschlechtern wird und das Cluster mehr Ressourcen brauchen wird. Hier ist wichtig zu verstehen, wieso und vor allem, ob man eine Service Mesh Architektur wirklich benötigt.

Generell macht ein Service Mesh sicher in wachsenden, komplexer werdenden Microservice Architekturen Sinn. Fest steht, dass Istio im Fehlerfall die Analyse um einiges einfacher macht und beschleunigt.

Sie benötigten Hilfe bei Ihrer Service Mesh-Implementation oder haben weitere Fragen? Kontaktieren Sie uns!

Tom Trapp

Tom Trapp – Problemlöser, Innovator, Sportler. Am liebsten feilt Tom den ganzen Tag an der moderner Software und legt viel Wert auf objektiv sauberen, leanen Code.