
Napomena za prijevod.: 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 .
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 createdManifest deploymenta za 'zelenu verziju' razlikuje se na dva mjesta:
- Slika se temelji na drugoj oznaci —
istio-green, - 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 , što će dovesti do sljedeće situacije:

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:

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 ():
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 mainNapomena: Da biste dodali različite vrijednosti u zaglavlju i testirali rezultate izravno u pregledniku, možete koristiti za Chrome (ili za Firefox — napomena prevoditelja).
Uglavnom, DestinationRules imaju više mogućnosti u području balansiranja opterećenja — detalje provjerite u .
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" deletedZrcaljenje: 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:

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

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 ():
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- Host (
host) definira da se ovo pravilo primjenjuje samo na slučajeve kada ruta ide prema servisusa-logic; - Nazivi (
ime) podgrupa koriste se prilikom usmjeravanja na instance podgrupe; - 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 kreiranSada kada su podskupovi definirani, možemo dalje nastaviti i konfigurirati VirtualService kako bismo primijenili pravila na zahtjeve prema sa-logic, kako bi:
- Bila usmjerena na podskup
v1, - Bila zrcaljena na podskup
v2.
Sljedeći manifest omogućava postizanje željenog ():
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: v2Objaš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 kreiranDodajmo 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.

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.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: 500VirtualServices 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 "" 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:
- dodati timeout ako servis odgovara duže od 8 sekundi,
- poduzeti ponovni pokušaj ako zahtjev ne uspije.
Za implementaciju koristićemo sljedeću definiciju resursa ():
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- Timeout za zahtjev postavljen je na 8 sekundi;
- Ponovni pokušaji zahtjeva poduzimaju se 3 puta;
- 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 konfiguriranI provjerite u Grafana grafikama da je broj uspješnih odgovora porastao iznad:

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” obrisanPatterni 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, .)
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, .)
Preskočit ću detalje o implementaciji ovih obrazaca, jer ih je lako pronaći u , 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:
- «Povratak mikroservisima uz Istio»: , ;
- «»;
- «».
Izvor: habr.com
