Tracing en Monitoring in Istio: Microservices en het Onzekerheidsprincipe

Het principe van de onzekerheid van Heisenberg stelt dat het onmogelijk is om tegelijkertijd de positie van een object en zijn snelheid te meten. Als een object in beweging is, heeft het geen specifieke positie. En als er een positie is, dan betekent dat dat het geen snelheid heeft.

Tracing en Monitoring in Istio: Microservices en het Onzekerheidsprincipe

Wat betreft microservices op het Red Hat OpenShift-platform (en beheerd door Kubernetes), kunnen ze dankzij de bijbehorende open-source software tegelijkertijd rapporteren over zowel hun prestaties als hun functionaliteit. Dit weerlegt natuurlijk de oude man Heisenberg niet, maar het elimineert de onzekerheid bij het werken met cloudapplicaties. Istio maakt het gemakkelijk om tracering en monitoring van dergelijke applicaties te organiseren, zodat alles onder controle blijft.

Laten we de terminologie vaststellen

Onder tracering (Tracing) verstaan we het loggen van systeemactiviteit. Het klinkt vrij algemeen, maar een van de belangrijkste regels hier is om traceergegevens in de juiste opslag te dumpen, zonder je zorgen te maken over hun opmaak. Het volledige werk van het zoeken en analyseren van gegevens ligt bij de gebruiker ervan. In Istio wordt het traceringssysteem Jaeger gebruikt, dat het OpenTracing-datamodel implementeert.

Traceringen (Traces, en het woord "traceringen" wordt hier gebruikt in de betekenis van "sporen", zoals bijvoorbeeld in ballistische expertises) noemen we de gegevens die volledig beschrijven hoe een verzoek of een werkunit verloopt, zeg maar, “van begin tot eind”. Bijvoorbeeld, alles wat er gebeurt vanaf het moment dat een gebruiker op een knop op een webpagina drukt tot het moment dat gegevens worden teruggestuurd, inclusief alle microservices die daarbij betrokken zijn. Je zou kunnen zeggen dat één tracering volledig beschrijft (of modelleert) hoe een verzoek heen en terug gaat. In de Jaeger-interface worden traceringen opgedeeld in componenten langs de tijdas, zoals je een ketting in aparte schakels kunt opdelen. Maar in plaats van schakels bestaat een tracering uit zogenaamde span's.

Span – dit is het interval van het begin van de uitvoering van een werkunit tot de voltooiing ervan. Blijft de analogie behouden, dan kun je zeggen dat elke span een afzonderlijke schakel van de ketting vertegenwoordigt. Een span kan (of kan geen) een of meerdere kindspan's hebben. Als gevolg hiervan zal de span van het hoogste niveau (root span) dezelfde totale duur hebben als de tracering waartoe hij behoort.

Monitoring – is, in fact, the observation of your system – through the UI or via automation tools. Monitoring is based on tracing data. In Istio, monitoring is implemented using Prometheus and has a corresponding UI. Prometheus supports automatic monitoring with alert notifications and Alert Managers.

We make notches

For tracing to be possible, the application must create a collection of spans. These must then be exported to Jaeger, which in turn creates a visual representation of the trace. Among other things, these spans mark the operation name and the timestamps of its start and end. The transfer of spans is done by redirecting HTTP headers intended for Jaeger from incoming requests to outgoing requests. Depending on the programming language used, this may require slight modifications to the application source code. Below is an example of code in Java (using the Spring Boot framework) that adds B3 (Zipkin-style) headers to your request in the Spring configuration class:

Tracing en Monitoring in Istio: Microservices en het Onzekerheidsprincipe
The following header settings are used:

Tracing en Monitoring in Istio: Microservices en het Onzekerheidsprincipe
If you are using Java, you don't need to change the code; just add a few lines in the Maven POM file and set environment variables. Here are the lines that need to be added to the POM.XML file to implement the Jaeger Tracer Resolver:

Tracing en Monitoring in Istio: Microservices en het Onzekerheidsprincipe
And the corresponding environment variables are set in the Dockerfile:

Tracing en Monitoring in Istio: Microservices en het Onzekerheidsprincipe
That's it, everything is set up, and our microservices will start generating trace data.

Looking at the big picture

Istio includes a simple control panel based on Grafana. When everything is set up and running on the Red Hat OpenShift PaaS platform (in our example, Red Hat OpenShift and Kubernetes are deployed on minishift), this panel is launched with the following command:

open "$(minishift openshift service grafana -u)/d/1/istio-dashboard?refresh=5⩝Id=1"

The Grafana panel allows for a quick assessment of the system's performance. A fragment of this panel is shown in the image below:

Tracing en Monitoring in Istio: Microservices en het Onzekerheidsprincipe
Hier zien we dat de microservice customer de microservice preference v1 aanroept, en deze op zijn beurt roept de microservices recommendation v1 en v2 aan. Op het Grafana-paneel is er een Dashboard Row-blok voor high-level metrics, zoals het totale aantal verzoeken (Global Request Volume), het percentage succesvolle verzoeken (success rates) en fouten 4xx. Daarnaast is er een weergave van Server Mesh met grafieken voor elke service en een blok Services Row voor het bekijken van gedetailleerde informatie over elke container voor elke service.

Laten we dieper graven

Bij correct ingestelde tracing van Istio, wat eigenlijk direct uit de doos beschikbaar is, kan je dieper ingaan op de prestatie-analyse van het systeem. In de Jaeger UI kun je traceringen bekijken en zien hoe ver en diep ze gaan, en visueel knelpunten in de prestaties lokaliseren. Wanneer je Red Hat OpenShift op het minishift-platform gebruikt, start je de Jaeger UI met de volgende opdracht:

minishift openshift service jaeger-query --in-browser

Tracing en Monitoring in Istio: Microservices en het Onzekerheidsprincipe
Wat kunnen we zeggen over de tracing op deze afbeelding:

  • Het is verdeeld in 7 spans.
  • De totale uitvoeringstijd bedraagt 6,99 ms.
  • De microservice recommendation, die de laatste in de keten is, verbruikt 0,69 ms.

Dit type diagrammen maakt het mogelijk om snel te begrijpen wanneer de prestaties van het complete systeem lijden onder een enkel dienst die niet goed functioneert.

Laten we de taak nu complexer maken en twee exemplaren van de microservice recommendation:v2 opstarten met het commando oc scale --replicas=2 deployment/recommendation-v2. Dit is wat we daarna aan pods zullen hebben:

Tracing en Monitoring in Istio: Microservices en het Onzekerheidsprincipe
Als we nu terugschakelen naar Jaeger en de span voor de service recommendation uitvouwen, zien we naar welke pod de verzoeken worden gerouteerd. Hierdoor kunnen we eenvoudig vertragingen lokaliseren op het niveau van een specifieke pod. Kijk hierbij naar het veld node_id:

Tracing en Monitoring in Istio: Microservices en het Onzekerheidsprincipe

Waarheen en hoe alles loopt

We gaan nu naar de Prometheus-interface en zien daar, zoals verwacht, dat de verzoeken tussen de tweede en eerste versies van de service recommendation worden verdeeld in een verhouding van 2:1, strikt op basis van het aantal werkende pods. Dit grafiek zal dynamisch veranderen bij het opschalen van pods omhoog of omlaag, wat bijzonder nuttig zal zijn bij Canary Deployment (we zullen deze implementatiestrategie in de volgende sessie beter bekijken).

Tracing en Monitoring in Istio: Microservices en het Onzekerheidsprincipe

Alles begint pas

Eigenlijk hebben we vandaag slechts oppervlakkig een schat aan nuttige informatie over Jaeger, Grafana en Prometheus aangestipt. Dit was ook ons doel – u in de juiste richting leiden en de mogelijkheden van Istio onthullen.

En onthoud, dit is allemaal al ingebouwd in Istio. Bij het gebruik van bepaalde programmeertalen (zoals Java) en frameworks (zoals Spring Boot) kan dit allemaal worden gerealiseerd zonder de applicatiecode aan te raken. Ja, de code moet enigszins worden aangepast als u andere talen gebruikt, met name Node.js of C#. Maar aangezien traceerbaarheid (lees: ‘tracering’) een van de vereisten is voor het creëren van betrouwbare cloudsystemen, zult u in ieder geval de code moeten aanpassen, of u nu Istio gebruikt of niet. Waarom de inspanning dan niet effectiever inzetten?

Laten we zeggen: om altijd met 100% zekerheid de vragen 'waar?' en 'hoe snel?' te kunnen beantwoorden.

Chaos-engineering in Istio: zoals het bedoeld was

Het vermogen om dingen kapot te maken helpt ervoor te zorgen dat ze niet kapotgaan.

Softwaretesten is niet alleen een complexe taak, maar ook een belangrijke. Tegelijkertijd is testen op correctheid (bijvoorbeeld of een functie het juiste resultaat teruggeeft) iets anders dan testen onder onbetrouwbare netwerkconditions – dit wordt vaak verondersteld dat het netwerk altijd zonder onderbrekingen werkt, en dat is het eerste van de acht misvattingen over gedistribueerde computing. Een van de moeilijkheden bij het aanpakken van deze taak is hoe systeemstoringen te simuleren of deze opzettelijk te introduceren door middel van zogenaamde fault injection. Dit kan gedaan worden door de oorspronkelijke code van de applicatie te wijzigen. Maar dan test u niet uw oorspronkelijke code, maar een versie die speciaal is ontworpen om storingen te simuleren. Het resultaat is dat u het risico loopt om in de dodelijke omhelzing van fault injection te belanden en te maken te krijgen met Heisenbugs – storingen die verdwijnen wanneer men probeert ze te ontdekken.

En nu laten we zien hoe Istio helpt deze complicaties snel op te lossen.

Hoe alles eruitziet wanneer alles perfect werkt.

Laten we het volgende scenario bekijken: we hebben twee pod’s voor onze recommendation microservice, die we uit de Istio-handleiding hebben gehaald. De ene pod is gemarkeerd als v1 en de andere als v2. Zoals we zien, werkt alles prima tot nu toe:

Tracing en Monitoring in Istio: Microservices en het Onzekerheidsprincipe
(Trouwens, het nummer aan de rechterkant is gewoon een teller voor elke pod.)

Maar we hebben dit echt niet nodig, toch? Laten we proberen alles kapot te maken, zonder de oorspronkelijke code aan te raken.

We veroorzaken storingen in de microservice.

Hieronder staat een yaml-bestand voor de Istio-routeringregel, die in de helft van de gevallen een fout zal geven (foutmelding). de server 503):

Tracing en Monitoring in Istio: Microservices en het Onzekerheidsprincipe
Let op, we geven expliciet aan dat in de helft van de gevallen een fout 503 moet worden teruggegeven.

Zo ziet een screenshot eruit van de curl-opdracht die in een loop draait, nadat we deze regel hebben geactiveerd om storingen te simuleren. Zoals te zien is, geeft de helft van de aanvragen een fout 503 terug, ongeacht op welke pod – v1 of v2 – ze worden verzonden.

Tracing en Monitoring in Istio: Microservices en het Onzekerheidsprincipe
Om de normale werking te herstellen, hoeft u alleen maar deze regel te verwijderen, in ons geval met het commando istioctl delete routerule recommendation-503 -n tutorial. Hier is Tutorial de naam van het Red Hat OpenShift-project waarin onze Istio-tutorial draait.

We brengen kunstmatige vertragingen aan.

Kunstmatige fouten 503 helpen om het systeem op veerkracht tegen storingen te testen, maar het vermogen om vertragingen te voorspellen en ermee om te gaan, zou u nog meer moeten imponeren. Vertragingen komen in het echte leven namelijk vaker voor dan storingen. Een traag werkende microservice is een vergif waar het hele systeem onder lijdt. Met Istio kunnen we de code die met vertragingen omgaat testen, zonder deze te wijzigen. We zullen eerst laten zien hoe dit werkt bij kunstmatig ingevoerde netwerkvertragingen.

Let op, na zo'n test moet u mogelijk (of wilt u) uw code aanpassen. Het goede nieuws is dat u in dit geval proactief zult handelen, in plaats van reactief. Dit is hoe de ontwikkelingscyclus moet worden gebouwd: coderen-testen-feedback-coderen-testen…

Dit is hoe de regel eruitziet, die... Maar weet u wat? Istio is zo eenvoudig, en dit yaml-bestand is zo duidelijk, dat alles in dit voorbeeld voor zich spreekt. Kijk maar:

Tracing en Monitoring in Istio: Microservices en het Onzekerheidsprincipe
In de helft van de gevallen zullen we een vertraging van 7 seconden ervaren. Dit is absoluut niet hetzelfde als wanneer we een sleep-commando in de originele code zouden invoegen, omdat Istio daadwerkelijk de aanvraag 7 seconden vertraagt. Aangezien Istio Jaeger-tracering ondersteunt, is deze vertraging duidelijk zichtbaar in de Jaeger UI, zoals te zien is in de onderstaande screenshot. Let op het lange verzoek in de rechterbovenhoek van de grafiek – de duur is 7,02 seconden:

Tracing en Monitoring in Istio: Microservices en het Onzekerheidsprincipe
Dit scenario maakt het mogelijk om de code te testen onder netwerklatenties. En het is duidelijk dat als we deze regel weghalen, we de kunstmatige vertraging zullen verwijderen. Laten we herhalen dat we dit alles hebben gedaan zonder de originele code aan te raken.

Niet afwijken en niet opgeven

Een andere nuttige functie van chaos engineering in Istio is de mogelijkheid om meerdere keren een verzoek naar de service te doen binnen een bepaald aantal keren. Het idee hier is om niet te stoppen als de eerste aanvraag eindigt met een foutmelding 503 – en dan, misschien, hebben we geluk bij de N-de poging. Misschien ligt de service tijdelijk plat om een of andere reden. Ja, deze reden moet worden uitgezocht en opgelost. Maar dat later, laten we nu proberen om het systeem operationeel te houden.

Dus we willen dat de service van tijd tot tijd een fout 503 teruggeeft, en Istio daarna opnieuw probeert contact te maken. En we hebben duidelijk een manier nodig om een fout 503 te genereren zonder de code zelf aan te raken…

Wacht, even wachten! We deden dit net.

Dit bestand zorgt ervoor dat de service recommendation-v2 in de helft van de gevallen een fout 503 zal geven:

Tracing en Monitoring in Istio: Microservices en het Onzekerheidsprincipe
Het is duidelijk dat een deel van de verzoeken zal falen:

Tracing en Monitoring in Istio: Microservices en het Onzekerheidsprincipe
Laten we nu de Istio Retry-functie inschakelen:

Tracing en Monitoring in Istio: Microservices en het Onzekerheidsprincipe
Deze routeringsregel maakt drie opnieuw pogingen met tussenpozen van twee seconden en zou de 503-fouten moeten verminderen (en idealiter volledig van de radar moeten verwijderen):

Tracing en Monitoring in Istio: Microservices en het Onzekerheidsprincipe
Samenvattend: we hebben ervoor gezorgd dat Istio, ten eerste, een fout 503 genereert voor de helft van de verzoeken. Ten tweede, dezelfde Istio probeert drie keer opnieuw contact te maken met de service bij een fout 503. Als gevolg daarvan werkt alles gewoon uitstekend. Door de Retry-functie te gebruiken, hebben we ons beloofde om niet af te wijken en niet op te geven, nagekomen.

En ja, we hebben het opnieuw gedaan, zonder de code aan te raken. Alles wat we nodig hadden, waren twee Istio routeringsregels:

Tracing en Monitoring in Istio: Microservices en het Onzekerheidsprincipe

Hoe je de gebruiker niet in de steek laat of zeven mensen wachten.

Laten we de situatie omdraaien en het scenario bekijken waarin het alleen gedurende een bepaalde tijd de moeite waard is om niet op te geven of zich niet over te geven. Daarna moeten we gewoon stoppen met het proberen om het verzoek te verwerken, om te voorkomen dat iedereen moet wachten op één vertraagde service. Met andere woorden, we zullen de verloren positie niet verdedigen, maar ons terugtrekken naar een alternatieve lijn om de gebruiker van de site niet in het ongewisse te laten zitten.

In Istio kun je een timeout voor het uitvoeren van een verzoek instellen. Als de service deze timeout overschrijdt, wordt er een fout 504 (Gateway Timeout) geretourneerd - dit alles gebeurt weer via de configuratie van Istio. Maar we moeten een slaapcommando aan de broncode van de service toevoegen (en vervolgens natuurlijk de rebuild en redeploy uitvoeren), om de trage werking van de service te simuleren. Helaas, anders kan het niet.

Dus, we hebben een drie seconden durende slaap in de code van de service recommendation v2 geplaatst, het bijbehorende image opnieuw opgebouwd en de container opnieuw gedeployed, en nu gaan we een timeout toevoegen met behulp van de volgende Istio-routingregel:

Tracing en Monitoring in Istio: Microservices en het Onzekerheidsprincipe
Op de bovenstaande screenshot is te zien dat we stoppen met het proberen om verbinding te maken met de service recommendation, als we binnen één seconde geen antwoord krijgen, dat wil zeggen nog voordat de fout 504 optreedt. Na het toepassen van deze routingregel (en het toevoegen van de drie seconden durende slaap in de code van de service recommendation:v2), krijgen we dit:

Tracing en Monitoring in Istio: Microservices en het Onzekerheidsprincipe
We herhalen het opnieuw, maar de timeout kan worden ingesteld zonder de broncode aan te raken. En het extra voordeel hier is dat je nu je code kunt aanpassen zodat deze reageert op de timeout, en deze aanpassingen eenvoudig kunt testen met behulp van Istio.

En nu alles samen

Een beetje chaos introduceren met behulp van Istio is een geweldige manier om je code en de betrouwbaarheid van je systeem als geheel te testen. Fallback-, bulkhead- en circuit breaker-patronen, mechanismen voor het creëren van kunstmatige storingen en vertragingen, evenals herhaalde aanroepen en timeouts zullen zeer nuttig zijn bij het creëren van veerkrachtige cloudsystemen. In combinatie met Kubernetes en Red Hat OpenShift zullen deze tools helpen om zelfverzekerd de toekomst tegemoet te treden.

Bron: habr.com

Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers 🔥 Koop betrouwbare webhosting met bescherming tegen DDoS, VPS VDS servers | ProHoster