Opmerking. vert.: Het eerste deel Deze serie was gewijd aan het introduceren van Istio-mogelijkheden en het demonstreren ervan in actie. Nu zullen we het hebben over complexere aspecten van de configuratie en het gebruik van deze service mesh, en in het bijzonder over nauwkeurig afgestemde routering en netwerkverkeersbeheer.
We herinneren u er ook aan dat het artikel configuraties (manifesten voor Kubernetes en Istio) uit de repository gebruikt istio-meesterschap.
Verkeersmanagement
Met Istio verschijnen er nieuwe mogelijkheden in het cluster om het volgende te bieden:
Naarmate het artikel verder gaat, zullen deze mogelijkheden worden geïllustreerd aan de hand van de geselecteerde applicatie als voorbeeld, en gaandeweg zullen nieuwe concepten worden geïntroduceerd. Het eerste dergelijke concept zal zijn DestinationRules(d.w.z. regels over de ontvanger van verkeer/verzoeken - ca. vert.), waarmee we A/B-testen activeren.
A/B-testen: DestinationRules in de praktijk
A/B-testen worden gebruikt in gevallen waarin er twee versies van een applicatie zijn (meestal zijn ze visueel verschillend) en we niet 100% zeker weten welke de gebruikerservaring zal verbeteren. Daarom voeren we beide versies tegelijkertijd uit en verzamelen we statistieken.
Om de tweede versie van de frontend te implementeren, vereist voor het demonstreren van A/B-testen, voert u de volgende opdracht uit:
$ kubectl apply -f resource-manifests/kube/ab-testing/sa-frontend-green-deployment.yaml
deployment.extensions/sa-frontend-green created
Het implementatiemanifest voor de groene versie verschilt op twee punten:
De afbeelding is gebaseerd op een andere tag - istio-green,
Pods hebben een label version: green.
Omdat beide implementaties een label hebben app: sa-frontend,verzoeken gerouteerd door virtuele service sa-external-services voor service sa-frontend, wordt doorgestuurd naar al zijn instanties en de belasting wordt verdeeld via round robin-algoritme, wat tot de volgende situatie zal leiden:
De gevraagde bestanden zijn niet gevonden
Deze bestanden zijn niet gevonden omdat ze in verschillende versies van de applicatie een andere naam hebben. Laten we hier zeker van zijn:
Dit betekent dat index.html, waarbij één versie van statische bestanden wordt aangevraagd, kan door de load balancer worden verzonden naar pods die een andere versie hebben, waar dergelijke bestanden om voor de hand liggende redenen niet bestaan. Om de applicatie te laten werken, moeten we daarom een beperking instellen: “dezelfde versie van de applicatie die index.html bediende, zou volgende verzoeken moeten verwerken.
We komen er met consistente, op hash gebaseerde load-balancing (Consistente hash-loadbalancing). In dit geval verzoeken van dezelfde client worden naar hetzelfde backend-exemplaar verzonden, waarvoor een vooraf gedefinieerde eigenschap wordt gebruikt, bijvoorbeeld een HTTP-header. Geïmplementeerd met behulp van DestinationRules.
Bestemmingsregels
Na VirtueleService een verzoek naar de gewenste service heeft gestuurd, kunnen we met behulp van DestinationRules beleid definiëren dat wordt toegepast op verkeer dat bestemd is voor exemplaren van deze service:
Verkeersmanagement met Istio-middelen
Noot: De impact van Istio-bronnen op het netwerkverkeer wordt hier gepresenteerd op een manier die gemakkelijk te begrijpen is. Om precies te zijn: de beslissing naar welk exemplaar het verzoek moet worden verzonden, wordt genomen door de Envoy in de Ingress Gateway die in de CRD is geconfigureerd.
Met bestemmingsregels kunnen we de taakverdeling configureren om consistente hashes te gebruiken en ervoor te zorgen dat hetzelfde service-exemplaar op dezelfde gebruiker reageert. Met de volgende configuratie kunt u dit bereiken (bestemmingsregel-sa-frontend.yaml):
Noot: Om verschillende waarden in de header toe te voegen en de resultaten rechtstreeks in de browser te testen, kunt u gebruiken deze uitbreiding naar Chroom (Of hiermee voor Firefox - ca. vert.).
Over het algemeen heeft DestinationRules meer mogelijkheden op het gebied van load-balancing - kijk voor details in officiële documentatie.
Laten we, voordat we VirtualService verder bestuderen, de “groene versie” van de applicatie en de bijbehorende verkeersrichtingsregel verwijderen door de volgende opdrachten uit te voeren:
schaduwing (“afscherming”) of spiegelen (“spiegelen”) gebruikt in gevallen waarin we een productiewijziging willen testen zonder gevolgen voor eindgebruikers: om dit te doen, dupliceren we (‘mirror’) verzoeken naar een tweede instantie waar de gewenste wijzigingen zijn aangebracht, en kijken we naar de gevolgen. Simpel gezegd: dit is het moment waarop uw collega het meest kritieke probleem kiest en een pull-verzoek indient in de vorm van zo'n enorme klomp vuil dat niemand het daadwerkelijk kan beoordelen.
Om dit scenario in actie te testen, maken we een tweede exemplaar van SA-Logic met bugs (buggy) door de volgende opdracht uit te voeren:
$ kubectl apply -f resource-manifests/kube/shadowing/sa-logic-service-buggy.yaml
deployment.extensions/sa-logic-buggy created
En laten we nu de opdracht uitvoeren om ervoor te zorgen dat alle exemplaren met app=sa-logic Ze hebben ook labels met de bijbehorende versies:
Dienst sa-logic richt zich op peulen met een label app=sa-logic, zodat alle verzoeken over alle instanties worden verdeeld:
... maar we willen dat verzoeken naar v1-instanties worden verzonden en worden gespiegeld naar v2-instanties:
We zullen dit bereiken via VirtualService in combinatie met DestinationRule, waarbij de regels de subsets en routes van de VirtualService naar een specifieke subset bepalen.
Hier is geen uitleg nodig, dus laten we het gewoon in actie zien:
$ kubectl apply -f resource-manifests/istio/shadowing/sa-logic-subsets-shadowing-vs.yaml
virtualservice.networking.istio.io/sa-logic created
Laten we de belasting toevoegen door de volgende opdracht aan te roepen:
$ while true; do curl -v http://$EXTERNAL_IP/sentiment
-H "Content-type: application/json"
-d '{"sentence": "I love yogobella"}';
sleep .8; done
Laten we eens kijken naar de resultaten in Grafana, waar je kunt zien dat de versie met bugs (buggy) resulteert in een mislukking voor ~60% van de verzoeken, maar geen van deze fouten heeft gevolgen voor eindgebruikers, aangezien hierop wordt gereageerd door een actieve service.
Succesvolle reacties van verschillende versies van de sa-logic-service
Hier zagen we voor het eerst hoe VirtualService wordt toegepast op de Envoys van onze diensten: wanneer sa-web-app doet een verzoek aan sa-logic, het gaat via de zijspan Envoy, die - via VirtualService - is geconfigureerd om het verzoek naar de v1-subset te routeren en het verzoek te spiegelen naar de v2-subset van de service sa-logic.
Ik weet het, je denkt misschien al dat Virtual Services eenvoudig is. In het volgende gedeelte gaan we daar dieper op in door te zeggen dat ze ook echt geweldig zijn.
Kanarie-uitrol
Canary Deployment is het proces waarbij een nieuwe versie van een applicatie wordt uitgerold naar een klein aantal gebruikers. Het wordt gebruikt om ervoor te zorgen dat er geen problemen zijn met de release en pas daarna, terwijl je al vertrouwen hebt in de kwaliteit ervan, deze naar andere gebruikers te distribueren.оgroter publiek.
Om de uitrol van kanaries te demonstreren, blijven we werken met een subset buggy у sa-logic.
Laten we geen tijd verspillen aan kleinigheden en onmiddellijk 20% van de gebruikers naar de versie met bugs sturen (dit vertegenwoordigt onze kanarie-uitrol), en de resterende 80% naar de normale service. Gebruik hiervoor de volgende VirtualService (sa-logic-subsets-canary-vs.yaml):
... en we zullen meteen zien dat sommige verzoeken tot mislukkingen leiden:
$ while true; do
curl -i http://$EXTERNAL_IP/sentiment
-H "Content-type: application/json"
-d '{"sentence": "I love yogobella"}'
--silent -w "Time: %{time_total}s t Status: %{http_code}n"
-o /dev/null; sleep .1; done
Time: 0.153075s Status: 200
Time: 0.137581s Status: 200
Time: 0.139345s Status: 200
Time: 30.291806s Status: 500
VirtualServices maken canary-implementaties mogelijk: in dit geval hebben we de potentiële impact van de problemen beperkt tot 20% van het gebruikersbestand. Prachtig! In elk geval waarin we niet zeker zijn van onze code (met andere woorden: altijd...), kunnen we mirroring en canary-implementaties gebruiken.
Time-outs en nieuwe pogingen
Maar bugs komen niet altijd in de code terecht. In de lijst van "8 Misvattingen over gedistribueerde computers“In de eerste plaats is er de onjuiste overtuiging dat ‘het netwerk betrouwbaar is’. In werkelijkheid het netwerk geen betrouwbaar, en om deze reden hebben we time-outs nodig (time-outs) en nieuwe pogingen (pogingen).
Voor demonstratie blijven we dezelfde probleemversie gebruiken sa-logic (buggy), en we zullen de onbetrouwbaarheid van het netwerk simuleren met willekeurige storingen.
Laat onze service met bugs een kans van 1/3 hebben dat het te lang duurt om te reageren, een kans van 1/3 dat deze eindigt met een interne serverfout en een kans van 1/3 dat de pagina succesvol wordt geretourneerd.
Om de impact van dergelijke problemen te verzachten en het leven van gebruikers te verbeteren, kunnen we:
een time-out toevoegen als de service langer dan 8 seconden nodig heeft om te reageren,
De time-out voor het verzoek is ingesteld op 8 seconden;
Verzoeken worden 3 keer opnieuw geprobeerd;
En elke poging wordt als mislukt beschouwd als de responstijd langer is dan 3 seconden.
Dit is een optimalisatie omdat de gebruiker niet langer dan 8 seconden hoeft te wachten en we bij storingen drie nieuwe pogingen zullen doen om een reactie te krijgen, waardoor de kans op een succesvolle reactie groter wordt.
Pas de bijgewerkte configuratie toe met de volgende opdracht:
En kijk in de Grafana-grafieken hierboven dat het aantal succesvolle reacties is toegenomen:
Verbeteringen in succesvolle responsstatistieken na het toevoegen van time-outs en nieuwe pogingen
Voordat u doorgaat naar het volgende gedeelte (of beter gezegd, naar het volgende deel van het artikel, want hierin zullen geen praktische experimenten meer plaatsvinden - ca. vert.), verwijderen sa-logic-buggy en VirtualService door de volgende opdrachten uit te voeren:
We hebben het over twee belangrijke patronen in de microservice-architectuur waarmee u zelfherstel kunt bereiken (zelfgenezing) Diensten.
schakelaar("zekering") gebruikt om verzoeken te beëindigen die binnenkomen bij een exemplaar van een service die als ongezond wordt beschouwd en deze te herstellen terwijl clientverzoeken worden omgeleid naar gezonde exemplaren van die service (wat het percentage succesvolle reacties verhoogt). (Let op: Een meer gedetailleerde beschrijving van het patroon vindt u bijvoorbeeld op hier.)
waterdicht schot("partitie") voorkomt dat servicestoringen het hele systeem beïnvloeden. Service B is bijvoorbeeld kapot en een andere service (de client van Service B) doet een verzoek aan Service B, waardoor deze zijn threadpool leegmaakt en geen andere verzoeken kan verwerken (zelfs als deze niet van Service B komen). (Let op: Een meer gedetailleerde beschrijving van het patroon vindt u bijvoorbeeld op hier.)
Ik zal de implementatiedetails van deze patronen weglaten omdat ze gemakkelijk te vinden zijn officiële documentatie, en ik wil ook heel graag authenticatie en autorisatie laten zien, wat in het volgende deel van het artikel zal worden besproken.