ZurĂŒck zu Mikrodiensten mit Istio. Teil 2

ZurĂŒck zu Mikrodiensten mit Istio. Teil 2

Anmerkung des Übersetzers.: Erster Teil dieser Reihe war der EinfĂŒhrung in die Möglichkeiten von Istio und deren praktischer Demonstration gewidmet. Nun geht es um komplexere Aspekte der Konfiguration und Nutzung dieses Service Mesh, insbesondere um die fein justierbare RoutenfĂŒhrung und das Management des Netzwerkverkehrs.

Wir erinnern auch daran, dass in dem Artikel Konfigurationen (Manifeste fĂŒr Kubernetes und Istio) aus dem Repository verwendet werden istio-mastery.

Verkehrsmanagement

Mit Istio ergeben sich im Cluster neue Möglichkeiten, die Folgendes ermöglichen:

  • Dynamische RoutenfĂŒhrung von Anfragen: Canary-Rollouts, A/B-Tests;
  • Lastverteilung: einfach und widerspruchsfrei, basierend auf Hashes;
  • Wiederherstellung nach AusfĂ€llen: Timeouts, Wiederholungen, Circuit Breakers;
  • StörungseinfĂŒhrung: Verzögerungen, Anfragelösungen usw.

Im Fortgang des Artikels werden diese Möglichkeiten anhand einer ausgewĂ€hlten Anwendung veranschaulicht und gleichzeitig neue Konzepte vorgestellt. Das erste dieser Konzepte wird sein DestinationRules (d.h. Regeln fĂŒr den EmpfĂ€nger von Verkehr/Anfragen — Anm. d. Ü.), mit deren Hilfe wir A/B-Tests aktivieren.

A/B-Tests:  DestinationRules in der Praxis

A/B-Tests werden in FĂ€llen angewendet, in denen es zwei Versionen einer Anwendung gibt (normalerweise unterscheiden sie sich visuell) und wir uns nicht zu 100% sicher sind, welche von ihnen das Nutzererlebnis verbessern wird. Daher starten wir beide Versionen gleichzeitig und sammeln Metriken.

FĂŒr die Bereitstellung der zweiten Version des Frontends, die zur Demonstration von A/B-Tests erforderlich ist, fĂŒhren Sie den folgenden Befehl aus:

$ kubectl apply -f resource-manifests/kube/ab-testing/sa-frontend-green-deployment.yaml
deployment.extensions/sa-frontend-green erstellt

Das Manifest des Deployments fĂŒr die "grĂŒne Version" unterscheidet sich an zwei Stellen:

  1. Das Image basiert auf einem anderen Tag — istio-green,
  2. Pods haben das Label version: green.

Da beide Deployments das Label app: sa-frontend, Anfragen, die vom virtuellen Dienst sa-external-services an den Dienst sa-frontend, weitergeleitet werden, an alle seine Instanzen umgeleitet werden und die Last gemĂ€ĂŸ dem Round-Robin-Algorithmus, was zu folgender Situation fĂŒhrt:

ZurĂŒck zu Mikrodiensten mit Istio. Teil 2
Angeforderte Dateien nicht gefunden

Diese Dateien wurden nicht gefunden, weil sie in verschiedenen Versionen der Anwendung unterschiedlich benannt sind. Lassen Sie uns dies ĂŒberprĂŒfen:

$ curl --silent http://$EXTERNAL_IP/ | tr '"' 'n' | grep main
/static/css/main.c7071b22.css
/static/js/main.059f8e9c.js
$ curl --silent http://$EXTERNAL_IP/ | tr '"' 'n' | grep main
/static/css/main.f87cd8c9.css
/static/js/main.f7659dbb.js

Das bedeutet, dass index.html, der eine Version statischer Dateien anfordert, kann vom Lastenausgleich auf Pods geleitet werden, die eine andere Version haben, wo aus verstĂ€ndlichen GrĂŒnden solche Dateien nicht existieren. Daher mĂŒssen wir eine EinschrĂ€nkung setzen: „Die gleiche Version der Anwendung, die index.html zurĂŒckgegeben hat, muss auch nachfolgende Anfragen bedienen».

Wir erreichen das Ziel durch konsistenten Lastenausgleich auf Hash-Basis (Consistent Hash Loadbalancing). In diesem Fall werden Anfragen von einem Client an dasselbe Backend-Exemplar gesendet, wobei eine vordefinierte Eigenschaft verwendet wird — zum Beispiel ein HTTP-Header. Dies wird mit DestinationRules umgesetzt.

DestinationRules

Nachdem VirtualService hat die Anfrage an den richtigen Dienst weitergeleitet, mit DestinationRules können wir Richtlinien festlegen, die auf den Datenverkehr angewendet werden, der an die Exemplare dieses Dienstes gerichtet ist:

ZurĂŒck zu Mikrodiensten mit Istio. Teil 2
Verwaltung des Datenverkehrs mit Istio-Ressourcen

Hinweis: Der Einfluss von Istio-Ressourcen auf den Netzwerkverkehr wird hier in einer verstÀndlicheren Form dargestellt. Genau genommen wird die Entscheidung, an welches Exemplar die Anfrage gesendet wird, vom Envoy im Ingress Gateway getroffen, das in CRD konfiguriert ist.

Mit Destination Rules können wir die Lastenverteilung so konfigurieren, dass konsistente Hashes verwendet und garantiert werden, dass Antworten desselben Dienstexemplars an denselben Benutzer gehen. Die folgende Konfiguration ermöglicht dies (destinationrule-sa-frontend.yaml):

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: sa-frontend
spec:
  host: sa-frontend
  trafficPolicy:
    loadBalancer:
      consistentHash:
        httpHeaderName: version   # 1

1 — Der Hash wird basierend auf dem Inhalt des HTTP-Headers generiert version.

Wenden Sie die Konfiguration mit dem folgenden Befehl an:

$ kubectl apply -f resource-manifests/istio/ab-testing/destinationrule-sa-frontend.yaml
destinationrule.networking.istio.io/sa-frontend erstellt

FĂŒhren Sie nun den Befehl unten aus und stellen Sie sicher, dass Sie die gewĂŒnschten Dateien erhalten, wenn Sie den Header angeben version:

$ curl --silent -H "version: yogo" http://$EXTERNAL_IP/ | tr '"' 'n' | grep main

Hinweis: Um verschiedene Werte im Header hinzuzufĂŒgen und die Ergebnisse direkt im Browser zu testen, können Sie diese Erweiterung fĂŒr Chrome (oder diese hier fĂŒr Firefox — Anm. d. Übs.).

Im Allgemeinen bietet DestinationRules mehr Möglichkeiten im Bereich Load Balancing — Details erfragen Sie bitte bei offiziellen Dokumentation.

Bevor wir mit der weiteren Untersuchung von VirtualService fortfahren, entfernen wir die "grĂŒne Version" der Anwendung und die entsprechende Regel zur Verkehrslenkung, indem wir die folgenden Befehle ausfĂŒhren:

$ kubectl delete -f resource-manifests/kube/ab-testing/sa-frontend-green-deployment.yaml
deployment.extensions "sa-frontend-green" gelöscht
$ kubectl delete -f resource-manifests/istio/ab-testing/destinationrule-sa-frontend.yaml
destinationrule.networking.istio.io "sa-frontend" gelöscht

Mirroring: Virtual Services in der Praxis

Shadowing („Maskierung“) oder Mirroring („Spiegelung“) wird in FĂ€llen angewendet, in denen wir eine Änderung in der Produktion testen möchten, ohne die Endbenutzer zu beeinflussen: Dazu duplizieren wir (spiegeln) die Anfragen an ein zweites Exemplar, wo die erforderlichen Änderungen vorgenommen wurden, und beobachten die Auswirkungen. Vereinfacht gesagt, ist es, wenn dein Kollege das kritischste Problem auswĂ€hlt und einen Pull-Request in Form eines riesigen Klumpens Schmutz macht, sodass niemand tatsĂ€chlich eine ÜberprĂŒfung vornehmen kann.

Um dieses Szenario in Aktion zu testen, erstellen wir ein zweites Exemplar von SA-Logic mit Fehlern (fehlerhaft), indem wir den folgenden Befehl ausfĂŒhren:

$ kubectl apply -f resource-manifests/kube/shadowing/sa-logic-service-buggy.yaml
deployment.extensions/sa-logic-buggy erstellt

Und jetzt fĂŒhren wir den Befehl aus, um sicherzustellen, dass alle Exemplare mit app=sa-logic auch die entsprechenden Versionslabels haben:

$ kubectl get pods -l app=sa-logic --show-labels
NAME                              READY   LABELS
sa-logic-568498cb4d-2sjwj         2/2     app=sa-logic,version=v1
sa-logic-568498cb4d-p4f8c         2/2     app=sa-logic,version=v1
sa-logic-buggy-76dff55847-2fl66   2/2     app=sa-logic,version=v2
sa-logic-buggy-76dff55847-kx8zz   2/2     app=sa-logic,version=v2

Dienst sa-logic zielt auf Pods mit dem Label app=sa-logic, daher werden alle Anfragen ĂŒber alle Exemplare verteilt:

ZurĂŒck zu Mikrodiensten mit Istio. Teil 2


 aber wir möchten, dass die Anfragen an die Exemplare mit der Version v1 geleitet und auf die Exemplare mit der Version v2 gespiegelt werden:

ZurĂŒck zu Mikrodiensten mit Istio. Teil 2

Wir erreichen dies durch ein VirtualService in Kombination mit einer DestinationRule, wobei die Regeln Teilmengen und Routen des VirtualService zu einer bestimmten Teilmenge definieren.

Definition von Teilmengen in Destination Rules

Teilmenge (subsets) werden durch die folgende Konfiguration definiert (sa-logic-subsets-destinationrule.yaml):

apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
  name: sa-logic
spec:
  host: sa-logic    # 1
  subsets:
  - name: v1        # 2
    labels:
      version: v1   # 3
  - name: v2
    labels:
      version: v2

  1. Host (host) definiert, dass diese Regel nur in FĂ€llen angewendet wird, in denen die Route zum Dienst fĂŒhrt sa-logic;
  2. Namen (name) von Teilmengen werden bei der Routenlenkung auf Exemplare der Teilmenge verwendet;
  3. Label (label) definiert SchlĂŒssel-Wert-Paare, denen Instanzen entsprechen mĂŒssen, um Teil einer Teilmenge zu werden.

Wenden Sie die Konfiguration mit dem folgenden Befehl an:

$ kubectl apply -f resource-manifests/istio/shadowing/sa-logic-subsets-destinationrule.yaml
destinationrule.networking.istio.io/sa-logic erstellt

Jetzt, da die Teilmengen definiert sind, können wir fortfahren und den VirtualService konfigurieren, um Regeln fĂŒr Anfragen an sa-logic anzuwenden, damit sie:

  1. an die Teilmenge weitergeleitet werden v1,
  2. in die Teilmenge gespiegelt werden v2.

Das folgende Manifest ermöglicht das GewĂŒnschte (sa-logic-subsets-shadowing-vs.yaml):

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: sa-logic
spec:
  hosts:
    - sa-logic          
  http:
  - route:
    - destination:
        host: sa-logic  
        subset: v1      
    mirror:             
      host: sa-logic     
      subset: v2

Hier sind keine ErklÀrungen erforderlich, also sehen wir uns einfach die Anwendung an:

$ kubectl apply -f resource-manifests/istio/shadowing/sa-logic-subsets-shadowing-vs.yaml
virtualservice.networking.istio.io/sa-logic erstellt

Lassen Sie uns Last generieren, indem wir den folgenden Befehl aufrufen:

$ while true; do curl -v http://$EXTERNAL_IP/sentiment 
    -H "Content-type: application/json" 
    -d '{"sentence": "Ich liebe yogobella"}'; 
    sleep .8; done

Wir schauen uns die Ergebnisse in Grafana an, wo zu sehen ist, dass die fehlerhafte Version (fehlerhaft) bei ~60 % der Anfragen fehlschlÀgt, aber keiner dieser AusfÀlle wirkt sich auf die Endbenutzer aus, da diese vom funktionierenden Dienst bedient werden.

ZurĂŒck zu Mikrodiensten mit Istio. Teil 2
Die Erfolgsquote der Antworten verschiedener Versionen des Dienstes sa-logic

Hier haben wir zum ersten Mal gesehen, wie der VirtualService in Bezug auf die Envoys unserer Dienste angewendet wird: wenn sa-web-app eine Anfrage an sa-logic, geht sie durch den Sidecar-Envoy, der ĂŒber den VirtualService so konfiguriert ist, dass die Anfrage an die Teilmenge v1 weitergeleitet und die Anfrage an die Teilmenge v2 des Dienstes gespiegelt wird. sa-logic.

Ich weiß: Sie haben bereits gedacht, dass Virtual Services einfach sind. Im nĂ€chsten Abschnitt werden wir diese Auffassung erweitern, indem wir erklĂ€ren, dass sie wirklich großartig sind.

Canary Deployments

Canary Deployment ist der Prozess, eine neue Version einer Anwendung fĂŒr eine kleine Benutzergruppe bereitzustellen. Dies wird verwendet, um sicherzustellen, dass im Release keine Probleme auftreten, und erst nachdem man sich der ausreichenden QualitĂ€t (des Releases) sicher ist, wird es auf einogrĂ¶ĂŸeres Publikum verteilt.

Zur Demonstration der Canary Deployments werden wir mit der Teilmenge fehlerhaft arbeiten sa-logic.

Lassen Sie uns nicht kleinlich sein und sofort 20 % der Benutzer zur fehlerhaften Version schicken (dies wird unser Canary Deployment sein), und die verbleibenden 80 % zur normalen Dienstleistung. Zu diesem Zweck wenden wir den folgenden VirtualService an (sa-logic-subsets-canary-vs.yaml):

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: sa-logic
spec:
  hosts:
    - sa-logic    
  http:
  - route: 
    - destination: 
        host: sa-logic
        subset: v1
      weight: 80         # 1
    - destination: 
        host: sa-logic
        subset: v2
      weight: 20 # 1

1 — dies ist das Gewicht (weight), das den Prozentsatz der Anfragen bestimmt, die an den EmpfĂ€nger oder ein Teilmengen des EmpfĂ€ngers geleitet werden.

Aktualisieren wir die vorherige Konfiguration des VirtualService mit sa-logic dem folgenden Befehl:

$ kubectl apply -f resource-manifests/istio/canary/sa-logic-subsets-canary-vs.yaml
virtualservice.networking.istio.io/sa-logic konfiguriert


 und sofort sehen wir, dass ein Teil der Anfragen fehlschlÀgt:

$ while true; do 
   curl -i http://$EXTERNAL_IP/sentiment 
   -H "Content-type: application/json" 
   -d '{"sentence": "Ich liebe yogobella"}' 
   --silent -w "Zeit: %{time_total}s t Status: %{http_code}n" 
   -o /dev/null; sleep .1; done
Zeit: 0.153075s Status: 200
Zeit: 0.137581s Status: 200
Zeit: 0.139345s Status: 200
Zeit: 30.291806s Status: 500

VirtualServices aktivieren Kanarienvogel-Deployments: In diesem Fall haben wir die potenziellen Auswirkungen von Problemen auf 20 % der Benutzerbasis eingegrenzt. Wunderbar! Jetzt, jedes Mal, wenn wir uns mit unserem Code unsicher sind (mit anderen Worten - immer
), können wir Mirroring und Kanarienvogel-Deployments verwenden.

Timeouts und Wiederholungsversuche

Aber Fehler liegen nicht immer im Code. Auf der Liste der „8 MissverstĂ€ndnisse in verteilten Berechnungen“ steht an erster Stelle der irrige Glaube, dass „das Netzwerk zuverlĂ€ssig ist“. In Wirklichkeit ist das Netzwerk nicht zuverlĂ€ssig, und daher benötigen wir Timeouts (timeouts) und Wiederholungsversuche (retries).

Um dieses Problem zu demonstrieren, werden wir dasselbe Problem weiterhin behandeln sa-logic (fehlerhaft), wÀhrend wir die UnzuverlÀssigkeit des Netzwerks durch zufÀllige AusfÀlle simulieren.

Nehmen wir an, unser fehlerhaftes Dienst hat eine 1/3 Chance auf eine zu lange Antwort, 1/3 auf einen Fehler mit Internal Server Error und 1/3 auf eine erfolgreiche RĂŒckgabe der Seite.

Um die Auswirkungen solcher Probleme zu mildern und das Leben der Benutzer zu verbessern, können wir:

  1. ein Timeout hinzufĂŒgen, wenn der Dienst lĂ€nger als 8 Sekunden antwortet,
  2. einen Wiederholungsversuch unternehmen, wenn bei der Anfrage ein Fehler auftritt.

Zu diesem Zweck verwenden wir folgende Ressourcendefinition (sa-logic-retries-timeouts-vs.yaml):

apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
  name: sa-logic
spec:
  hosts:
    - sa-logic
  http:
  - route: 
    - destination: 
        host: sa-logic
        subset: v1
      weight: 50
    - destination: 
        host: sa-logic
        subset: v2
      weight: 50
    timeout: 8s           # 1
    retries:
      attempts: 3         # 2
      perTryTimeout: 3s # 3

  1. Das Timeout fĂŒr die Anfrage ist auf 8 Sekunden festgelegt;
  2. Wiederholungsversuche fĂŒr Anfragen werden dreimal unternommen;
  3. Und jeder Versuch wird als erfolglos angesehen, wenn die Antwortzeit 3 Sekunden ĂŒberschreitet.

So haben wir eine Optimierung erreicht, da der Benutzer nicht lÀnger als 8 Sekunden warten muss und wir im Falle von Fehlern drei neue Versuche unternehmen werden, eine Antwort zu erhalten, was die Chance auf eine erfolgreiche Antwort erhöht.

Wenden Sie die aktualisierte Konfiguration mit dem folgenden Befehl an:

$ kubectl apply -f resource-manifests/istio/retries/sa-logic-retries-timeouts-vs.yaml
virtualservice.networking.istio.io/sa-logic konfiguriert

ÜberprĂŒfen Sie die Grafiken in Grafana, dass die Anzahl der erfolgreichen Antworten ĂŒber gestiegen ist:

ZurĂŒck zu Mikrodiensten mit Istio. Teil 2
Verbesserungen in der Statistik der erfolgreichen Antworten nach HinzufĂŒgung von Timeouts und Wiederholungsversuchen

Bevor Sie zum nĂ€chsten Abschnitt ĂŒbergehen (genauer gesagt - bereits zum nĂ€chsten Teil des Artikels, da es in diesem keine praktischen Experimente mehr geben wird - Anmerkung des Übersetzers), entfernen Sie sa-logic-buggy und VirtualService, indem Sie die folgenden Befehle ausfĂŒhren:

$ kubectl delete deployment sa-logic-buggy
deployment.extensions “sa-logic-buggy” gelöscht
$ kubectl delete virtualservice sa-logic
virtualservice.networking.istio.io “sa-logic” gelöscht

Circuit Breaker- und Bulkhead-Muster

Es handelt sich um zwei wichtige Muster in der Mikrodienste-Architektur, die es ermöglichen, eine Selbstheilung (self-healing) der Dienste zu erreichen.

Circuit Breaker („Automatsicher Schalter“) wird verwendet, um Anfragen, die an eine Dienstinstanz gesendet werden, die als nicht gesund angesehen wird, zu stoppen und sie wiederherzustellen, wĂ€hrend die Kundenanfragen an gesunde Instanzen dieses Dienstes umgeleitet werden (was die Erfolgsquote erhöht). (Anmerkung des Übersetzers: Eine detailliertere Beschreibung des Musters finden Sie beispielsweise in hier.)

Bulkhead („Trennwand“) isoliert Fehler in Diensten von einer BeeintrĂ€chtigung des gesamten Systems. Wenn beispielsweise Dienst B ausgefallen ist und ein anderer Dienst (Kunde von Dienst B) eine Anfrage an Dienst B sendet, verbraucht er sein Thread-Pool und kann keine anderen Anfragen mehr bedienen (auch wenn diese nichts mit Dienst B zu tun haben). Ich werde die Details zur Implementierung dieser Muster auslassen, da sie leicht zu finden sind in (Anmerkung des Übersetzers: Eine detailliertere Beschreibung des Musters finden Sie beispielsweise in hier.)

, und ich möchte auch unbedingt die Authentifizierung und Autorisierung zeigen, ĂŒber die es im nĂ€chsten Teil des Artikels gehen wird. offiziellen Dokumentation„ZurĂŒck zu Mikrodiensten mit Istio“:

P.S. vom Übersetzer

Lesen Sie auch in unserem Blog:

Quelle: habr.com

60GB SSD 8Gb DDR4