Kthehu tek mikroshërbimet me Istio. Pjesa 2

Kthehu tek mikroshërbimet me Istio. Pjesa 2

Shën. përkth.: Pjesa e parë 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 istio-mastery.

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 created

Manifesti i deployment për "versionin e gjelbër" ndryshon në dy vende:

  1. Imazhi është i bazuar në një etiketë tjetër — istio-green,
  2. 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 algoritmit round-robin, që do të çojë në situatën e mëposhtme:

Kthehu tek mikroshërbimet me Istio. Pjesa 2
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:

Kthehu tek mikroshërbimet me Istio. Pjesa 2
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 (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-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 main

Shënim: Për të shtuar vlera të ndryshme në header dhe për të testuar rezultatet direkt në shfletues, mund të përdorni këtë shtesë për Chrome (ose këtë 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ë dokumentacionin zyrtar.

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 fshij

Pë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:

Kthehu tek mikroshërbimet me Istio. Pjesa 2

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

Kthehu tek mikroshërbimet me Istio. Pjesa 2

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 (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. Hosti (host) përcakton se ky rregull zbatohet vetëm në rastet kur ruta shkon drejt shërbimit sa-logic;
  2. Emrat (emri) e nëngrupeve përdoren gjatë drejtimeve të ekzemplarëve të nëngrupit;
  3. 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 krijua

Tani 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:

  1. Të route-ohen në nëngrup v1,
  2. Të mirror-ohen në nëngrup v2.

Manifesti i mëposhtëm lejon arritjen e atij që është menduar (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

Shpjegimet 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 krijua

Le 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.

Kthehu tek mikroshërbimet me Istio. Pjesa 2
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 (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 — ë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: 500

VirtualServices 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 "8 mitet në kompjuterët e shpërndarë" 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ë:

  1. shtojmë një skadim, nëse shërbimi përgjigjet më gjatë se 8 sekonda,
  2. 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 (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. Koha e skadimit për kërkesën është vendosur në 8 sekonda;
  2. Përpjekjet e përsëritura për kërkesat bëhen 3 herë;
  3. Ç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 konfiguruar

Dhe kontrolloni në grafikat Grafana, që numri i përgjigjeve të suksesshme është rritur mbi:

Kthehu tek mikroshërbimet me Istio. Pjesa 2
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, këtu.)

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, këtu.)

Unë do të kaloj detajet mbi implementimin e këtyre modeleve, sepse ato janë të lehta për t'u gjetur në dokumentacionin zyrtar, 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ë:

Burimi: habr.com

Blini hosting të besueshëm për faqe interneti me mbrojtje nga DDoS, serverë VPS VDS 🔥 Blini hosting të besueshëm për faqe interneti me mbrojtje nga DDoS, serverë VPS VDS | ProHoster