
Shën. përk.: Ky këtij cikli i kushtohej njohjes me mundësitë e Istio dhe demonstruar veprimin e tyre. Tani do të flasim për aspekte më të nd复杂ta të konfigurimit dhe përdorimit të këtij service mesh, veçanërisht për routing të hollësishëm dhe menaxhimin e trafikut rrjetor.
Kujtojmë gjithashtu se artikulli përdor konfigurime (manifestet për Kubernetes dhe Istio) nga repozitori .
Menaxhimi i trafikut
Me Istio në klaster, shfaqen mundësi të reja që lejojnë:
- Routing dinamik i kërkesave: deploy të kanarinëve, testim A/B;
- Balancimin e ngarkesës: të thjeshtë dhe të konsistent, të bazuar në hashes;
- Rindërtimin pas dështimeve: kohë të skadimit, ri-probime, breakerët e qarkut;
- Introduktimin e defekteve: vonesa, ndërprerje të kërkesave etj.
Në vazhdim të artikullit, këto mundësi do të shfaqen përmes një aplikacioni të zgjedhur dhe në të njëjtën kohë do të prezantohen koncepte të reja. Koncepti i parë do të jetë DestinationRules (dmth. rregullat e marrësit të trafikut/kërkesave — shën. përkth.), me ndihmën e të cilave aktivizojmë testimin A/B.
Testimi A/B: DestinationRules në praktikë
Testimi A/B aplikohet në situatat kur ekzistojnë dy versione të aplikacionit (zakonisht ato ndryshojnë vizualisht) dhe ne nuk jemi të sigurt 100% se cila nga ato do të përmirësojë ndërveprimin me përdoruesin. Prandaj, ne drejtojmë të dyja versionet dhe mbledhim metrika.
Për të shpërndarë versionin e dytë të frontend-it, të nevojshëm për demonstrimin 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 deploy-it për "versionin e gjelbër" ndryshon në dy vende:
- Imazhi bazohet në një tag tjetër —
istio-green, - Pod-et kanë etiketë
version: green.
Duke qenë se të dy deploy-et kanë etiketë app: sa-frontend, kërkesat e drejtuara nga shërbimi virtual sa-external-services në shërbim sa-frontend, do të ridrejtohen në të gjitha instancat e tij dhe ngarkesa do të shpërndahet nëpërmjet , që do të çonte 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 kanë emra të ndryshëm 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, duke kërkuar një version të skedarëve statikë, mund të dërgohet nga balancuesi i ngarkesës në pod-et me versionin tjetër, ku, për arsye të kuptueshme, këta skedarë nuk ekzistojnë. Prandaj, për të siguruar që aplikacioni funksionon, na nevojitet të vendosim një kufizim: "versioni i njëjtë i aplikacionit që dha index.html, duhet të trajtojë gjithashtu kërkesat e mëtejshme».
Ne do të arrijmë këtë qëllim me balancimin e ngarkesës të qëndrueshëm të bazuar në hashes (Consistent Hash Loadbalancing). Në këtë rast kërkesat nga një klient dërgohen në një instancë të njëjtë të backend-it, për të cilin përdoret një pronë e paracaktuar — për shembull, një header HTTP. Implementohet me ndihmën e DestinationRules.
DestinationRules
Pas që VirtualService dërgoi 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 trafikun e destinuar për instancat e këtij shërbimi:

Menaxhimi i trafikut me burimet e Istio
Shënim: ndikimi i burimeve Istio në trafikun rrjetor është paraqitur këtu në një formë të thjeshtuar për t'u kuptuar. Në qoftë se të jemi të saktë, vendimi për se cilin instancë të dërgojmë kërkesën merret nga Envoy në Ingress Gateway, i cilësuar në CRD.
Me ndihmën e Destination Rules ne mund të konfigurojmë balancimin e ngarkesës në mënyrë që të përdoren hashes të qëndrueshme dhe të garantohet se përgjigjet e njëjtë instancë shërbimi do t’i shkojnë të njëjtit përdorues. Konfigurimi i mëposhtëm lejon arritjen e kësaj ():
apiVersion: networking.istio.io/v1alpha3
kind: DestinationRule
metadata:
name: sa-frontend
spec:
host: sa-frontend
trafficPolicy:
loadBalancer:
consistentHash:
httpHeaderName: version # 1 1 — hesh do të gjenerohet në bazë të përmbajtjes së header-it HTTP version.
Apliko konfigurimin me komandën e mëposhtme:
$ 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 sigurohu se po merrni skedarët e duhur kur caktoni header-in version:
$ curl --silent -H "version: yogo" http://$EXTERNAL_IP/ | tr '"' 'n' | grep mainShënim: Për të shtuar vlera të ndryshme në header dhe testuar rezultatet direkt në shfletues, mund të përdorim për Chrome (ose për Firefox — shën. përkth.).
Në përgjithësi, DestinationRules ka më shumë mundësi në fushën e balancimit të ngarkesës — detajet sqarohet në .
Para se të studiojmë më tej VirtualService, le t'i heqim "versionin e gjelbër" të aplikacionit dhe rregullin përkatës të trajtimit të 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” deleted
$ kubectl delete -f resource-manifests/istio/ab-testing/destinationrule-sa-frontend.yaml
destinationrule.networking.istio.io “sa-frontend” deletedPasqyrimi: Shërbimet Virtuale në praktikë
Hijezimi («ekranu») ose Pasqyrimi («pasqyrimi») aplikohet kur duam të testojmë një ndryshim në prodhim pa prekur përdoruesit përfundimtarë: për këtë, ne kopjojmë («pasqyrojmë») kërkesat në një instancë të dytë, ku janë bërë ndryshimet e nevojshme, dhe shohim pasojat. Thjesht duke folur, ky është kur kolegu juaj zgjidh problemin më kritik dhe bën një pull request në formën e një grumbulli të madh kaosi, saqë askush nuk mund të bëjë vërtet një rishikim.
Për të provuar këtë skenar në veprim, do krijojmë një instancë të dytë SA-Logic me defekte (defekti), duke ekzekutuar komandën e mëposhtme:
$ kubectl apply -f resource-manifests/kube/shadowing/sa-logic-service-buggy.yaml
deployment.extensions/sa-logic-buggy created Dhe tani do ekzekutojmë komandën për të siguruar që të gjitha instancat me app=sa-logic kanë gjithashtu etiketat me versionet përkatëse:
$ 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 Shërbimi sa-logic cili është i fokusuar në pod-ët me etiketën app=sa-logic, prandaj të gjitha kërkesat do të shpërndahen midis të gjitha instancave:

… por ne duam që kërkesat të drejtohen në instancat me versionin v1 dhe të pasqyrohen në instancat me versionin v2:

Do ta arrijmë këtë përmes VirtualService në kombinim me DestinationRule, ku rregullat do të përcaktojnë nëngrupet dhe rrugët VirtualService për një nëngrup të caktuar.
Definimi i nëngrupeve në Regullat 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 që ky rregull aplikohet vetëm për rastet kur rruga është në drejtim të shërbimitsa-logic; - Emrat (
emri) e nëngrupeve përdoren gjatë drejtuar në instancat e nëngrupit; - Etiketa (
etiketë) përcakton çifte çelës-vlerë, që duhet të përputhen instancat që të bëhen pjesë e nëngrupit.
Apliko konfigurimin me komandën e mëposhtme:
$ kubectl apply -f resource-manifests/istio/shadowing/sa-logic-subsets-destinationrule.yaml
destinationrule.networking.istio.io/sa-logic createdTani që nëngrupet janë të përcaktuara, mund të shkojmë përpara dhe të konfigurojmë VirtualService, për t'i aplikuar rregullat në kërkesat për sa-logic, në mënyrë që ato:
- Të drejtoheshin në nëngrupin
v1, - Të pasqyroheshin në nëngrupin
v2.
Manifesti i mëposhtëm lejon arritjen e synuar ():
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: v2Shpjegime këtu nuk janë të nevojshme, kështu që thjesht do ta shohim në veprim:
$ kubectl apply -f resource-manifests/istio/shadowing/sa-logic-subsets-shadowing-vs.yaml
virtualservice.networking.istio.io/sa-logic createdLe të shtojmë ngarkesë me thirrjen e kësaj komande:
$ while true; do curl -v http://$EXTERNAL_IP/sentiment
-H "Content-type: application/json"
-d '{"sentence": "I love yogobella"}';
sleep .8; done Le të shohim rezultatet në Grafana, ku mund të shohim se versioni me defekte (defekti) shkakton dështim për ~60 % të kërkesave, por asnjë nga këto dështime nuk prekin përdoruesit përfundimtarë, pasi ata marrin përgjigje nga shërbimi në funksion.

Suksesi i 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 Envoy-it sidecar, i cili — përmes VirtualService — është konfiguruar për të drejtuar kërkesën në nëngrupin v1 dhe për të pasqyruar kërkesën në nëngrupin v2 të shërbimit sa-logic.
E di: ju tashmë keni menduar se Shërbimet Virtuale janë të thjeshta. Në seksionin tjetër do ta zgjasim këtë mendim duke thënë se ato janë në të vërtetë të shkëlqyera.
Shkëmbimet kanarinë
Deployimi Canary — procesi i lançimit 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ë version dhe vetëm pas kësaj, pasi të jemi të sigurt për cilësinë e tij (versionit), do ta shpërndajmë për njëoaudiencë më të madhe.
Për të demonstruar lançimet canary, do të vazhdojmë me nëngrupin defekti u sa-logic.
Nuk do të merremi me gjëra të vogla dhe menjëherë do të dërgojmë 20 % të përdoruesve në versionin me defekte (ai do të përfaqësojë lançimin tonë canary), ndërsa 80 % e mbetur do të shkojnë në shërbimin normal. Për këtë, do të aplikojmë VirtualService-in e 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ë pesha (weight), që përcakton përqindjen e kërkesave që do të drejtohen te marrësi ose një nëndegë të marrësit.
Do të azhurnojmë konfigurimin 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 një pjesë e kërkesave çon në 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ë lançimet kanar: në këtë rast, ne e kemi ngushtuar ndikimin e problemeve në 20% të bazës së përdoruesve. Shkëlqyeshëm! Tani, çdo herë kur nuk jemi të sigurt për kodin tonë (do të thotë gjithmonë…), mund të përdorim pasqyrimin dhe lançimet kanar.
Kohët e pritjes dhe përpjekjet e riparimit
Por nuk gjithmonë gabimet janë në kod. Në listën e "" mitet e para të mencura është se "rrjeti është i besueshëm". Në të vërtetë, rrjeti nuk është i besueshëm dhe për këtë shkak na duhen kohët e pritjes (timeouts) dhe përpjekjet e riparimit (retries).
Për të demonstruar do të vazhdojmë të përdorim të njëjtën problem version sa-logic (defekti), dhe do të simullojmë mosbesueshmërinë e rrjetit me dështime të rastësishme.
Le të themi që shërbimi ynë me gabime ka një mundësi 1/3 për një përgjigje shumë të gjatë, 1/3 për të marrë një gabim Internal Server Error dhe 1/3 për të dhënë një faqe të suksesshme.
Për të zbutur pasojat e kësaj problemi dhe për të përmirësuar jetën e përdoruesve, mund të:
- shtojmë një kohë pritje, nëse shërbimi përgjigjet më shumë se 8 sekonda,
- të bëjmë një përpjekje të riparimit, nëse ndodh një dështim në kërkesë.
Për realizimin e kësaj do të përdorim një definicion 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 pritjes për kërkesën është caktuar në 8 sekonda;
- Përpjekjet e riparimit bëhen për 3 herë;
- Dhe çdo përpjekje konsiderohet e dështuar, nëse koha e përgjigjes kalon 3 sekonda.
Kështu kemi arritur 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 shansin për një përgjigje të suksesshme.
Aplikoni konfigurimin e azhurnuar me komandën e mëposhtme:
$ kubectl apply -f resource-manifests/istio/retries/sa-logic-retries-timeouts-vs.yaml
virtualservice.networking.istio.io/sa-logic configuredDhe kontrolloni në grafikat Grafana, që numri i përgjigjeve të suksesshme të jetë rritur:

Përmirësimet në statistikën e përgjigjeve të suksesshme pas shtimit të kohëve të pritjes dhe përpjekjeve të riparimit
Para se të kalojmë në seksionin e ardhshëm (në të vërtetë — tashmë në pjesën tjetër të artikullit, pasi në këtë pjesë nuk do të ketë më eksperimente praktike — shënim i përkthyesit), fshini sa-logic-buggy dhe VirtualService, duke ekzekutuar komandat e mëposhtme:
$ kubectl delete deployment sa-logic-buggy
deployment.extensions “sa-logic-buggy” deleted
$ kubectl delete virtualservice sa-logic
virtualservice.networking.istio.io “sa-logic” deletedModelet Circuit Breaker dhe Bulkhead
Këtu flitet për dy modele të rëndësishme në arkitekturën mikroshërbimeve, që lejojnë rindërtimin e shërbimeve (self-healing). Circuit Breaker
('ndërprerësi automat') përdoret për të ndërprerë kërkesat që po i dërgohen një instance shërbimi, e cila konsiderohet e paqartë, dhe për ta rikuperuar atë, ndërkohë që kërkesat e klientëve janë riviernuar në instance të shëndetshme të atij shërbimi (çka rrit përqindjen e përgjigjeve të suksesshme). (Shënim i përkthyesit: Një përshkrim më të detajuar të modelit mund të gjendet, për shembull, Bulkhead .)
('ndarje') izolon dështimet në shërbime nga dështimi i sistemit të tërë. Për shembull, nëse Shërbimi B është në gjendje të dështuar, një shërbim tjetër (klienti i Shërbimit B) bën një kërkesë ndaj Shërbimit B, duke e shpenzuar kështu poolin e saj të flukseve dhe nuk do të jetë në gjendje të shërbejë kërkesa të tjera (edhe nëse ato nuk lidhen me Shërbimin B). Do ta anashkaloj detajet e implementimit të këtyre modeleve, sepse ato janë lehtësisht të gjendura në Bulkhead .)
, dhe gjithashtu tashmë jam shumë i nxituar të tregoj për autentikimin dhe autorizimin, për të cilin do të flasim në pjesën tjetër të artikullit. , а также очень уже хочется показать аутентификацию и авторизацию, о чём и пойдёт речь в следующей части статьи.
P.S. nga përkthyesi
Lexoni gjithashtu në blogun tonë:
- «Kthehu te mikroshërbimet me Istio»: , ;
- «»;
- «».
Burimi: habr.com
