
Bem. overs.: Denne cyklus var dedikeret til at introducere mulighederne for Istio og demonstrere dem i aktion. Nu vil vi fokusere på de mere komplekse aspekter af konfiguration og brug af dette service mesh, især den fint indstillede routing og trafikstyring.
Vi minder også om, at artiklen bruger konfigurationer (manifester til Kubernetes og Istio) fra depotet. .
Trafikstyring
Med Istio i klyngen opstår der nye muligheder, der gør det muligt at sikre:
- Dynamisk routing af forespørgsler: kanary-udrulninger, A/B-test;
- Lastbalancering: enkel og konsekvent, baseret på hashes;
- Genopretning efter fejl: timeouts, genforsøg, circuit breakers;
- Indsættelse af fejl: forsinkelser, afbrydelser af forespørgsler osv.
I fortsættelsen af artiklen vil disse muligheder blive vist ved hjælp af et udvalgt program, og nye koncepter vil desuden blive præsenteret. Den første af disse koncepter vil være DestinationRules (dvs. regler for modtageren af trafik/forespørgsler — red.)., som vi bruger til at aktivere A/B-test.
A/B-test: DestinationRules i praksis
A/B-test anvendes i situationer, hvor der findes to versioner af et program (de adskiller sig typisk visuelt), og vi ikke er sikre på 100%, hvilken der vil forbedre brugeroplevelsen. Derfor kører vi begge versioner samtidigt og indsamler metrics.
For at deploye den anden version af frontend’en, som er nødvendig til demonstration af A/B-test, skal du udføre følgende kommando:
$ kubectl apply -f resource-manifests/kube/ab-testing/sa-frontend-green-deployment.yaml
deployment.extensions/sa-frontend-green createdManifestet for deployment af 'grøn version' adskiller sig på to punkter:
- Billedet er baseret på en anden tag —
istio-green, - Pods har et label
version: green.
Da begge deployment har label app: sa-frontend, vil forespørgsler, der routeres gennem den virtuelle tjeneste sa-external-services til tjenesten sa-frontend, blive omdirigeret til alle dens instanser, og belastningen vil blive fordelt via , hvilket vil føre til følgende situation:

Anmodede filer blev ikke fundet
Disse filer blev ikke fundet, fordi de har forskellige navne i de forskellige versioner af programmet. Lad os sikre os dette:
$ 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 Det betyder, at index.html, en anmodning om en version af statiske filer kan sendes af lastbalancer til pods, der har en anden version, hvor sådanne filer, af åbenlyse grunde, ikke eksisterer. Derfor er det nødvendigt for applikationen at fastsætte en begrænsning: «den samme version af applikationen, som leverede index.html, skal betjene de efterfølgende anmodninger».
Vi vil nå målet ved hjælp af konsistent belastningsbalancering baseret på hashing (Consistent Hash Loadbalancing). I dette tilfælde sendes anmodninger fra én klient til den samme backend-forekomst, hvilket opnås ved hjælp af en foruddefineret egenskab – for eksempel en HTTP-header. Dette implementeres med DestinationRules.
DestinationRules
Efter at VirtualService har dirigeret anmodningen til den rette service, kan vi ved hjælp af DestinationRules definere politikker, der vil blive anvendt på trafikken for de instanser af denne service:

Trafikstyring med Istio-ressourcer
Bemærk: Indflydelsen af Istio-ressourcer på netværkstrafik præsenteres her i en forenklet forståelig form. For at være præcis, træffes beslutningen om, hvilken instans anmodningen skal sendes til, af Envoy i Ingress Gateway, der er konfigureret i CRD.
Ved hjælp af Destination Rules kan vi konfigurere lastbalancering, så der anvendes konsistente hashes, og der sikres, at den samme serviceinstans altid svarer til den samme bruger. Den følgende konfiguration muliggør dette ():
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: sa-frontend
spec:
host: sa-frontend
trafficPolicy:
loadBalancer:
consistentHash:
httpHeaderName: version # 1 1 — hash vil blive genereret baseret på indholdet af HTTP-headeren version.
Anvend konfigurationen med følgende kommando:
$ kubectl apply -f resource-manifests/istio/ab-testing/destinationrule-sa-frontend.yaml
destinationrule.networking.istio.io/sa-frontend oprettet Udfør nu kommandoen nedenfor og bekræft, at du får de ønskede filer, når du angiver headeren version:
$ curl --silent -H "version: yogo" http://$EXTERNAL_IP/ | tr '"' 'n' | grep mainBemærk: For at tilføje forskellige værdier til headeren og teste resultaterne direkte i browseren, kan du bruge til Chrome (eller til Firefox — bem. overs..
Generelt har DestinationRules flere muligheder inden for lastbalancering — kontakt for nærmere oplysninger. .
Før vi fortsætter med at studere VirtualService, fjerner vi den "grønne version" af applikationen og det tilsvarende trafikstyrringsregel ved at udføre følgende kommandoer:
$ kubectl delete -f resource-manifests/kube/ab-testing/sa-frontend-green-deployment.yaml
deployment.extensions "sa-frontend-green" deleted
$ kubectl delete -f resource-manifests/istio/ab-testing/destinationrule-sa-frontend.yaml
destinationrule.networking.istio.io "sa-frontend" deletedSpejling: Virtual Services i praksis
Shadowing ("skygge") eller Mirroring ("spejling") anvendes i situationer, hvor vi ønsker at teste en ændring i produktion uden at påvirke slutbrugerne: til dette duplikerer vi ("spejler") forespørgslerne til en anden instans, hvor de ønskede ændringer er foretaget, og ser på konsekvenserne. Sagt på en enklere måde, det er når din kollega tager det mest kritiske problem og laver en pull request i form af et så stort rod, at ingen rent faktisk kan anmelde det.
For at teste dette scenarie i aktion, opretter vi en anden instans af SA-Logic med fejl (buggy), ved at udføre følgende kommando:
$ kubectl apply -f resource-manifests/kube/shadowing/sa-logic-service-buggy.yaml
deployment.extensions/sa-logic-buggy created Og nu udfører vi en kommando for at sikre os, at alle instanser med app=sa-logic også har etiketter med de relevante versioner:
$ kubectl get pods -l app=sa-logic --show-labels
NAVN KLAR ETIKETTER
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 Service sa-logic er rettet mod pods med etiketten app=sa-logic, derfor vil alle forespørgsler blive fordel delt mellem alle instanser:

… men vi ønsker, at forespørgsler skal sendes til instanser med version v1 og spejles til instanser med version v2:

Dette vil vi opnå via VirtualService i kombination med DestinationRule, hvor reglerne vil bestemme delmængder og ruter for VirtualService til det specifikke delmængde.
Definition af delmængder i Destination Rules
Delmængder (subsets) defineres ved følgende konfiguration ():
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- Værten (
host) definerer, at denne regel kun gælder, når ruten går mod tjenestensa-logic; - Navne (
name) for delmængderne bruges til at rute til instanser i delmængden; - Etiketten (
label) definerer nøgle-værdi par, som instanser skal opfylde for at blive en del af undergruppen.
Anvend konfigurationen med følgende kommando:
$ kubectl apply -f resource-manifests/istio/shadowing/sa-logic-subsets-destinationrule.yaml
destinationrule.networking.istio.io/sa-logic oprettetNu hvor undergrupperne er defineret, kan vi gå videre og konfigurere VirtualService til at anvende reglerne på anmodninger til sa-logic, så de:
- Rutes til undergruppen
v1, - Spejles til undergruppen
v2.
Den næste manifest opnår det ønskede ():
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: v2Der er ikke behov for forklaringer her, så lad os se det i aktion:
$ kubectl apply -f resource-manifests/istio/shadowing/sa-logic-subsets-shadowing-vs.yaml
virtualservice.networking.istio.io/sa-logic oprettetLad os tilføje belastningen ved at kalde denne kommando:
$ while true; do curl -v http://$EXTERNAL_IP/sentiment
-H "Content-type: application/json"
-d '{"sentence": "I love yogobella"}';
sleep .8; done Lad os se på resultaterne i Grafana, hvor vi kan se, at versionen med fejl (buggy) forårsager fejlslag til ~60 % af anmodningerne, men ingen af disse fejl påvirker de endelige brugere, da de får svar fra den fungerende tjeneste.

Succesen af svarene fra forskellige versioner af tjenesten sa-logic
Her så vi første gang, hvordan VirtualService anvendes i forhold til vores tjenesters Envoy’er: når sa-web-app der gør en anmodning til sa-logic, går den gennem sidecar Envoy, som – via VirtualService – er konfigureret til at rute anmodningen til undergruppen v1 og spejle anmodningen til undergruppen v2 af tjenesten sa-logic.
Jeg ved: du har allerede tænkt, at Virtual Services er enkle. I det næste afsnit vil vi udvide denne opfattelse ved at vise, at de rent faktisk også er fantastiske.
Canary deployments
Canary Deployment er processen med at rulle en ny version af applikationen ud til et lille antal brugere. Det bruges til at sikre, at der ikke er problemer i udgivelsen, og først derefter, når man er sikker på, at kvaliteten af udgivelsen er tilstrækkelig, udbrede den til enfleste afstørre audience.
For at demonstrere canary-udrulninger vil vi fortsætte arbejdet med undergruppen buggy af sa-logic.
Lad os ikke være smålige og sende 20 % af brugerne direkte til versionen med fejl (det vil være vores canary-udrulning), mens de resterende 80 % går til den normale tjeneste. For dette anvender vi følgende VirtualService ():
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 — dette er vægten (weight), der bestemmer procentdelen af anmodninger, der sendes til modtageren eller en undergruppe af modtageren.
Lad os opdatere den tidligere VirtualService-konfiguration med sa-logic følgende kommando:
$ kubectl apply -f resource-manifests/istio/canary/sa-logic-subsets-canary-vs.yaml
virtualservice.networking.istio.io/sa-logic configured… og vi vil straks se, at en del af anmodningerne fører til fejl:
$ 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: 500VirtualServices aktiverer kanary-udrulninger: i dette tilfælde har vi indsnævret de potentielle konsekvenser af problemer til 20 % af brugerbasen. Fantastisk! Nu, hver gang vi ikke er sikre på vores kode (med andre ord — altid...), kan vi bruge spejling og kanary-udrulninger.
Timeouts og genforsøg
Men fejl ligger ikke altid i koden. På listen over „” er det fejlaktige indtryk, at „netværket er pålideligt“ det første punkt. I virkeligheden er netværket ikke pålideligt, og derfor har vi brug for timeouts (timeouts) og genforsøg (retries).
For at demonstrere vil vi fortsætte med den samme problemversion sa-logic (buggy), mens netværksusikkerheden vil blive simuleret med tilfældige fejl.
Lad vores fejlbehæftede service have 1/3 chance for et for langvarigt svar, 1/3 chance for at afslutte med en Internal Server Error, og 1/3 chance for at returnere en succesfuld side.
For at mildne konsekvenserne af sådanne problemer og gøre livet lettere for brugerne kan vi:
- tilføje en timeout, hvis servicen svarer længere end 8 sekunder,
- foretage et genforsøg, hvis anmodningen fejler.
Til implementeringen vil vi bruge følgende ressourcebeskrivelse ():
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- Timeout for anmodningen er indstillet til 8 sekunder;
- Genforsøg af anmodninger foretages 3 gange;
- Og hver forsøg betragtes som mislykket, hvis svartiden overstiger 3 sekunder.
På denne måde opnåede vi optimering, da brugeren ikke vil skulle vente mere end 8 sekunder, og vi vil foretage tre nye forsøg på at få et svar i tilfælde af fejl og dermed øge chancen for et succesfuldt svar.
Anvend den opdaterede konfiguration med følgende kommando:
$ kubectl apply -f resource-manifests/istio/retries/sa-logic-retries-timeouts-vs.yaml
virtualservice.networking.istio.io/sa-logic konfigureretOg tjek i Grafana-diagrammerne, at antallet af succesfulde svar er steget over:

Forbedringer i statistikken for succesfulde svar efter tilføjelse af tidsgrænser og gentagelser
Før vi går videre til næste sektion (eller rettere sagt - allerede til næste del af artiklen, da der ikke vil være flere praktiske eksperimenter i denne - bem. overs.), slet sa-logic-buggy og VirtualService ved at udføre følgende kommandoer:
$ kubectl delete deployment sa-logic-buggy
department.extensions “sa-logic-buggy” slettet
$ kubectl delete virtualservice sa-logic
virtualservice.networking.istio.io “sa-logic” slettetMønstre for Circuit Breaker og Bulkhead
Det handler om to vigtige mønstre i mikrotjenestearkitektur, der muliggør selvhelbredelse (self-healing) af tjenester.
Circuit Breaker («automatiske afbryder») bruges til at stoppe anmodninger, der kommer til en tjenesteinstans, der betragtes som usund, og dens genopretning, mens anmodninger fra kunder omdirigeres til sunde instanser af denne tjeneste (hvilket øger procentdelen af succesfulde svar). (Bem. overs.: En mere detaljeret beskrivelse af mønsteret kan findes, f.eks. .)
Bulkhead («skillevæg») isolerer fejl i tjenester fra at påvirke hele systemet. For eksempel, hvis tjeneste B er nede, og en anden tjeneste (klient af tjeneste B) laver en anmodning til tjeneste B, vil den udnytte sin trådpool og ikke være i stand til at håndtere andre anmodninger (selv hvis de ikke relaterer til tjeneste B). (Bem. overs.: En mere detaljeret beskrivelse af mønsteret kan findes, f.eks. .)
Jeg vil undlade at gå ind i detaljerne om implementeringen af disse mønstre, da de er lette at finde, , og jeg vil virkelig gerne vise autentificering og autorisation, som vil blive behandlet i den næste del af artiklen.
P.S. fra oversætteren
Læs også på vores blog:
- «Tilbage til mikrotjenester sammen med Istio»: , ;
- «»;
- «».
Kilde: habr.com
