Povratak na mikroservise s Istiom. 2. dio

Povratak na mikroservise s Istiom. 2. dio

Bilješka. prev.: Prvi dio Ova serija bila je posvećena predstavljanju Istio mogućnosti i njihovoj demonstraciji na djelu. Sada ćemo govoriti o složenijim aspektima konfiguracije i korištenja ove servisne mreže, a posebno o fino podešenom usmjeravanju i upravljanju mrežnim prometom.

Također vas podsjećamo da se u članku koriste konfiguracije (manifesti za Kubernetes i Istio) iz repozitorija istio-majstorstvo.

upravljanje prometom

Uz Istio, u klasteru se pojavljuju nove mogućnosti koje pružaju:

  • Dinamičko usmjeravanje zahtjeva: Canary rollouts, A/B testiranje;
  • Balansiranje opterećenja: jednostavan i dosljedan, temeljen na hashovima;
  • Oporavak nakon padova: istek vremena, ponovni pokušaji, prekidači;
  • Umetanje grešaka: kašnjenja, odbačeni zahtjevi itd.

Kako se članak nastavlja, te će mogućnosti biti ilustrirane korištenjem odabrane aplikacije kao primjera, a usput će se uvoditi novi koncepti. Prvi takav koncept bit će DestinationRules (tj. pravila o primatelju prometa/zahtjeva - pribl. prijevod), uz pomoć kojeg aktiviramo A/B testiranje.

A/B testiranje: DestinationRules u praksi

A/B testiranje se koristi u slučajevima kada postoje dvije verzije aplikacije (obično su vizualno različite) i nismo 100% sigurni koja će poboljšati korisničko iskustvo. Stoga pokrećemo obje verzije istovremeno i prikupljamo metrike.

Za implementaciju druge verzije sučelja, potrebne za demonstraciju A/B testiranja, pokrenite sljedeću naredbu:

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

Manifest implementacije za zelenu verziju razlikuje se na dva mjesta:

  1. Slika se temelji na drugoj oznaci - istio-green,
  2. Mahune imaju etiketu version: green.

Budući da obje implementacije imaju oznaku app: sa-frontend,zahtjevi koje usmjerava virtualna usluga sa-external-services za uslugu sa-frontend, bit će preusmjeren na sve svoje instance i opterećenje će se distribuirati kroz kružni algoritam, što će dovesti do sljedeće situacije:

Povratak na mikroservise s Istiom. 2. dio
Zatražene datoteke nisu pronađene

Ove datoteke nisu pronađene jer se drugačije nazivaju u različitim verzijama aplikacije. Uvjerimo se u ovo:

$ 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

Znači da index.html, zahtijevajući jednu verziju statičkih datoteka, balanser opterećenja može poslati podovima koji imaju drugu verziju, gdje, iz očitih razloga, takve datoteke ne postoje. Stoga, da bi aplikacija radila, moramo postaviti ograničenje: “ista verzija aplikacije koja je poslužila index.html trebala bi poslužiti sljedeće zahtjeve".

To ćemo postići dosljednim balansiranjem opterećenja na temelju hashiranja (Dosljedno balansiranje hash opterećenja), U ovom slučaju zahtjevi istog klijenta šalju se istoj pozadinskoj instanci, za koje se koristi unaprijed definirano svojstvo - na primjer, HTTP zaglavlje. Implementirano korištenjem DestinationRules.

DestinationRules

Nakon VirtualService poslao zahtjev željenoj usluzi, koristeći DestinationRules možemo definirati pravila koja će se primjenjivati ​​na promet namijenjen instancama ove usluge:

Povratak na mikroservise s Istiom. 2. dio
Upravljanje prometom s Istio resursima

Primijetiti: Utjecaj Istio resursa na mrežni promet ovdje je predstavljen na način koji je lako razumjeti. Točnije, odluku o tome kojoj instanci poslati zahtjev donosi Envoy u Ingress Gatewayu konfiguriranom u CRD-u.

Pomoću odredišnih pravila možemo konfigurirati balansiranje opterećenja za korištenje dosljednih hashova i osigurati da ista instanca usluge odgovara istom korisniku. Sljedeća konfiguracija omogućuje vam da to postignete (destinationrule-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 će se generirati na temelju sadržaja HTTP zaglavlja version.

Primijenite konfiguraciju sljedećom naredbom:

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

Sada pokrenite naredbu u nastavku i pobrinite se da dobijete prave datoteke kada navedete zaglavlje version:

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

Primijetiti: Da biste dodali različite vrijednosti u zaglavlju i testirali rezultate izravno u pregledniku, možete koristiti ovo proširenje u Chrome (Ili s ovim za Firefox - cca. prev.).

Općenito, DestinationRules ima više mogućnosti u području uravnoteženja opterećenja - provjerite detalje u službena dokumentacija.

Prije nego što dalje proučavamo VirtualService, izbrišite "zelenu verziju" aplikacije i odgovarajuće pravilo za usmjeravanje prometa pokretanjem sljedećih naredbi:

$ 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

Mirroring: Virtualne usluge u praksi

Sjenčanje ("zaštita") ili Zrcaljenje ("zrcaljenje") koristi se u slučajevima kada želimo testirati promjenu u proizvodnji bez utjecaja na krajnje korisnike: da bismo to učinili, dupliciramo ("zrcalimo") zahtjeve na drugu instancu gdje su napravljene željene promjene i gledamo posljedice. Jednostavno rečeno, to je kada vaš kolega odabere najkritičniji problem i napravi zahtjev za povlačenjem u obliku tako velike gomile prljavštine da je nitko ne može pregledati.

Kako bismo testirali ovaj scenarij na djelu, stvorimo drugu instancu SA-Logic s greškama (buggy) pokretanjem sljedeće naredbe:

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

A sada pokrenimo naredbu kako bismo bili sigurni da sve instance s app=sa-logic Imaju i oznake s odgovarajućim verzijama:

$ 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

Usluga sa-logic cilja mahune s oznakom app=sa-logic, tako da će svi zahtjevi biti raspoređeni među svim instancama:

Povratak na mikroservise s Istiom. 2. dio

... ali želimo da se zahtjevi šalju v1 instancama i preslikavaju na v2 instance:

Povratak na mikroservise s Istiom. 2. dio

To ćemo postići kroz VirtualService u kombinaciji s DestinationRule, gdje će pravila odrediti podskupove i rute VirtualServicea do određenog podskupa.

Definiranje podskupova u odredišnim pravilima

Podskupovi (podskupovi) određuju se sljedećom konfiguracijom (sa-logic-subset-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. Domaćin (host) definira da se ovo pravilo odnosi samo na slučajeve kada ruta ide prema servisu sa-logic;
  2. Naslovi (name) podskupovi se koriste pri usmjeravanju do instanci podskupa;
  3. Oznaka (label) definira parove ključ-vrijednost s kojima se instance moraju podudarati da bi postale dijelom podskupa.

Primijenite konfiguraciju sljedećom naredbom:

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

Sada kada su podskupovi definirani, možemo krenuti dalje i konfigurirati VirtualService za primjenu pravila na zahtjeve za sa-logiku tako da oni:

  1. Usmjeren na podskup v1,
  2. Zrcaljeno na podskup v2.

Sljedeći manifest omogućuje vam da ostvarite svoje planove (sa-logic-subset-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

Ovdje nije potrebno objašnjenje, pa da vidimo na djelu:

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

Dodajmo opterećenje pozivom sljedeće naredbe:

$ while true; do curl -v http://$EXTERNAL_IP/sentiment 
    -H "Content-type: application/json" 
    -d '{"sentence": "I love yogobella"}'; 
    sleep .8; done

Pogledajmo rezultate u Grafani, gdje možete vidjeti da je verzija s greškama (buggy) rezultira neuspjehom za ~60% zahtjeva, ali nijedan od tih neuspjeha ne utječe na krajnje korisnike jer na njih odgovara pokrenuta usluga.

Povratak na mikroservise s Istiom. 2. dio
Uspješni odgovori različitih verzija sa-logic usluge

Ovdje smo prvi put vidjeli kako se VirtualService primjenjuje na izaslanike naših usluga: kada sa-web-app postavlja zahtjev za sa-logic, prolazi kroz sidecar Envoy, koji je - putem VirtualService-a - konfiguriran za usmjeravanje zahtjeva na v1 podskup i zrcaljenje zahtjeva na v2 podskup usluge sa-logic.

Znam, možda već mislite da su virtualne usluge jednostavne. U sljedećem ćemo odjeljku to proširiti govoreći da su i oni uistinu izvrsni.

Canary Rollouts

Canary Deployment je proces postavljanja nove verzije aplikacije malom broju korisnika. Koristi se kako bi se uvjerili da nema problema u izdanju i tek nakon toga, već uvjereni u njegovu (izdanja) kvalitetu, distribuirati ga ostalim korisnicima.оveću publiku.

Kako bismo demonstrirali uvođenje kanarinca, nastavit ćemo raditi s podskupom buggy у sa-logic.

Nemojmo gubiti vrijeme na sitnice i odmah poslati 20% korisnika na verziju s greškama (ovo će predstavljati naš kanarinčić rollout), a preostalih 80% na normalnu uslugu. Da biste to učinili, koristite sljedeći VirtualService (sa-logic-podskupovi-kanarinac-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 je težina (weight), koji navodi postotak zahtjeva koji će biti usmjereni primatelju ili podskupu primatelja.

Ažurirajmo prethodnu konfiguraciju VirtualService za sa-logic sa sljedećom naredbom:

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

... i odmah ćemo vidjeti da neki zahtjevi dovode do neuspjeha:

$ 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 omogućuju Canary rollouts: U ovom slučaju, suzili smo potencijalni utjecaj problema na 20% baze korisnika. Predivno! Sada, u svakom slučaju kada nismo sigurni u naš kod (drugim riječima - uvijek...), možemo koristiti zrcaljenje i canary rollouts.

Istek vremena i ponovni pokušaji

Ali greške ne završavaju uvijek u kodu. Na popisu iz "8 zabluda o distribuiranom računalstvu“Na prvom mjestu je pogrešno uvjerenje da je “mreža pouzdana”. U stvarnosti mreža ne pouzdan, i iz tog razloga su nam potrebni timeoutovi (istek vremena) i ponovno pokušava (ponovni pokušaji).

Za demonstraciju ćemo nastaviti koristiti istu verziju problema sa-logic (buggy), a mi ćemo simulirati nepouzdanost mreže sa slučajnim kvarovima.

Neka naša usluga s greškama ima 1/3 šanse da predugo odgovori, 1/3 šanse da završi s internom greškom poslužitelja i 1/3 šanse da uspješno vrati stranicu.

Kako bismo ublažili utjecaj takvih problema i učinili život korisnicima boljim, možemo:

  1. dodajte vremensko ograničenje ako servisu treba više od 8 sekundi da odgovori,
  2. pokušaj ponovno ako zahtjev ne uspije.

Za implementaciju ćemo koristiti sljedeću definiciju resursa (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. Istek vremena za zahtjev postavljen je na 8 sekundi;
  2. Zahtjevi se ponavljaju 3 puta;
  3. I svaki se pokušaj smatra neuspješnim ako vrijeme odgovora prelazi 3 sekunde.

Ovo je optimizacija jer korisnik neće morati čekati više od 8 sekundi, a mi ćemo napraviti tri nova pokušaja da dobijemo odgovor u slučaju neuspjeha, čime se povećava mogućnost uspješnog odgovora.

Primijenite ažuriranu konfiguraciju sljedećom naredbom:

$ kubectl apply -f resource-manifests/istio/retries/sa-logic-retries-timeouts-vs.yaml
virtualservice.networking.istio.io/sa-logic configured

A da li je gore porastao broj uspješnih odgovora provjerite u grafikonima Grafane:

Povratak na mikroservise s Istiom. 2. dio
Poboljšanja statistike uspješnih odgovora nakon dodavanja vremenskih ograničenja i ponovnih pokušaja

Prije nego prijeđete na sljedeći odjeljak (odnosno, na sljedeći dio članka, jer u ovom više neće biti praktičnih eksperimenata - pribl. prev.), brisanje sa-logic-buggy i VirtualService pokretanjem sljedećih naredbi:

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

Uzorci prekidača i pregrada

Govorimo o dva važna obrasca u arhitekturi mikroservisa koji vam omogućuju postizanje samooporavka (samoizlječenje) usluge.

Osigurač ("osigurač") koristi se za prekid zahtjeva koji dolaze na instancu usluge koja se smatra nezdravom i vraćanje iste dok se zahtjevi klijenata preusmjeravaju na zdrave instance te usluge (što povećava postotak uspješnih odgovora). (Napomena: Detaljniji opis uzorka možete pronaći, na primjer, здесь.)

Pregrada ("particija") izolira kvarove usluge od utjecaja na cijeli sustav. Na primjer, usluga B je pokvarena i druga usluga (klijent usluge B) upućuje zahtjev usluzi B, uzrokujući da ona iscrpi svoj skup niti i ne može servisirati druge zahtjeve (čak i ako nisu iz usluge B). (Napomena: Detaljniji opis uzorka možete pronaći, na primjer, здесь.)

Izostavit ću detalje implementacije ovih obrazaca jer ih je lako pronaći službena dokumentacija, a također stvarno želim pokazati autentifikaciju i autorizaciju, o čemu će biti riječi u sljedećem dijelu članka.

PS od prevoditelja

Pročitajte i na našem blogu:

Izvor: www.habr.com

Dodajte komentar