Povratak na mikroservise sa Istiom. Dio 2

Povratak na mikroservise sa Istiom. Dio 2

Bilješka. transl.: Prvi dio ovaj ciklus je bio posvećen upoznavanju sa mogućnostima Istia i njihovom demonstriranju na djelu. Sada ćemo govoriti o složenijim aspektima konfiguracije i korištenja ove mreže usluga, a posebno o fino podešenom rutiranju i upravljanju mrežnim prometom.

Također vas podsjećamo da članak koristi konfiguracije (manifeste za Kubernetes i Istio) iz spremišta istio-majstorstvo.

upravljanje saobraćajem

Uz Istio, nove funkcije su dodane u klaster kako bi se osiguralo:

  • Dinamičko usmjeravanje zahtjeva: izvođenje kanarinca, A/B testiranje;
  • balansiranje opterećenja: jednostavan i dosljedan, baziran na hashovima;
  • Oporavak nakon padova: vremenska ograničenja, ponovni pokušaji, prekidači;
  • Uvođenje kvarova: kašnjenja, prekid zahtjeva itd.

Kako se članak nastavlja, ove karakteristike će biti demonstrirane koristeći odabranu aplikaciju kao primjer, a usput će biti predstavljeni i novi koncepti. Prvi takav koncept će biti DestinationRules (tj. pravila o primaocu saobraćaja/zahtjeva - pribl. prev.), s kojim aktiviramo A/B testiranje.

A/B testiranje: Pravila odredišta u praksi

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

Da biste implementirali drugu verziju frontenda koja je potrebna za demo 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 je zasnovana na drugoj oznaci − istio-green,
  2. Mahune imaju etiketu version: green.

Zato što obje implementacije imaju oznaku app: sa-frontend, zahtjevi koje usmjerava virtuelna usluga sa-external-services za uslugu sa-frontend, bit će preusmjeren na sve svoje instance i opterećenje će biti raspoređeno po round-robin algoritam, što će dovesti do sljedeće situacije:

Povratak na mikroservise sa Istiom. Dio 2
Zatraženi fajlovi nisu pronađeni

Ove datoteke nisu pronađene zbog činjenice da su drugačije nazvane u različitim verzijama aplikacije. Hajde da to proverimo:

$ 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 index.htmlZahtevanje jedne verzije statičkih fajlova može biti poslato od strane balansera opterećenja podovima koji imaju drugu verziju, gde iz očiglednih razloga takvi fajlovi ne postoje. Stoga, da bi aplikacija radila, moramo postaviti ograničenje: "ista verzija aplikacije koja je vratila index.html mora poslužiti sljedeće zahtjeve".

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

DestinationRules

Posle Virtuelna usluga poslao zahtjev na željenu uslugu, koristeći DestinationRules možemo definirati politike koje će se primjenjivati ​​na promet namijenjen instancama ove usluge:

Povratak na mikroservise sa Istiom. Dio 2
Upravljanje prometom pomoću Istio resursa

primjedba: Uticaj Istio resursa na mrežni promet je ovdje predstavljen u pojednostavljenom obliku za razumijevanje. Da budemo precizni, odluku o tome kojoj instanci poslati zahtjev donosi Izaslanik u Ingress Gatewayu konfigurisanom u CRD-u.

Sa odredišnim pravilima možemo postaviti balansiranje opterećenja kako bismo koristili konzistentne hešove i osigurali da ista instanca usluge odgovara istom korisniku. Sljedeća konfiguracija to postiže (destinacijarule-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 - heš će biti generisan na osnovu 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 ispod i uvjerite se da ste dobili prave datoteke kada navedete naslov version:

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

primjedba: Da biste dodali različite vrijednosti u zaglavlje i testirali rezultate direktno u pretraživaču, možete koristiti ovo proširenje u Chrome (ili ovo za Firefox - cca. prevod).

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

Prije daljnjeg istraživanja VirtualServicea, uklonimo "zelenu verziju" aplikacije i odgovarajuće pravilo za smjer 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: virtuelne usluge u praksi

Senka ("zaštita") ili Mirroring ("zrcaljenje") koristi se u slučajevima kada želimo da testiramo promenu u proizvodnji bez uticaja na krajnje korisnike: da bismo to uradili, dupliramo („preslikavamo“) zahteve na drugu instancu gde se vrše potrebne promene i gledamo posledice. Jednostavno rečeno, to je kada vaš kolega odabere najkritičniji problem i uputi zahtjev za povlačenjem u tako ogromnoj gomili prljavštine da ga niko zapravo ne može pregledati.

Da bismo testirali ovaj scenario u akciji, napravimo drugu instancu SA-Logic-a sa 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 su sve instance sa 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 sa etiketom app=sa-logic, tako da će svi zahtjevi biti raspoređeni među svim instancama:

Povratak na mikroservise sa Istiom. Dio 2

… ali želimo da se zahtjevi usmjeravaju na v1 instance i preslikavaju na v2 instance:

Povratak na mikroservise sa Istiom. Dio 2

To postižemo kroz VirtualService u kombinaciji sa DestinationRule, gdje pravila definiraju podskupove i rute VirtualServicea do određenog podskupa.

Definiranje podskupova u Pravilima odredišta

Podskupovi (podskupovi) definisano sljedećom konfiguracijom (sa-logic-podsets-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 primjenjuje samo na slučajeve kada ruta ide prema servisu sa-logic;
  2. imena (name) podskupovi se koriste kada se usmjeravaju na instance podskupova;
  3. Oznaka (label) definira parove ključ/vrijednost koje instance moraju odgovarati da bi postale 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 created

Sada kada su podskupovi definirani, možemo nastaviti i konfigurirati VirtualService da primjenjuje pravila na zahtjeve sa-logic tako da:

  1. Preusmjeren na podskup v1,
  2. Preslikano na podskup v2.

Sljedeći manifest vam omogućava da postignete svoje ciljeve (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

Ovdje nije potrebno objašnjenje, pa pogledajmo to 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 pozivanjem 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 sa greškama (buggy) ne uspijeva za ~60% zahtjeva, ali nijedan od ovih kvarova ne utiče na krajnje korisnike jer na njih odgovara pokrenuta usluga.

Povratak na mikroservise sa Istiom. Dio 2
Uspješnost odgovora različitih verzija sa-logic servisa

Ovdje smo prvi put vidjeli kako se VirtualService primjenjuje na našu uslugu Poslanici: kada sa-web-app postavlja zahtjev za sa-logic, prolazi kroz sidecar Envoy, koji je - kroz VirtualService - konfiguriran da usmjerava zahtjev na v1 podskup i odražava zahtjev na v2 podskup usluge sa-logic.

Znam: već ste imali vremena da mislite da su virtuelne usluge jednostavne. U sljedećem dijelu ćemo proširiti ovo mišljenje rekavši da su i oni zaista odlični.

Canary Rollouts

Canary Deployment je proces uvođenja nove verzije aplikacije malom broju korisnika. Koristi se kako bi se osiguralo da nema problema u izdanju, a tek nakon toga, već sigurni u njegov dovoljan (izdajući) kvalitet, distribuirati gaоveća publika.

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

Nemojmo gubiti vrijeme na sitnice i odmah pošaljimo 20% korisnika na verziju sa greškama (to će predstavljati naše kanarinsko izvođenje), a preostalih 80% na normalan servis. Da biste to učinili, primijenite sljedeći 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 je težina (weight) koji specificira postotak zahtjeva koji će biti upućeni primaocu, ili podskup primaoca.

Ažurirajte prethodnu konfiguraciju VirtualService za sa-logic sa sljedećom komandom:

$ 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 od zahtjeva 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 pokreću uvođenje kanaraca: u ovom slučaju, suzili smo potencijalni utjecaj problema na 20% korisničke baze. Divno! Sada, u svakom slučaju kada nismo sigurni u naš kod (drugim riječima, uvijek...), možemo koristiti preslikavanje i kanarinsko uvođenje.

Istek vremena i ponovni pokušaji

Ali greške ne završavaju uvijek u kodu. Na listi od8 zabluda u distribuiranom računarstvu” na prvom mjestu je pogrešno mišljenje da je “mreža pouzdana”. U stvarnosti mreža ne pouzdan, i iz tog razloga nam je potrebno vremensko ograničenje (istek vremena) i ponovo pokušava (ponovni pokušaji).

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

Neka naš servis sa greškama ima 1/3 šanse da predugo odgovara, 1/3 da završi internom greškom servera i 1/3 da uspešno renderuje stranicu.

Da bismo ublažili uticaj ovih problema i poboljšali živote naših korisnika, možemo:

  1. dodajte vremensko ograničenje ako usluga odgovara duže od 8 sekundi,
  2. pokušajte ponovo ako zahtjev ne uspije.

Za implementaciju koristimo 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. Vremensko ograničenje za zahtev je postavljeno na 8 sekundi;
  2. Zahtjevi se ponavljaju 3 puta;
  3. Svaki pokušaj se smatra neuspjelim ako vrijeme odgovora prelazi 3 sekunde.

Ovo je optimizacija jer korisnik ne mora čekati više od 8 sekundi, a mi ćemo napraviti tri nova pokušaja da dobijemo odgovor u slučaju neuspjeha, povećavajući šanse za uspješan odgovor.

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

I provjerite na Grafana grafikonima da je broj uspješnih odgovora gotov:

Povratak na mikroservise sa Istiom. Dio 2
Poboljšanja statistike uspjeha nakon dodavanja vremenskih ograničenja i ponovnih pokušaja

Prije prelaska na sljedeći odjeljak (tačnije - već u sljedećem dijelu članka, jer u ovim praktičnim eksperimentima više neće biti - pribl. prev.), izbriši 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

Obrasci prekidača i pregrada

Govorimo o dva važna obrasca u mikroservisnoj arhitekturi koji vam omogućavaju da postignete samo-oporavak. (samoizlječenje) usluge.

Prekidač ("prekidač") koristi se za zaustavljanje zahtjeva koji dolaze do instance usluge koja se smatra nezdravom i vraćanje iste dok se zahtjevi klijenta preusmjeravaju na zdrave instance te usluge (što povećava stopu uspješnosti). (Prim. napomena: Detaljniji opis uzorka može se naći, npr. ovdje.)

Pregrada ("particija") izoluje kvarove u uslugama od poraza cijelog sistema. Na primjer, usluga B je pokvarena, a druga usluga (klijent usluge B) upućuje zahtjev servisu B, uzrokujući da iskoristi svoj skup niti i ne može poslužiti druge zahtjeve (čak i ako ne pripadaju servisu B). (Prim. napomena: Detaljniji opis uzorka može se naći, npr. ovdje.)

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

PS od prevodioca

Pročitajte i na našem blogu:

izvor: www.habr.com

Dodajte komentar