Povratak na mikroservise zajedno s Istio-om. Dio 2

Povratak na mikroservise zajedno s Istio-om. Dio 2

Napomena za prijevod.: Prvi dio Ovaj ciklus bio je posvećen upoznavanju s mogućnostima Istio i njihovoj demonstraciji u praksi. Sada ćemo se fokusirati na složenije aspekte konfiguracije i korištenja ove service mesh, a posebno na fino podešavanje rutiranja i upravljanje mrežnim prometom.

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

Upravljanje prometom

S Istio u klasteru pojavljuju se nove mogućnosti koje omogućuju:

  • Dinamičko rutiranje zahtjeva: kanarinski izlasci, A/B testiranje;
  • Raspodjela opterećenja: jednostavno i dosljedno, zasnovano na heširanju;
  • Obnavljanje nakon kvara: vremenska ograničenja, ponovni pokušaji, circuit breakers;
  • Uvođenje grešaka: kašnjenja, prekidi zahtjeva itd.

U nastavku članka ove mogućnosti bit će prikazane na konkretnom primjeru aplikacije i usput će biti predstavljene nove koncepcije. Prva takva koncepcija bit će DestinationRules (tj. pravila o odredištu prometa/zahtjeva — napomena prev.), pomoću kojih aktiviramo A/B testiranje.

A/B testiranje:  DestinationRules u praksi

A/B testiranje se primjenjuje u situacijama kada postoje dvije verzije aplikacije (obično se razlikuju vizualno) i nismo 100% sigurni koja će od njih poboljšati korisničku interakciju. Stoga istovremeno pokrećemo obje verzije i prikupljamo metrike.

Za postavljanje druge verzije frontenda, potrebne za demonstraciju A/B testiranja, izvršite sljedeću naredbu:

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

Manifest deploymenta za 'zelenu verziju' razlikuje se na dva mjesta:

  1. Slika se temelji na drugoj oznaci — istio-green,
  2. Podovi imaju oznaku version: green.

Budući da oba deploymenta imaju oznaku app: sa-frontend, zahtjevi koji se usmjeravaju putem virtualne usluge sa-external-services na uslugu sa-frontend, bit će preusmjereni na sve njene instance, a opterećenje će se raspodijeliti pomoću round-robin algoritma, što će dovesti do sljedeće situacije:

Povratak na mikroservise zajedno s Istio-om. Dio 2
Zatraženi datoteke nisu pronađene

Ove datoteke nisu pronađene jer se različito nazivaju u raznim verzijama aplikacije. Provjerimo to:

$ 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

To znači da index.html, tražeći jednu verziju statičkih datoteka, može se poslati na balansiranje opterećenja na podove koji imaju drugu verziju, gdje, iz očitih razloga, takve datoteke ne postoje. Stoga, da bi aplikacija radila, potrebno je postaviti ograničenje: „ista verzija aplikacije koja je poslala index.html, treba obraditi i sve daljnje zahtjeve».

Ostvarit ćemo cilj uz dosljedno balansiranje opterećenja na temelju hashova (Dosljedno hash balansiranje opterećenja). U ovom slučaju zahtjevi jednog klijenta se šalju u istu instancu pozadinske usluge, za što se koristi prethodno definirana osobina — na primjer, HTTP header. Implementira se pomoću DestinationRules.

DestinationRules

Nakon što VirtualService usmjeri zahtjev na odgovarajuću uslugu, pomoću DestinationRules možemo odrediti politike koje će se primjenjivati na promet namijenjen instancama te usluge:

Povratak na mikroservise zajedno s Istio-om. Dio 2
Upravljanje prometom s Istio resursima

Napomena: Utjecaj Istio resursa na mrežni promet prikazan je ovdje u pojednostavljenom obliku za razumijevanje. Ako budemo precizni, odluka o tome kojoj instanci poslati zahtjev donosi Envoy u Ingress Gateway-u, konfiguriranom u CRD.

Pomoću Destination Rules možemo postaviti balansiranje opterećenja tako da se koriste dosljedni hashovi i osiguraju odgovori iste instance usluge istom korisniku. Sljedeća konfiguracija omogućava to (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

A sada izvršite donju naredbu i uvjerite se da dobivate potrebne datoteke kada navedete zaglavlje version:

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

Napomena: Da biste dodali različite vrijednosti u zaglavlju i testirali rezultate izravno u pregledniku, možete koristiti ovaj dodatak za Chrome (ili ovaj za Firefox — napomena prevoditelja).

Uglavnom, DestinationRules imaju više mogućnosti u području balansiranja opterećenja — detalje provjerite u službene dokumentacije.

Prije nego što nastavimo s proučavanjem VirtualService-a, uklonimo "zelenu verziju" aplikacije i odgovarajuće pravilo za usmjeravanje prometa izvršavanjem 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

Zrcaljenje: Virtual Services u praksi

Shadowing ("maskiranje") ili Mirroring ("zrcaljenje") primjenjuje se kada želimo testirati promjenu u produkciji bez utjecaja na krajnje korisnike: za to dupliciramo ("zrcalimo") zahtjeve na drugu instancu u kojoj su izvršene potrebne promjene i promatramo posljedice. Jednostavnije rečeno, to je kada vaš/a kolega bira najkritičniji problem i stvara pull request u obliku takvog ogromnog klupka nereda da nitko zapravo ne može pregledati.

Kako bismo testirali ovaj scenarij u akciji, stvorit ćemo drugu instancu SA-Logic-a s greškama (buggy), izvršavanjem sljedeće naredbe:

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

I sada ćemo izvršiti naredbu kako bismo bili sigurni da sve instance s app=sa-logic imaju također 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

Servis sa-logic usmjeren je na podove s oznakom app=sa-logic, tako da će svi zahtjevi biti raspoređeni između svih instanci:

Povratak na mikroservise zajedno s Istio-om. Dio 2

… ali želimo da se zahtjevi usmjere na instance s verzijom v1 i zrcale na instance s verzijom v2:

Povratak na mikroservise zajedno s Istio-om. Dio 2

To ćemo postići putem VirtualService-a u kombinaciji s DestinationRule-om, gdje pravila definiraju podgrupe i rute VirtualService-a prema konkretnoj podgrupi.

Definiranje podgrupa u Destination Rules

Podgrupe (subsets) određuju se sljedećom konfiguracijom (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. Host (host) definira da se ovo pravilo primjenjuje samo na slučajeve kada ruta ide prema servisu sa-logic;
  2. Nazivi (ime) podgrupa koriste se prilikom usmjeravanja na instance podgrupe;
  3. Oznaka (label) određuje parove ključ-vrijednost kojima primjerci moraju udovoljavati da bi postali dio podskupa.

Primijenite konfiguraciju sljedećom naredbom:

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

Sada kada su podskupovi definirani, možemo dalje nastaviti i konfigurirati VirtualService kako bismo primijenili pravila na zahtjeve prema sa-logic, kako bi:

  1. Bila usmjerena na podskup v1,
  2. Bila zrcaljena na podskup v2.

Sljedeći manifest omogućava postizanje željenog (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

Objašnjenja nisu potrebna ovdje, pa samo pogledajmo u akciji:

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

Dodajmo opterećenje pozivom ove 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 se može vidjeti da verzija s greškom (buggy) uzrokuje grešku za ~60 % zahtjeva, ali nijedna od tih grešaka ne utječe na krajnje korisnike, jer im odgovara radna usluga.

Povratak na mikroservise zajedno s Istio-om. Dio 2
Uspješnost odgovora različitih verzija usluge sa-logic

Ovdje smo prvi put vidjeli kako se VirtualService primjenjuje u odnosu na Envoye naših usluga: kada sa-web-app izvrši zahtjev prema sa-logic, prolazi kroz sidecar Envoy, koji — putem VirtualService — postavljen je za usmjeravanje zahtjeva prema podskupu v1 i zrcaljenje zahtjeva prema podskupu v2 usluge sa-logic.

Znam: već ste pomislili da su Virtual Services jednostavni. U sljedećem odjeljku proširit ćemo ovo mišljenje time što su oni također zaista veličanstveni.

Kanarinci ili canary ispuštanja

Canary Deployment — proces uvodjenja nove verzije aplikacije za mali broj korisnika. Koristi se da bi se osiguralo da nema problema u izdanju, a tek nakon toga, kada budemo sigurni u dovoljnu kvalitetu (izdanja), prošit ćemo ga na veće publike.oZa demonstraciju kanarinskih ispuštanja nastavit ćemo rad s podskupom

Nećemo se zadržavati i odmah ćemo poslati 20 % korisnika na verziju s greškama (ona će predstavljati naše kanarinsko ispuštanje), a preostalih 80 % na normalnu uslugu. Za to ćemo primijeniti sljedeći VirtualService ( buggy u sa-logic.

sa-logic-subsets-canary-vs.yamlsa-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 — to je težina (težina), koja određuje postotak zahtjeva koji će biti usmjereni na odredište ili podskup odredišta.

Ažurirajmo prošlu konfiguraciju VirtualService s sa-logic sljedećom komandom:

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

… i odmah ćemo vidjeti da dio zahtjeva dovodi do grešaka:

$ while true; do 
   curl -i http://$EXTERNAL_IP/sentiment 
   -H "Content-type: application/json" 
   -d '{"sentence": "I love yogobella"}' 
   --silent -w "Vrijeme: %{time_total}s t Status: %{http_code}n" 
   -o /dev/null; sleep .1; done
Vrijeme: 0.153075s Status: 200
Vrijeme: 0.137581s Status: 200
Vrijeme: 0.139345s Status: 200
Vrijeme: 30.291806s Status: 500

VirtualServices aktiviraju kanarinske isporuke: u ovom slučaju suzili smo potencijalne posljedice problema na 20 % korisničke baze. Odlično! Sada, svaki put kada nismo sigurni u naš kod (drugim riječima — uvijek…), možemo koristiti zrcaljenje i kanarinske isporuke.

Timeouti i ponovni pokušaji

Ali greške nisu uvijek u kodu. Na popisu od "8 zabluda u distribuiranim računalstvima" na prvom mjestu nalazi se pogrešno uvjerenje da je "mreža pouzdana". U stvarnosti, mreža ne je pouzdana, i zato su nam potrebni timeouti (timeouti) i ponovni pokušaji (ponovni pokušaji).

Za demonstraciju nastavit ćemo koristiti isti problem verziju sa-logic (buggy), a nepouzdano stanje mreže simulirat ćemo slučajnim greškama.

Pretpostavimo da naš servis s greškama ima 1/3 šanse za predugi odgovor, 1/3 za završavanje s greškom Internal Server Error i 1/3 za uspješno vraćanje stranice.

Kako bismo ublažili posljedice takvih problema i poboljšali korisničko iskustvo, možemo:

  1. dodati timeout ako servis odgovara duže od 8 sekundi,
  2. poduzeti ponovni pokušaj ako zahtjev ne uspije.

Za implementaciju koristićemo 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. Timeout za zahtjev postavljen je na 8 sekundi;
  2. Ponovni pokušaji zahtjeva poduzimaju se 3 puta;
  3. Svaka pokušaj se smatra neuspješnim ako vrijeme odgovora prelazi 3 sekunde.

Tako smo optimizirali proces, jer korisnik neće morati čekati više od 8 sekundi, a mi ćemo pokušati tri nova puta dobiti odgovor u slučaju grešaka, povećavajući šanse za uspješan odgovor.

Primijenite ažuriranu konfiguraciju sljedećom komandom:

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

I provjerite u Grafana grafikama da je broj uspješnih odgovora porastao iznad:

Povratak na mikroservise zajedno s Istio-om. Dio 2
Poboljšanja u statistikama uspješnih odgovora nakon dodavanja vremenskih ograničenja i ponovljenih pokušaja

Prije nego pređete na sljedeći odjeljak (točnije — već na sljedeći dio članka, budući da u ovom dijelu više neće biti praktičnih eksperimenata — napomena prev.), obrišite sa-logic-buggy i VirtualService, izvršavajući sljedeće komande:

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

Patterni Circuit Breaker i Bulkhead

Radi se o dva važna obrasca u mikroservisnoj arhitekturi, koji omogućuju autonomno oporavak (self-healing) servisa.

Circuit Breaker («automatski prekidač») se koristi za prekinuti zahtjeve koji dolaze na instancu servisa koja se smatra nezdravom, a njegovo obnavljanje dok se zahtjevi korisnika preusmjeravaju na zdrave instance ovog servisa (što povećava postotak uspješnih odgovora). (Napomena prev.: Detaljniji opis obrasca može se pronaći, na primjer, ovdje.)

Bulkhead («pregrada») izolira greške u servisima od utjecaja na cijeli sustav. Na primjer, servis B je pokvaren, a drugi servis (klijent servisa B) šalje zahtjev servisu B, zbog čega taj servis troši svoj bazen niti i ne može obraditi druge zahtjeve (čak i ako se ne odnose na servis B). (Napomena prev.: Detaljniji opis obrasca može se pronaći, na primjer, ovdje.)

Preskočit ću detalje o implementaciji ovih obrazaca, jer ih je lako pronaći u službene dokumentacije, a također želim prikazati autentifikaciju i autorizaciju, o čemu će se raspravljati u sljedećem dijelu članka.

P.S. od prevodioca

Pročitajte i na našem blogu:

Izvor: habr.com

Kupite pouzdan hosting za web stranice s DDoS zaštitom, VPS VDS servere 🔥 Kupite pouzdan hosting za web stranice s DDoS zaštitom, VPS VDS servere | ProHoster