Istio Circuit Breaker: Deaktivieren fehlerhafter Container

Die Feiertage sind vorbei und wir sind zurück mit unserem zweiten Beitrag in der Istio Service Mesh-Reihe.

Istio Circuit Breaker: Deaktivieren fehlerhafter Container

Das heutige Thema ist Leistungsschalter, was in der russischen Elektrotechnik „Leistungsschalter“ bedeutet, im allgemeinen Sprachgebrauch „Leistungsschalter“. Nur in Istio trennt diese Maschine nicht einen kurzgeschlossenen oder überlasteten Stromkreis, sondern defekte Behälter.

Wie das im Idealfall funktionieren sollte

Wenn Microservices von Kubernetes verwaltet werden, beispielsweise innerhalb der OpenShift-Plattform, skalieren sie je nach Auslastung automatisch nach oben und unten. Da Microservices in Pods ausgeführt werden, kann es auf einem Endpunkt mehrere Instanzen eines Container-Microservices geben, und Kubernetes leitet Anforderungen weiter und sorgt für einen Lastausgleich zwischen ihnen. Und im Idealfall sollte das alles perfekt funktionieren.

Wir erinnern uns daran, dass Microservices klein und vergänglich sind. Flüchtigkeit, also die Leichtigkeit des Erscheinens und Verschwindens, wird oft unterschätzt. Die Geburt und der Tod einer weiteren Instanz eines Microservices in einem Pod sind durchaus zu erwartende Dinge, OpenShift und Kubernetes bewältigen das gut und alles funktioniert großartig – aber wiederum theoretisch.

Wie es wirklich funktioniert

Stellen Sie sich nun vor, dass eine bestimmte Instanz eines Microservices, also eines Containers, unbrauchbar geworden ist: Entweder antwortet er nicht (Fehler 503) oder, was noch unangenehmer ist, er antwortet, aber zu langsam. Mit anderen Worten: Es kommt zu Störungen oder reagiert nicht auf Anfragen, es wird jedoch nicht automatisch aus dem Pool entfernt. Was ist in diesem Fall zu tun? Noch einmal versuchen? Soll ich es aus dem Routing-Schema entfernen? Und was bedeutet „zu langsam“ – wie viele sind es in Zahlen und wer bestimmt sie? Vielleicht einfach eine Pause einlegen und es später noch einmal versuchen? Wenn ja, wie viel später?

Was ist Pool-Auswurf in Istio?

Und hier kommt Istio mit seinen Circuit Breaker-Schutzmaschinen zur Rettung, die fehlerhafte Container vorübergehend aus dem Routing- und Load-Balancing-Ressourcenpool entfernen und dabei das Pool-Ejection-Verfahren implementieren.

Mithilfe einer Ausreißererkennungsstrategie erkennt Istio Kurven-Pods, die außerhalb der Linie liegen, und entfernt sie für einen bestimmten Zeitraum, der als Ruhefenster bezeichnet wird, aus dem Ressourcenpool.

Um zu zeigen, wie das in Kubernetes auf der OpenShift-Plattform funktioniert, beginnen wir mit einem Screenshot normal funktionierender Microservices aus dem Beispiel im Repository Demos für Red Hat-Entwickler. Hier haben wir zwei Pods, v1 und v2, auf denen jeweils ein Container ausgeführt wird. Wenn Istio-Routing-Regeln nicht verwendet werden, verwendet Kubernetes standardmäßig ein gleichmäßig ausgewogenes Round-Robin-Routing:

Istio Circuit Breaker: Deaktivieren fehlerhafter Container

Bereiten Sie sich auf einen Absturz vor

Bevor Sie den Pool-Auswurf durchführen, müssen Sie eine Istio-Routing-Regel erstellen. Nehmen wir an, wir möchten Anfragen im Verhältnis 50/50 auf die Pods verteilen. Darüber hinaus werden wir die Anzahl der v2-Container von eins auf zwei erhöhen, wie folgt:

oc scale deployment recommendation-v2 --replicas=2 -n tutorial

Jetzt legen wir eine Routing-Regel fest, sodass der Datenverkehr im Verhältnis 50/50 auf die Pods verteilt wird.

Istio Circuit Breaker: Deaktivieren fehlerhafter Container
So sieht das Ergebnis dieser Regel aus:

Istio Circuit Breaker: Deaktivieren fehlerhafter Container
Man kann es bemängeln, dass dieser Bildschirm nicht 50/50, sondern 14:9 ist, aber mit der Zeit wird sich die Situation verbessern.

Einen Fehler machen

Jetzt deaktivieren wir einen der beiden v2-Container, sodass wir einen fehlerfreien v1-Container, einen fehlerfreien v2-Container und einen fehlerhaften v2-Container haben:

Istio Circuit Breaker: Deaktivieren fehlerhafter Container

Den Fehler beheben

Wir haben also einen fehlerhaften Container und es ist Zeit für den Pool-Auswurf. Mithilfe einer sehr einfachen Konfiguration schließen wir diesen ausgefallenen Container für 15 Sekunden von allen Routing-Schemata aus, in der Hoffnung, dass er in einen fehlerfreien Zustand zurückkehrt (entweder Neustart oder Wiederherstellung der Leistung). So sieht diese Konfiguration aus und die Ergebnisse ihrer Arbeit:

Istio Circuit Breaker: Deaktivieren fehlerhafter Container
Istio Circuit Breaker: Deaktivieren fehlerhafter Container
Wie Sie sehen, wird der ausgefallene v2-Container nicht mehr für Routing-Anfragen verwendet, da er aus dem Pool entfernt wurde. Aber nach 15 Sekunden kehrt es automatisch in den Pool zurück. Eigentlich haben wir gerade gezeigt, wie Pool Ejection funktioniert.

Beginnen wir mit dem Bau von Architektur

Mit Pool Ejection können Sie in Kombination mit den Überwachungsfunktionen von Istio mit dem Aufbau eines Frameworks für den automatischen Austausch fehlerhafter Container beginnen, um Ausfallzeiten und Ausfälle zu reduzieren, wenn nicht sogar ganz zu vermeiden.

Die NASA hat ein lautes Motto – Scheitern ist keine Option, dessen Autor als Flugdirektor gilt Gene Kranz. Ins Russische lässt es sich mit „Misserfolg ist keine Option“ übersetzen und bedeutet hier, dass mit genügend Willen alles zum Laufen gebracht werden kann. Im wirklichen Leben passieren Misserfolge jedoch nicht einfach, sie sind unvermeidlich, überall und in allem. Und wie geht man bei Microservices damit um? Unserer Meinung nach ist es besser, sich nicht auf die Willenskraft zu verlassen, sondern auf die Fähigkeiten von Containern. Kubernetes, Red Hat OpenShiftUnd Istio.

Istio implementiert, wie wir oben geschrieben haben, das Konzept der Leistungsschalter, das sich in der physischen Welt bestens bewährt hat. Und genau wie ein elektrischer Schutzschalter einen problematischen Abschnitt eines Stromkreises abschaltet, öffnet Istios Software Circuit Breaker die Verbindung zwischen einem Anforderungsstrom und einem Problemcontainer, wenn mit dem Endpunkt etwas nicht stimmt, beispielsweise wenn der Server abgestürzt ist oder zu funktionieren begann verlangsamen.

Darüber hinaus gibt es im zweiten Fall nur noch mehr Probleme, da die Bremsen eines Containers nicht nur zu einer Kaskade von Verzögerungen bei den darauf zugreifenden Diensten führen und dadurch die Leistung des Gesamtsystems verringern, sondern auch zu wiederholten Verzögerungen führen Anfragen an einen bereits langsam laufenden Dienst, was die Situation nur verschlimmert.

Leistungsschalter in der Theorie

Circuit Breaker ist ein Proxy, der den Fluss von Anfragen an einen Endpunkt steuert. Wenn dieser Punkt nicht mehr funktioniert oder, abhängig von den angegebenen Einstellungen, langsamer wird, unterbricht der Proxy die Verbindung mit dem Container. Der Datenverkehr wird dann einfach aufgrund des Lastausgleichs auf andere Container umgeleitet. Die Verbindung bleibt für ein bestimmtes Schlaffenster, beispielsweise zwei Minuten, geöffnet und gilt dann als halboffen. Ein Versuch, die nächste Anfrage zu senden, bestimmt den weiteren Zustand der Verbindung. Wenn mit dem Dienst alles in Ordnung ist, kehrt die Verbindung in den Betriebszustand zurück und wird wieder geschlossen. Wenn immer noch etwas mit dem Dienst nicht stimmt, wird die Verbindung getrennt und das Ruhefenster wird wieder aktiviert. So sieht ein vereinfachtes Leistungsschalter-Zustandsdiagramm aus:

Istio Circuit Breaker: Deaktivieren fehlerhafter Container
Dabei ist zu beachten, dass dies alles sozusagen auf der Ebene der Systemarchitektur geschieht. Irgendwann müssen Sie Ihren Anwendungen also beibringen, mit Circuit Breaker zu arbeiten, indem Sie beispielsweise einen Standardwert als Antwort bereitstellen oder, wenn möglich, die Existenz des Dienstes ignorieren. Hierzu wird ein Schottmuster verwendet, das jedoch den Rahmen dieses Artikels sprengen würde.

Leistungsschalter in der Praxis

Beispielsweise werden wir zwei Versionen unseres Empfehlungs-Microservices auf OpenShift ausführen. Version 1 wird gut funktionieren, aber in Version 2 werden wir eine Verzögerung einbauen, um Verlangsamungen auf dem Server zu simulieren. Um die Ergebnisse anzuzeigen, verwenden Sie das Tool Belagerung:

siege -r 2 -c 20 -v customer-tutorial.$(minishift ip).nip.io

Istio Circuit Breaker: Deaktivieren fehlerhafter Container
Alles scheint zu funktionieren, aber zu welchem ​​Preis? Auf den ersten Blick haben wir eine 100-prozentige Verfügbarkeit, aber schauen Sie genauer hin – die maximale Transaktionsdauer beträgt sogar 12 Sekunden. Dies stellt eindeutig einen Engpass dar und muss ausgebaut werden.

Dazu verwenden wir Istio, um Aufrufe an langsame Container zu eliminieren. So sieht die entsprechende Konfiguration mit Circuit Breaker aus:

Istio Circuit Breaker: Deaktivieren fehlerhafter Container
Die letzte Zeile mit dem Parameter httpMaxRequestsPerConnection signalisiert, dass die Verbindung mit getrennt werden soll, wenn versucht wird, zusätzlich zur bestehenden eine weitere – eine zweite – Verbindung herzustellen. Da unser Container einen langsamen Dienst simuliert, treten solche Situationen regelmäßig auf, und Istio gibt dann einen 503-Fehler zurück, aber Folgendes wird bei Siege angezeigt:

Istio Circuit Breaker: Deaktivieren fehlerhafter Container

OK, wir haben den Leistungsschalter, was kommt als nächstes?

Deshalb haben wir das automatische Herunterfahren implementiert, ohne den Quellcode der Dienste selbst zu berühren. Mithilfe von Circuit Breaker und dem oben beschriebenen Pool-Auswurfverfahren können wir Bremscontainer aus dem Ressourcenpool entfernen, bis sie wieder normal sind, und ihren Status in einer bestimmten Häufigkeit überprüfen – in unserem Beispiel sind dies zwei Minuten (sleepWindow-Parameter).

Beachten Sie, dass die Fähigkeit einer Anwendung, auf einen 503-Fehler zu reagieren, immer noch auf der Quellcodeebene festgelegt wird. Je nach Situation gibt es viele Strategien für den Einsatz von Leistungsschaltern.

Im nächsten Beitrag: Wir sprechen über die Ablaufverfolgung und Überwachung, die bereits integriert ist oder einfach in Istio hinzugefügt werden kann, und darüber, wie man absichtlich Fehler in das System einschleusen kann.

Source: habr.com

Kommentar hinzufügen