Tilbake til mikrotjenester med Istio. Del 2

Tilbake til mikrotjenester med Istio. Del 2

Merk. overs.: Den første delen Denne serien var dedikert til å introdusere Istio-funksjoner og demonstrere dem i aksjon. Nå skal vi snakke om mer komplekse aspekter ved konfigurasjonen og bruken av dette tjenestenettet, og spesielt om finjustert ruting og administrasjon av nettverkstrafikk.

Vi minner deg også om at artikkelen bruker konfigurasjoner (manifester for Kubernetes og Istio) fra depotet istio-mestring.

Trafikkstyring

Med Istio vises nye funksjoner i klyngen for å gi:

  • Dynamisk forespørselsruting: utrullinger av kanarifugler, A/B-testing;
  • Lastbalansering: enkel og konsistent, basert på hashes;
  • Restitusjon etter fall: tidsavbrudd, forsøk på nytt, strømbrytere;
  • Innsetting av feil: forsinkelser, henlagte forespørsler osv.

Ettersom artikkelen fortsetter, vil disse egenskapene bli illustrert ved å bruke den valgte applikasjonen som eksempel, og nye konsepter vil bli introdusert underveis. Det første slike konsept vil være DestinationRules (dvs. regler om mottaker av trafikk/forespørsler - ca. oversettelse), ved hjelp av dette aktiverer vi A/B-testing.

A/B-testing: Destinasjonsregler i praksis

A/B-testing brukes i tilfeller der det er to versjoner av en applikasjon (vanligvis er de visuelt forskjellige) og vi er ikke 100 % sikre på hvilken som vil forbedre brukeropplevelsen. Derfor kjører vi begge versjonene samtidig og samler inn beregninger.

For å distribuere den andre versjonen av grensesnittet, nødvendig for å demonstrere A/B-testing, kjør 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 versjonen er forskjellig på to steder:

  1. Bildet er basert på en annen tag - istio-green,
  2. Pods har en etikett version: green.

Siden begge distribusjonene har en etikett app: sa-frontend,forespørsler rutet av virtuell tjeneste sa-external-services for service sa-frontend, vil bli omdirigert til alle forekomstene, og lasten vil bli distribuert gjennom round-robin algoritme, som vil føre til følgende situasjon:

Tilbake til mikrotjenester med Istio. Del 2
De forespurte filene ble ikke funnet

Disse filene ble ikke funnet fordi de heter forskjellig i forskjellige versjoner av programmet. La oss sørge for 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 betyr at index.html, som ber om én versjon av statiske filer, kan sendes av lastbalanseren til pods som har en annen versjon, der slike filer av åpenbare grunner ikke eksisterer. Derfor, for at applikasjonen skal fungere, må vi sette en begrensning: "den samme versjonen av programmet som leverte index.html skal tjene påfølgende forespørsler'.

Vi kommer dit med konsekvent hasj-basert belastningsbalansering (Konsekvent Hash Load Balancing)... I dette tilfellet forespørsler fra samme klient sendes til samme backend-instans, som en forhåndsdefinert egenskap brukes for - for eksempel en HTTP-header. Implementert ved hjelp av DestinationRules.

Destinasjonsregler

Etter VirtualService sendte en forespørsel til ønsket tjeneste, ved å bruke DestinationRules kan vi definere retningslinjer som vil bli brukt på trafikk destinert for forekomster av denne tjenesten:

Tilbake til mikrotjenester med Istio. Del 2
Trafikkstyring med Istio-ressurser

Note: Effekten av Istio-ressurser på nettverkstrafikk presenteres her på en måte som er lett å forstå. For å være presis, avgjørelsen om hvilken instans forespørselen skal sendes til, tas av utsendingen i Ingress Gateway konfigurert i CRD.

Med Destination Rules kan vi konfigurere lastbalansering for å bruke konsistente hasher og sikre at samme tjenesteforekomst svarer til samme bruker. Følgende konfigurasjon lar deg oppnå dette (destinationsrule-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 bli generert basert på innholdet i HTTP-headeren version.

Bruk konfigurasjonen med følgende kommando:

$ kubectl apply -f resource-manifests/istio/ab-testing/destinationrule-sa-frontend.yaml
destinationrule.networking.istio.io/sa-frontend created

Kjør nå kommandoen nedenfor og sørg for at du får de riktige filene når du spesifiserer overskriften version:

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

Note: For å legge til forskjellige verdier i overskriften og teste resultatene direkte i nettleseren, kan du bruke denne utvidelsen til Chrome (eller med dette for Firefox - ca. oversett.).

Generelt har DestinationRules flere muligheter innen lastbalansering - sjekk for detaljer i offisiell dokumentasjon.

Før vi studerer VirtualService videre, la oss slette den "grønne versjonen" av applikasjonen og den tilsvarende trafikkretningsregelen ved å kjø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

Speiling: virtuelle tjenester i praksis

skygging ("skjerming") eller speiling ("speiling") brukes i tilfeller der vi ønsker å teste en produksjonsendring uten å påvirke sluttbrukere: For å gjøre dette dupliserer («speiler») vi forespørsler til en andre instans der de ønskede endringene er gjort, og ser på konsekvensene. Enkelt sagt, dette er når kollegaen din velger det mest kritiske problemet og kommer med en pull-forespørsel i form av en så stor klump med skitt at ingen faktisk kan vurdere den.

For å teste dette scenariet i aksjon, la oss lage en andre forekomst av SA-Logic med feil (buggy) ved å kjøre følgende kommando:

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

Og la oss nå kjøre kommandoen for å sikre at alle forekomster med app=sa-logic De har også etiketter med tilsvarende versjoner:

$ 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

Verktøy sa-logic retter seg mot pods med en etikett app=sa-logic, så alle forespørsler vil bli distribuert mellom alle forekomster:

Tilbake til mikrotjenester med Istio. Del 2

... men vi vil at forespørsler skal sendes til v1-forekomster og speiles til v2-forekomster:

Tilbake til mikrotjenester med Istio. Del 2

Dette vil vi oppnå gjennom VirtualService i kombinasjon med DestinationRule, hvor reglene vil bestemme undersettene og rutene til VirtualService til et spesifikt undersett.

Definere delsett i destinasjonsregler

Delmengder (undersett) bestemmes av følgende konfigurasjon (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. vert (host) definerer at denne regelen kun gjelder tilfeller når ruten går mot tjenesten sa-logic;
  2. Titler (name) delsett brukes ved ruting til delsettforekomster;
  3. Etikett (label) definerer nøkkelverdi-parene som forekomster må matche for å bli en del av delsettet.

Bruk konfigurasjonen med følgende kommando:

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

Nå som delsettene er definert, kan vi gå videre og konfigurere VirtualService til å bruke regler på forespørsler til sa-logic slik at de:

  1. Rutet til et undersett v1,
  2. Speilet til et delsett v2.

Følgende manifest lar deg oppnå planene dine (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å la oss bare se det i aksjon:

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

La oss legge til lasten ved å ringe 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

La oss se på resultatene i Grafana, hvor du kan se at versjonen med feil (buggy) resulterer i feil for ~60 % av forespørslene, men ingen av disse feilene påvirker sluttbrukere ettersom de blir besvart av en kjørende tjeneste.

Tilbake til mikrotjenester med Istio. Del 2
Vellykkede svar fra forskjellige versjoner av sa-logic-tjenesten

Her så vi først hvordan VirtualService brukes på utsendingene til våre tjenester: når sa-web-app gjør en forespørsel til sa-logic, går den gjennom sidevognen Envoy, som - via VirtualService - er konfigurert til å rute forespørselen til v1-delsettet og speile forespørselen til v2-delsettet av tjenesten sa-logic.

Jeg vet, du tror kanskje allerede at virtuelle tjenester er enkelt. I den neste delen vil vi utvide det ved å si at de også er virkelig flotte.

Kanarieutrullinger

Canary Deployment er prosessen med å rulle ut en ny versjon av en applikasjon til et lite antall brukere. Den brukes for å sikre at det ikke er noen problemer i utgivelsen, og først etter det, som allerede er trygg på (utgivelsens) kvalitet, distribuerer den til andre brukere.оstørre publikum.

For å demonstrere utrullinger av kanarifugler, vil vi fortsette å jobbe med en undergruppe buggy у sa-logic.

La oss ikke kaste bort tid på bagateller og umiddelbart sende 20% av brukerne til versjonen med bugs (dette vil representere vår kanarie-utrulling), og de resterende 80% til den vanlige tjenesten. For å gjøre dette, bruk 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 vekten (weight), som spesifiserer prosentandelen av forespørsler som vil bli rettet til en mottaker eller en undergruppe av mottakeren.

La oss oppdatere den forrige VirtualService-konfigurasjonen for 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 umiddelbart se at noen forespørsler fører til feil:

$ 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 muliggjør utrulling av kanarifugler: I dette tilfellet har vi begrenset den potensielle effekten av problemene til 20 % av brukerbasen. Herlig! Nå, i alle tilfeller når vi ikke er sikre på koden vår (med andre ord - alltid...), kan vi bruke speiling og kanarieutrullinger.

Tidsavbrudd og nye forsøk

Men feil havner ikke alltid i koden. I listen fra "8 misoppfatninger om distribuert databehandling"For det første er den feilaktige troen på at "nettverket er pålitelig." I virkeligheten nettverket no pålitelig, og av denne grunn trenger vi timeouts (timeout) og prøver på nytt (forsøker på nytt).

For demonstrasjon vil vi fortsette å bruke den samme problemversjonen sa-logic (buggy), og vi vil simulere upåliteligheten til nettverket med tilfeldige feil.

La vår tjeneste med feil ha en 1/3 sjanse for å ta for lang tid å svare, en 1/3 sjanse for å ende med en intern serverfeil, og en 1/3 sjanse for å lykkes med å returnere siden.

For å dempe virkningen av slike problemer og gjøre livet bedre for brukere, kan vi:

  1. legg til et tidsavbrudd hvis tjenesten tar mer enn 8 sekunder å svare,
  2. prøv på nytt hvis forespørselen mislykkes.

For implementering vil vi bruke følgende ressursdefinisjon (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. Tidsavbruddet for forespørselen er satt til 8 sekunder;
  2. Forespørsler prøves på nytt 3 ganger;
  3. Og hvert forsøk anses som mislykket hvis responstiden overstiger 3 sekunder.

Dette er en optimalisering fordi brukeren ikke trenger å vente mer enn 8 sekunder, og vi vil gjøre tre nye forsøk på å få svar ved feil, noe som øker sjansen for en vellykket respons.

Bruk den oppdaterte konfigurasjonen 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 sjekk i Grafana-grafene at antallet vellykkede svar har økt ovenfor:

Tilbake til mikrotjenester med Istio. Del 2
Forbedringer i vellykket responsstatistikk etter å ha lagt til tidsavbrudd og forsøk på nytt

Før du går videre til neste avsnitt (eller rettere sagt, til neste del av artikkelen, for i denne vil det ikke være flere praktiske eksperimenter - ca. overs.), slette sa-logic-buggy og VirtualService ved å kjø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ømbryter og skottmønstre

Vi snakker om to viktige mønstre i mikrotjenestearkitektur som lar deg oppnå selvgjenoppretting (selv helbreding) tjenester.

Circuit Breaker ("strømbryter") brukes til å avslutte forespørsler som kommer til en forekomst av en tjeneste som anses som usunn og gjenopprette den mens klientforespørsler omdirigeres til sunne forekomster av den tjenesten (noe som øker prosentandelen av vellykkede svar). (Merk: En mer detaljert beskrivelse av mønsteret finner du f.eks. her.)

Skott ("skillevegg") isolerer tjenestefeil fra å påvirke hele systemet. For eksempel er tjeneste B ødelagt og en annen tjeneste (tjeneste Bs klient) sender en forespørsel til tjeneste B, noe som får den til å tømme trådpoolen sin og ikke være i stand til å betjene andre forespørsler (selv om de ikke er fra tjeneste B). (Merk: En mer detaljert beskrivelse av mønsteret finner du f.eks. her.)

Jeg vil utelate implementeringsdetaljene til disse mønstrene fordi de er enkle å finne i offisiell dokumentasjon, og jeg ønsker også virkelig å vise autentisering og autorisasjon, som vil bli diskutert i neste del av artikkelen.

PS fra oversetter

Les også på bloggen vår:

Kilde: www.habr.com

Legg til en kommentar