
Shën. përkth.: Ky kyçim të këtij cikli ishte prezantimi i mundësive të Istio dhe demostrimi i tyre në veprim. Tani do të flasim për aspekte më të komplikuara të konfigurimit dhe përdorimit të këtij service mesh, veçanërisht për rrugetimin e hollësishëm dhe menaxhimin e trafikut rrjetës.
Kujtojmë gjithashtu se artikulli përdor konfigurime (manifeste për Kubernetes dhe Istio) nga repozitori .
Menaxhimi i trafikut
Me Istio, në klaster shfaqen mundësi të reja që lejojnë:
- Rrugëtimin dinamik të kërkesave: lançime kanarie, testim A/B;
- Balancimin e ngarkesës: të thjeshtë dhe të paqëndrueshme, të bazuar në hash;
- Rimëkëmbjen pas dështimeve: kohët e pritjes, përpjekjet e përsëritura, thyesa circuit;
- Identifikimin e defekteve: vonesa, ndërprerje të kërkesave etj.
Në vazhdim të artikullit, këto mundësi do të demonstrohen me shembuj të aplikacioneve të zgjedhura dhe do të prezantohen gjithashtu koncepte të reja. Koncepti i parë i tillë do të jetë DestinationRules (dmth. rregullat për destinacionin e trafikut/kërkesave — shënimi i përkthyesit), me ndihmën e të cilave ne aktivizojmë testimin A/B.
Testimi A/B: DestinationRules në praktikë
Testimi A/B përdoret kur ekzistojnë dy versione të aplikacionit (zakonisht ato ndryshojnë vizualisht) dhe nuk jemi të sigurt 100% se cila do të përmirësojë ndërveprimin me përdoruesin. Kështu që ne lançojmë të dyja versionet njëkohësisht dhe mbledhim metrikat.
Për të deployuar versionin e dytë të frontend-it, i nevojshëm për demostrimin e testimit A/B, ekzekutoni komandën e mëposhtme:
$ kubectl apply -f resource-manifests/kube/ab-testing/sa-frontend-green-deployment.yaml
deployment.extensions/sa-frontend-green createdManifesti i deployment për "versionin e gjelbër" ndryshon në dy vende:
- Imazhi është i bazuar në një etiketë tjetër —
istio-green, - Pod-at kanë etiketën
version: green.
Pasi të dyja deployment-et kanë etiketën app: sa-frontend, kërkesat që rrugetohen nga shërbimi virtual sa-external-services në shërbimin sa-frontend, do të redirigjohen në të gjithë instancat e tij dhe ngarkesa do të shpërndahet përmes , që do të çojë në situatën e mëposhtme:

Skedarët e kërkuar nuk u gjetën
Këta skedarë nuk u gjetën për shkak se ata quhen ndryshe në versione të ndryshme të aplikacionit. Le të sigurohemi për këtë:
$ 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 Kjo do të thotë se index.html, që kërkon një version të njëjtë të skedarëve statikë, mund të dërgohet nga balancuesi i ngarkesës në pod'ët që kanë një version tjetër, ku, për arsye të kuptueshme, të tillë skedarë nuk ekzistojnë. Prandaj, që aplikacioni të funksionojë, ne duhet të vendosim një kufizim: "versioni i njëjtë i aplikacionit që dha index.html, duhet të shërbejë dhe për kërkesat e mëtejshme».
Ne do të arrijmë objektivin me ndihmën e balancimit të ngarkesës së qëndrueshëm mbi baza hashes (Balancimi i Ngarkesës me Hash të Qëndrueshëm). Në këtë rast kërkesat nga një klient dërgohen në të njëjtin instancë të backend-it, për të cilin përdoret një pronë e paracaktuar — për shembull, HTTP-header. I realizuar me ndihmën e DestinationRules.
DestinationRules
Pasi është VirtualService direktoi kërkesën në shërbimin e duhur, me ndihmën e DestinationRules ne mund të përcaktojmë politikat që do të aplikohen për trafik të destinuar për instancat e këtij shërbimi:

Menaxhimi i trafikut me burimet Istio
Shënim: Ndikimi i burimeve Istio në trafikun rrjetor paraqitet këtu në një mënyrë të thjeshtë për t'u kuptuar. Nëse të jemi të saktë, vendimi se në cilën instancë të dërgohet kërkesa, merret nga Envoy në Ingress Gateway, i konfiguruar në CRD.
Me ndihmën e Destination Rules ne mund ta konfigurojmë balancimin e ngarkesës në mënyrë që të përdoren hashes të qëndrueshme dhe të garantohen përgjigjet nga e njëjta instancë e shërbimit për të njëjtin përdorues. Konfigurimi në vazhdim lejon arritjen e këtij qëllimi ():
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: sa-frontend
spec:
host: sa-frontend
trafficPolicy:
loadBalancer:
consistentHash:
httpHeaderName: version # 1 1 — hash-i do të gjenerohet mbi bazën e përmbajtjes së HTTP-headerit version.
Apliko konfigurimin me komandën në vazhdim:
$ kubectl apply -f resource-manifests/istio/ab-testing/destinationrule-sa-frontend.yaml
destinationrule.networking.istio.io/sa-frontend created Tani, ekzekutoni komandën më poshtë dhe sigurohuni që po merrni skedarët e duhur, kur specifikoni headerin version:
$ curl --silent -H "version: yogo" http://$EXTERNAL_IP/ | tr '"' 'n' | grep mainShënim: Për të shtuar vlera të ndryshme në header dhe për të testuar rezultatet direkt në shfletues, mund të përdorni për Chrome (ose për Firefox — shënim i përkthyesit).
Në përgjithësi, DestinationRules ka më shumë mundësi në fushën e balancimit të ngarkesës — detajet specifikoni në .
Para të vazhdojmë me studimin e VirtualService, le të fshijmë aplikacionin "versioni i gjelbër" dhe rregullin përkatës për drejtimin e trafikut duke ekzekutuar komandat e mëposhtme:
$ kubectl delete -f resource-manifests/ kube/ ab-testing/ sa-frontend-green-deployment.yaml
deployment.extensions "sa-frontend-green" u fshij
$ kubectl delete -f resource-manifests/ istio/ ab-testing/ destinationrule-sa-frontend.yaml
destinationrule.networking.istio.io "sa-frontend" u fshijPërgjysmë: Virtual Services në praktikë
Shadowing ("mbrojtje") ose Mirroring ("përgjysmë") përdoret kur dëshirojmë të testojmë një ndryshim në produksion, pa prekur përdoruesit përfundimtarë: për këtë, ne kopjojmë ("përgjysmë") kërkesat në një ekzemplar të dytë, ku janë bërë ndryshimet e nevojshme dhe shohim pasojat. Thjesht, kjo ndodh kur kolegu juaj zgjidh çështjen më kritike dhe bën një pull request në formën e një grumbulli të madh të papastruar, aq sa askush nuk mund ta shqyrtojë atë në të vërtetë.
Për të provuar këtë skenar në veprim, do të krijojmë një ekzemplar të dytë të SA-Logic me defekte (defekt), duke ekzekutuar komandën e mëposhtme:
$ kubectl apply -f resource-manifests/ kube/ shadowing/ sa-logic-service-buggy.yaml
deployment.extensions/ sa-logic-buggy u krijua Dhe tani do të ekzekutojmë komandën për të verifikuar se të gjithë ekzemplarët me app=sa-logic kanë gjithashtu etiketat përkatëse me versionet:
$ kubectl get pods -l app=sa-logic --show-labels
EMRI GATI ETIKETAT
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 Shërbimi sa-logic direkt në pod’ët me etiketë app=sa-logic, prandaj të gjitha kërkesat do të shpërndahen mes të gjithë ekzemplarëve:

… por ne duam që kërkesat të drejtohen te ekzemplarët me versionin v1 dhe të përgjysmojnë në ekzemplarët me versionin v2:

Këtë do ta arrijmë përmes VirtualService në kombinim me DestinationRule, ku rregullat do të përcaktojnë nëngrupet dhe rrugët e VirtualService për një nëngrup të veçantë.
Përkufizimi i nëngrupit në Rregullat e Destinacionit
Nëngrupet (nëngrupet) përcaktohen nga konfigurimi i mëposhtëm ():
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- Hosti (
host) përcakton se ky rregull zbatohet vetëm në rastet kur ruta shkon drejt shërbimitsa-logic; - Emrat (
emri) e nëngrupeve përdoren gjatë drejtimeve të ekzemplarëve të nëngrupit; - Etiketa (
label) përcakton çiftet çelës-vlerë, të cilat duhet të përmbushen nga instancat për t'u bërë pjesë e një nëngrupe.
Apliko konfigurimin me komandën në vazhdim:
$ kubectl apply -f resource-manifests/istio/shadowing/sa-logic-subsets-destinationrule.yaml
destinationrule.networking.istio.io/sa-logic u krijuaTani që nëngrupet janë përcaktuar, mund të vazhdojmë dhe të konfigurojmë VirtualService për të aplikuar rregullat në kërkesat për sa-logic, në mënyrë që ato:
- Të route-ohen në nëngrup
v1, - Të mirror-ohen në nëngrup
v2.
Manifesti i mëposhtëm lejon arritjen e atij që është menduar ():
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: v2Shpjegimet këtu nuk janë të nevojshme, kështu që thjesht do të shohim në veprim:
$ kubectl apply -f resource-manifests/istio/shadowing/sa-logic-subsets-shadowing-vs.yaml
virtualservice.networking.istio.io/sa-logic u krijuaLe t'i shtojmë ngarkesat duke thirrur këtë komandë:
$ while true; do curl -v http://$EXTERNAL_IP/sentiment
-H "Content-type: application/json"
-d '{"sentence": "I love yogobella"}';
sleep .8; done Të shohim rezultatet në Grafana, ku mund të shohim se versioni me defekte (defekt) çon në dështim për ~60% të kërkesave, por asnjë nga këto dështime nuk i prek përdoruesit përfundimtar, pasi ata iu përgjigjen nga shërbimi funksional.

Sukseset e përgjigjeve të versioneve të ndryshme të shërbimit sa-logic
Këtu e pamë për herë të parë se si VirtualService aplikohet në lidhje me Envoy-t e shërbimeve tona: kur sa-web-app bën një kërkesë në sa-logic, ajo kalon përmes sidecar Envoy, i cili - përmes VirtualService - është konfiguruar për të route-uar kërkesën në nëngrupin v1 dhe për të mirror-uar kërkesën në nëngrupin v2 të shërbimit. sa-logic.
E di: ju tashmë keni menduar se Virtual Services janë të thjeshta. Në pjesën e ardhshme ne do ta zgjerim këtë mendim duke treguar se ato janë vërtet të shkëlqyera.
Zbatimi kanarin
Kanari Deployment - procesi i lëshimit të një versioni të ri të aplikacionit për një numër të vogël përdoruesish. Përdoret për të siguruar që nuk ka probleme në lëshim dhe vetëm pas kësaj, kur jemi të sigurt për cilësinë e mjaftueshme të tij (lëshimit), shpërthejmë në njëoaudiencë më të madhe.
Për të demonstruar lëshimet kanar, ne do të vazhdojmë punën me nëngrupin defekt i sa-logic.
Nuk do ta bejme të vogël dhe menjëherë do të dërgojmë 20% të përdoruesve në versionin me defekte (ai do të paraqesë lëshimin tonë kanar), ndërsa 80% e mbetur do të shkojnë në shërbimin normal. Për këtë, do të aplikojmë VirtualService të mëposhtëm ():
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 — është peshë (peshë), e cila përcakton përqindjen e kërkesave që do të dirigjohen te marrësi ose në një nëngrup të marrësit.
Do të azhurnojmë konfigūrimin e kaluar të VirtualService për sa-logic me komandën e mëposhtme:
$ kubectl apply -f resource-manifests/istio/canary/sa-logic-subsets-canary-vs.yaml
virtualservice.networking.istio.io/sa-logic configured… dhe menjëherë do të shohim se disa kërkesa rezultojnë me dështime:
$ 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: 500VirtualServices aktivizojnë ngarkesat kanarike: në këtë rast kemi kufizuar pasojat potenciale nga problemet deri në 20% të bazës së përdoruesve. Shkëlqyer! Tani në çdo rast, kur nuk jemi të sigurt për kodin tonë (në fjalë të tjera - gjithmonë...), mund të përdorim pasqyrimin dhe ngarkesat kanarike.
Koha e skadimit dhe përpjekjet e përsëritura
Por jo gjithmonë gabimet ndodhin në kod. Në listën e "" në vendin e parë lëviz mendimi i gabuar se "rrjeti është i besueshëm". Në të vërtetë, rrjeti jo është i besueshëm, dhe për këtë arsye na nevojiten koha e skadimit (timeouts) dhe përpjekjet e përsëritura (retries).
Për të demonstruar, do të vazhdojmë të përdorim të njëjtën problem version sa-logic (defekt), ndërsa paqëndrueshmërinë e rrjetit do ta simulojmë me dështime të rastësishme.
Le të themi se shërbimi ynë me gabime ka 1/3 mundësi për një përgjigje shumë të gjatë, 1/3 për të përfunduar me gabim të brendshëm të serverit dhe 1/3 për të dhënë me sukses faqen.
Për të zbutur pasojat nga këto probleme dhe për të bërë jetën e përdoruesve më të mirë, mund të:
- shtojmë një skadim, nëse shërbimi përgjigjet më gjatë se 8 sekonda,
- të bëjmë përpjekje të përsëritura, nëse ndodhin gabime gjatë kërkesës.
Për realizimin e këtij do të përdorim një përkufizim të tillë të burimit ():
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- Koha e skadimit për kërkesën është vendosur në 8 sekonda;
- Përpjekjet e përsëritura për kërkesat bëhen 3 herë;
- Çdo përpjekje konsiderohet e dështuar nëse koha e përgjigjes kalon 3 sekonda.
Kështu arritëm optimizimin, pasi përdoruesi nuk do të duhet të presë më shumë se 8 sekonda dhe ne do të bëjmë tre përpjekje të reja për të marrë një përgjigje në rast dështimesh, duke rritur shanset për një përgjigje të suksesshme.
Aplikoni konfigurimin e azhurnuar me komandën vijues:
$ kubectl apply -f resource-manifests/istio/retries/sa-logic-retries-timeouts-vs.yaml
virtualservice.networking.istio.io/sa-logic konfiguruarDhe kontrolloni në grafikat Grafana, që numri i përgjigjeve të suksesshme është rritur mbi:

Përmirësimet në statistikat e përgjigjeve të suksesshme pas shtimit të skadimeve dhe përpjekjeve të përsëritura
Para se të kaloni në seksionin tjetër (më saktësisht — tashmë në pjesën tjetër të artikullit, pasi në këtë nuk do të ketë më eksperimente praktike — shën. i përkth.), hiqni sa-logic-buggy dhe VirtualService, duke ekzekutuar komandat vijues:
$ kubectl delete deployment sa-logic-buggy
deployment.extensions “sa-logic-buggy” e fshirë
$ kubectl delete virtualservice sa-logic
virtualservice.networking.istio.io “sa-logic” e fshirëModelet Circuit Breaker dhe Bulkhead
Bëhet fjalë për dy modele të rëndësishme në arkitekturën mikroshërbyese që lejojnë rikuperimin e vetë-ndihmës (self-healing) të shërbimeve.
Circuit Breaker (“ndërprerësi automatik”) përdoret për të përfunduar kërkesat që i dërgohen një instance shërbimi që konsiderohet i sëmurë, dhe rikuperimin e tij gjatë kohës që kërkesat e klientëve janë përcjellë në instance të shëndetshme të këtij shërbimi (gjë që rrit përqindjen e përgjigjeve të suksesshme). (Shën. i përkth.: Një përshkrim më të detajuar të modelit mund të gjendet, për shembull, .)
Bulkhead (“ndarje”) izolon dështimet në shërbime nga ndikimi i gjithë sistemit. Për shembull, shërbimi B është i prishur, dhe një shërbim tjetër (klienti i shërbimit B) bën kërkesë në shërbimin B, duke rezultuar që e shpenzon fondin e tij të flukseve dhe nuk do të jetë në gjendje të shërbejë kërkesa të tjera (edhe nëse ato nuk janë të lidhura me shërbimin B). (Shën. i përkth.: Një përshkrim më të detajuar të modelit mund të gjendet, për shembull, .)
Unë do të kaloj detajet mbi implementimin e këtyre modeleve, sepse ato janë të lehta për t'u gjetur në , si dhe më shumë do të doja të tregoja autentifikimin dhe autorizimin, për të cilin do të flitet në pjesën tjetër të artikullit.
P.S. nga përkthyesi
Lexoni gjithashtu në blogun tonë:
- "Kthehu në mikroshërbime me Istio": , ;
- «»;
- «».
Burimi: habr.com
