Tilbage til mikrotjenester med Istio. Del 2

Tilbage til mikrotjenester med Istio. Del 2

Bemærk. overs.: Den første del Denne serie var dedikeret til at introducere Istio-kapaciteter og demonstrere dem i aktion. Nu vil vi tale om mere komplekse aspekter af konfigurationen og brugen af ​​dette servicenetværk, og især om finjusteret routing og netværkstrafikstyring.

Vi minder dig også om, at artiklen bruger konfigurationer (manifester for Kubernetes og Istio) fra lageret istio-mesterskab.

trafikstyring

Med Istio vises nye funktioner i klyngen for at give:

  • Dynamisk routing af anmodninger: udrulninger af kanariefugle, A/B-testning;
  • Lastbalancering: enkel og konsekvent, baseret på hashes;
  • Restitution efter fald: timeouts, genforsøg, afbrydere;
  • Indsættelse af fejl: forsinkelser, frafaldne anmodninger osv.

Som artiklen fortsætter, vil disse muligheder blive illustreret med den valgte applikation som eksempel, og nye koncepter vil blive introduceret undervejs. Det første sådan koncept vil være DestinationRules (dvs. regler om modtager af trafik/anmodninger - ca. oversættelse), ved hjælp af hvilken vi aktiverer A/B-test.

A/B-test: DestinationRules i praksis

A/B-test bruges i tilfælde, hvor der er to versioner af en applikation (normalt er de visuelt forskellige), og vi er ikke 100% sikre på, hvilken der vil forbedre brugeroplevelsen. Derfor kører vi begge versioner samtidigt og indsamler metrics.

For at implementere den anden version af frontend, der kræves for at demonstrere A/B-test, skal du køre følgende kommando:

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

Implementeringsmanifestet for den grønne version adskiller sig to steder:

  1. Billedet er baseret på et andet tag - istio-green,
  2. Bælge har en etiket version: green.

Da begge implementeringer har en etiket app: sa-frontend,anmodninger dirigeret af virtuel tjeneste sa-external-services til service sa-frontend, vil blive omdirigeret til alle dens forekomster, og belastningen vil blive distribueret igennem round-robin algoritme, hvilket vil føre til følgende situation:

Tilbage til mikrotjenester med Istio. Del 2
De anmodede filer blev ikke fundet

Disse filer blev ikke fundet, fordi de er navngivet forskelligt i 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

Dette betyder det index.html, der anmoder om en version af statiske filer, kan sendes af load balancer til pods, der har en anden version, hvor sådanne filer af åbenlyse årsager ikke findes. Derfor, for at applikationen skal fungere, skal vi sætte en begrænsning: "den samme version af applikationen, der serverede index.html, skal tjene efterfølgende anmodninger'.

Vi når dertil med konsekvent hash-baseret belastningsbalancering (Konsekvent Hash Loadbalancing). I dette tilfælde anmodninger fra den samme klient sendes til den samme backend-instans, hvortil der bruges en foruddefineret egenskab - for eksempel en HTTP-header. Implementeret ved hjælp af DestinationRules.

Destinationsregler

Efter VirtualService sendte en anmodning til den ønskede tjeneste, ved hjælp af DestinationRules kan vi definere politikker, der vil blive anvendt på trafik, der er bestemt til forekomster af denne tjeneste:

Tilbage til mikrotjenester med Istio. Del 2
Trafikstyring med Istio-ressourcer

Bemærk: Virkningen af ​​Istio-ressourcer på netværkstrafikken præsenteres her på en måde, der er let at forstå. For at være præcis, træffes beslutningen om, hvilken instans anmodningen skal sendes til af udsendingen i Ingress Gateway, der er konfigureret i CRD.

Med Destination Rules kan vi konfigurere belastningsbalancering til at bruge konsistente hashes og sikre, at den samme serviceinstans svarer til den samme bruger. Følgende konfiguration giver dig mulighed for at opnå dette (destinationsregel-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 - 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 created

Kør nu kommandoen nedenfor, og sørg for, at du får de rigtige filer, når du angiver overskriften version:

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

Bemærk: For at tilføje forskellige værdier i overskriften og teste resultaterne direkte i browseren, kan du bruge denne udvidelse til Chrome (eller med dette til Firefox - ca. oversættelse).

Generelt har DestinationRules flere muligheder inden for belastningsbalancering - tjek for detaljer i officiel dokumentation.

Før vi studerer VirtualService yderligere, lad os slette den "grønne version" af applikationen og den tilsvarende trafikretningsregel ved at kø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” deleted

Spejling: Virtuelle tjenester i praksis

shadowing ("afskærmning") eller spejling ("spejling") bruges i tilfælde, hvor vi ønsker at teste en ændring i produktionen uden at påvirke slutbrugerne: For at gøre dette duplikerer (“spejler”) vi anmodninger til en anden instans, hvor de ønskede ændringer er foretaget, og ser på konsekvenserne. Kort sagt er det, når din kollega vælger det mest kritiske emne og fremsætter en pull-anmodning i form af en så stor klump snavs, at ingen faktisk kan gennemgå den.

For at teste dette scenarie i aktion, lad os oprette en anden forekomst af SA-Logic med fejl (buggy) ved at køre følgende kommando:

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

Og lad os nu køre kommandoen for at sikre, at alle forekomster med app=sa-logic De har også etiketter med de tilsvarende versioner:

$ 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

Service sa-logic målretter mod bælg med en etiket app=sa-logic, så alle anmodninger vil blive fordelt mellem alle forekomster:

Tilbage til mikrotjenester med Istio. Del 2

... men vi ønsker, at anmodninger skal sendes til v1-instanser og spejles til v2-instanser:

Tilbage til mikrotjenester med Istio. Del 2

Dette vil vi opnå gennem VirtualService i kombination med DestinationRule, hvor reglerne vil bestemme undersæt og ruter for VirtualService til et specifikt undersæt.

Definering af undersæt i destinationsregler

Undersæt (undersæt) bestemmes af følgende konfiguration (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. vært (host) definerer, at denne regel kun gælder for tilfælde, hvor ruten går mod tjenesten sa-logic;
  2. Titler (name) undersæt bruges ved routing til undersætforekomster;
  3. Etiket (label) definerer de nøgleværdi-par, som instanser skal matche for at blive en del af undersættet.

Anvend konfigurationen med følgende kommando:

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

Nu hvor undersættene er defineret, kan vi gå videre og konfigurere VirtualService til at anvende regler på anmodninger til sa-logic, så de:

  1. Omdirigeret til en delmængde v1,
  2. Spejlet til en delmængde v2.

Følgende manifest giver dig mulighed for at nå dine planer (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

Ingen forklaring nødvendig her, så lad os bare se det i aktion:

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

Lad os tilføje belastningen ved at kalde følgende 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 du kan se, at versionen med fejl (buggy) resulterer i fejl for ~60 % af anmodningerne, men ingen af ​​disse fejl påvirker slutbrugere, da de bliver besvaret af en kørende tjeneste.

Tilbage til mikrotjenester med Istio. Del 2
Vellykkede svar fra forskellige versioner af sa-logic-tjenesten

Her så vi først, hvordan VirtualService anvendes på vores tjenesters udsendinge: hvornår sa-web-app fremsætter en anmodning til sa-logic, går den gennem sidevognen Envoy, som - via VirtualService - er konfigureret til at dirigere anmodningen til v1-undergruppen og spejle anmodningen til v2-undergruppen af ​​tjenesten sa-logic.

Jeg ved, du måske allerede tror, ​​at virtuelle tjenester er simpelt. I det næste afsnit vil vi udvide det ved at sige, at de også virkelig er fantastiske.

Kanariske udrulninger

Canary Deployment er processen med at udrulle en ny version af en applikation til et lille antal brugere. Det bruges til at sikre, at der ikke er nogen problemer i udgivelsen, og først derefter distribuere det til andre brugere, da det allerede er overbevist om dets (udgivelses) kvalitet.оstørre publikum.

For at demonstrere udrulninger af kanariefugle fortsætter vi med at arbejde med en undergruppe buggy у sa-logic.

Lad os ikke spilde tid på bagateller og straks sende 20% af brugerne til versionen med fejl (dette vil repræsentere vores kanarie-udrulning), og de resterende 80% til den normale service. For at gøre dette skal du bruge følgende VirtualService (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 er vægten (weight), som angiver procentdelen af ​​anmodninger, der vil blive rettet til en modtager eller en undergruppe af modtageren.

Lad os opdatere den tidligere VirtualService-konfiguration til sa-logic med 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 nogle anmodninger 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: 500

VirtualServices muliggør udrulning af canary: I dette tilfælde har vi indsnævret den potentielle indvirkning af problemerne til 20 % af brugerbasen. Vidunderlig! Nu, i alle tilfælde, hvor vi ikke er sikre på vores kode (med andre ord - altid...), kan vi bruge spejling og kanariske udrulninger.

Timeouts og genforsøg

Men fejl ender ikke altid i koden. På listen fra "8 misforståelser om distribueret databehandling"For det første er den fejlagtige tro på, at "netværket er pålideligt." I virkeligheden netværket nej pålidelig, og derfor har vi brug for timeouts (timeout) og forsøger igen (forsøg igen).

Til demonstration vil vi fortsætte med at bruge den samme problemversion sa-logic (buggy), og vi vil simulere netværkets upålidelighed med tilfældige fejl.

Lad vores service med fejl have en 1/3 chance for at tage for lang tid at svare, en 1/3 chance for at ende med en intern serverfejl og en 1/3 chance for at returnere siden.

For at afbøde virkningen af ​​sådanne problemer og gøre livet bedre for brugerne, kan vi:

  1. tilføje en timeout, hvis tjenesten tager længere end 8 sekunder at reagere,
  2. prøv igen, hvis anmodningen mislykkes.

Til implementering vil vi bruge følgende ressourcedefinition (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. Timeout for anmodningen er sat til 8 sekunder;
  2. Anmodninger prøves igen 3 gange;
  3. Og hvert forsøg anses for mislykket, hvis responstiden overstiger 3 sekunder.

Dette er en optimering, fordi brugeren ikke skal vente mere end 8 sekunder, og vi vil gøre tre nye forsøg på at få et svar i tilfælde af fejl, hvilket øger chancen for et vellykket 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 configured

Og tjek i Grafana-graferne, at antallet af vellykkede svar er steget ovenfor:

Tilbage til mikrotjenester med Istio. Del 2
Forbedringer i succesfulde svarstatistikker efter tilføjelse af timeouts og genforsøg

Inden du går videre til næste afsnit (eller rettere, til næste del af artiklen, for i denne vil der ikke være flere praktiske eksperimenter - ca. overs.), slette sa-logic-buggy og VirtualService ved at køre følgende kommandoer:

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

Strømafbryder og skotmønstre

Vi taler om to vigtige mønstre i mikroservicearkitektur, der giver dig mulighed for at opnå selvgendannelse (selvhelbredende) tjenester.

Afbryder ("afbryder") bruges til at afslutte anmodninger, der kommer til en forekomst af en tjeneste, der anses for usund, og gendanne den, mens klientanmodninger omdirigeres til sunde forekomster af den pågældende tjeneste (hvilket øger procentdelen af ​​vellykkede svar). (Bemærk: En mere detaljeret beskrivelse af mønsteret findes f.eks. her.)

Bulkhead ("skillevæg") isolerer servicefejl fra at påvirke hele systemet. For eksempel er Service B brudt, og en anden service (Service B's klient) sender en anmodning til Service B, hvilket får den til at udtømme sin trådpulje og ikke være i stand til at servicere andre anmodninger (selvom de ikke er fra Service B). (Bemærk: En mere detaljeret beskrivelse af mønsteret findes f.eks. her.)

Jeg vil udelade implementeringsdetaljerne for disse mønstre, fordi de er nemme at finde i officiel dokumentation, og jeg vil også rigtig gerne vise godkendelse og autorisation, hvilket vil blive diskuteret i næste del af artiklen.

PS fra oversætteren

Læs også på vores blog:

Kilde: www.habr.com

Tilføj en kommentar