Notă. transl.: Prima parte Această serie a fost dedicată introducerii capabilităților Istio și demonstrării lor în acțiune. Acum vom vorbi despre aspecte mai complexe ale configurației și utilizării acestei rețele de servicii și, în special, despre rutarea fin reglată și gestionarea traficului de rețea.
De asemenea, vă reamintim că articolul folosește configurații (manifeste pentru Kubernetes și Istio) din depozit istio-stăpânire.
Administrarea traficului
Cu Istio, noi capabilități apar în cluster pentru a oferi:
Dirijarea dinamică a cererilor: lansări canare, testare A/B;
Echilibrarea sarcinii: simplu și consistent, bazat pe hashes;
Recuperare după cădere: timeout-uri, reîncercări, întrerupătoare;
Inserarea defectelor: întârzieri, solicitări renunțate etc.
Pe măsură ce articolul continuă, aceste capabilități vor fi ilustrate folosind aplicația selectată ca exemplu și vor fi introduse noi concepte pe parcurs. Primul astfel de concept va fi DestinationRules(adică reguli despre destinatarul traficului/solicitărilor - aprox. traducere), cu ajutorul căruia activăm A/B testing.
Testare A/B: Reguli de destinație în practică
Testarea A/B este folosită în cazurile în care există două versiuni ale unei aplicații (de obicei sunt diferite vizual) și nu suntem 100% siguri care dintre ele va îmbunătăți experiența utilizatorului. Prin urmare, rulăm ambele versiuni simultan și colectăm valori.
Pentru a implementa cea de-a doua versiune a frontend-ului, necesară pentru demonstrarea testării A/B, rulați următoarea comandă:
$ kubectl apply -f resource-manifests/kube/ab-testing/sa-frontend-green-deployment.yaml
deployment.extensions/sa-frontend-green created
Manifestul de implementare pentru versiunea verde diferă în două locuri:
Imaginea se bazează pe o altă etichetă - istio-green,
Podurile au o etichetă version: green.
Deoarece ambele implementări au o etichetă app: sa-frontend,cereri direcționate prin serviciu virtual sa-external-services pentru service sa-frontend, va fi redirecționat către toate instanțele sale și încărcarea va fi distribuită prin algoritm round-robin, ceea ce va duce la următoarea situație:
Fișierele solicitate nu au fost găsite
Aceste fișiere nu au fost găsite deoarece sunt denumite diferit în diferite versiuni ale aplicației. Să ne asigurăm de asta:
Acest lucru înseamnă că index.html, care solicită o versiune de fișiere statice, poate fi trimisă de echilibrator de încărcare către poduri care au o versiune diferită, unde, din motive evidente, astfel de fișiere nu există. Prin urmare, pentru ca aplicația să funcționeze, trebuie să stabilim o restricție: „aceeași versiune a aplicației care a servit index.html ar trebui să servească solicitările ulterioare".
Vom ajunge acolo cu o echilibrare a încărcăturii bazată pe hash (Echilibrare hash constantă). În acest caz cererile de la același client sunt trimise către aceeași instanță backend, pentru care este utilizată o proprietate predefinită - de exemplu, un antet HTTP. Implementat folosind DestinationRules.
Reguli de destinație
După Serviciu virtual a trimis o solicitare către serviciul dorit, folosind DestinationRules putem defini politici care vor fi aplicate traficului destinat instanțelor acestui serviciu:
Gestionarea traficului cu resurse Istio
Nota: Impactul resurselor Istio asupra traficului de rețea este prezentat aici într-un mod ușor de înțeles. Mai exact, decizia asupra cărei instanțe să trimită cererea este luată de Envoy în Ingress Gateway configurat în CRD.
Cu Destination Rules, putem configura echilibrarea încărcăturii pentru a utiliza hashuri consistente și a ne asigura că aceeași instanță de serviciu răspunde aceluiași utilizator. Următoarea configurație vă permite să realizați acest lucru (destinationrule-sa-frontend.yaml):
Nota: Pentru a adăuga diferite valori în antet și a testa rezultatele direct în browser, puteți utiliza această extensie la Chrome (Sau, cu asta pentru Firefox - aprox. traducere).
În general, DestinationRules are mai multe capacități în domeniul echilibrării sarcinii - verificați detalii în documentație oficială.
Înainte de a studia în continuare VirtualService, să ștergem „versiunea verde” a aplicației și regula corespunzătoare de direcție a traficului, rulând următoarele comenzi:
shadowing („protecție”) sau Oglindire ("oglindire") utilizat în cazurile în care dorim să testăm o schimbare în producție fără a afecta utilizatorii finali: pentru a face acest lucru, duplicăm cererile („oglindă”) către o a doua instanță în care s-au făcut modificările dorite și ne uităm la consecințe. Mai simplu spus, acesta este momentul în care colegul tău alege cea mai critică problemă și face o cerere de tragere sub forma unui bulgăre atât de mare de murdărie încât nimeni nu o poate revizui cu adevărat.
Pentru a testa acest scenariu în acțiune, să creăm oa doua instanță a SA-Logic cu erori (buggy) prin rularea următoarei comenzi:
$ kubectl apply -f resource-manifests/kube/shadowing/sa-logic-service-buggy.yaml
deployment.extensions/sa-logic-buggy created
Și acum să rulăm comanda pentru a ne asigura că toate instanțele cu app=sa-logic Au și etichete cu versiunile corespunzătoare:
Serviciu sa-logic vizează păstăile cu o etichetă app=sa-logic, astfel încât toate solicitările vor fi distribuite între toate instanțele:
... dar dorim ca cererile să fie trimise la instanțe v1 și reflectate în instanțe v2:
Vom realiza acest lucru prin VirtualService în combinație cu DestinationRule, unde regulile vor determina subseturile și rutele VirtualService către un anumit subset.
Gazdă (host) definește că această regulă se aplică numai cazurilor în care ruta merge spre serviciu sa-logic;
Titluri (name) subseturile sunt folosite la rutarea către instanțe de subseturi;
Eticheta (label) definește perechile cheie-valoare cu care instanțele trebuie să se potrivească pentru a deveni parte a subsetului.
Aplicați configurația cu următoarea comandă:
$ kubectl apply -f resource-manifests/istio/shadowing/sa-logic-subsets-destinationrule.yaml
destinationrule.networking.istio.io/sa-logic created
Acum că subseturile sunt definite, putem trece mai departe și configura VirtualService să aplice reguli cererilor către sa-logic, astfel încât acestea:
Nu este nevoie de explicații aici, așa că haideți să o vedem în acțiune:
$ kubectl apply -f resource-manifests/istio/shadowing/sa-logic-subsets-shadowing-vs.yaml
virtualservice.networking.istio.io/sa-logic created
Să adăugăm încărcarea apelând următoarea comandă:
$ while true; do curl -v http://$EXTERNAL_IP/sentiment
-H "Content-type: application/json"
-d '{"sentence": "I love yogobella"}';
sleep .8; done
Să ne uităm la rezultatele din Grafana, unde puteți vedea că versiunea cu bug-uri (buggy) duce la eșec pentru ~60% din solicitări, dar niciuna dintre aceste eșecuri nu afectează utilizatorii finali, deoarece li se răspunde la un serviciu care rulează.
Răspunsuri de succes ale diferitelor versiuni ale serviciului sa-logic
Aici am văzut mai întâi cum se aplică VirtualService trimișilor serviciilor noastre: când sa-web-app face o cerere către sa-logic, trece prin sidecar Envoy, care - prin VirtualService - este configurat să direcționeze cererea către subsetul v1 și să oglindească cererea către subsetul v2 al serviciului sa-logic.
Știu, s-ar putea să credeți deja că Serviciile Virtuale sunt simple. În secțiunea următoare, vom extinde acest lucru spunând că sunt, de asemenea, cu adevărat grozave.
Lansări Canary
Canary Deployment este procesul de lansare a unei noi versiuni a unei aplicații pentru un număr mic de utilizatori. Este folosit pentru a vă asigura că nu există probleme în lansare și numai după aceea, având deja încredere în calitatea sa (lansării), îl distribuiți altor utilizatori.оaudienta mai mare.
Pentru a demonstra lansările Canary, vom continua să lucrăm cu un subset buggy у sa-logic.
Să nu pierdem timpul cu fleacuri și să trimitem imediat 20% dintre utilizatori la versiunea cu erori (aceasta va reprezenta lansarea noastră canar), iar restul de 80% la serviciul normal. Pentru a face acest lucru, utilizați următorul VirtualService (sa-logic-subseturi-canary-vs.yaml):
... și vom vedea imediat că unele solicitări duc la eșecuri:
$ 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 permit lansările canare: în acest caz, am redus impactul potențial al problemelor la 20% din baza de utilizatori. Minunat! Acum, în fiecare caz când nu suntem siguri de codul nostru (cu alte cuvinte - întotdeauna...), putem folosi oglindirea și lansările canary.
Timeouts și reîncercări
Dar erorile nu ajung întotdeauna în cod. În lista de la "8 Concepții greșite despre calculul distribuit„În primul rând este credința eronată că „rețeaua este fiabilă”. In realitate reteaua nu fiabile și din acest motiv avem nevoie de timeout-uri (time-out) și reîncercați (reîncercați).
Pentru demonstrație vom continua să folosim aceeași versiune cu probleme sa-logic (buggy), și vom simula nefiabilitatea rețelei cu defecțiuni aleatorii.
Permiteți serviciului nostru cu erori să aibă o șansă de 1/3 să dureze prea mult să răspundă, o șansă de 1/3 să se încheie cu o eroare internă a serverului și o șansă de 1/3 de a returna pagina cu succes.
Pentru a atenua impactul unor astfel de probleme și pentru a face viața mai bună pentru utilizatori, putem:
adăugați un timeout dacă serviciul durează mai mult de 8 secunde pentru a răspunde,
Și fiecare încercare este considerată nereușită dacă timpul de răspuns depășește 3 secunde.
Aceasta este o optimizare deoarece utilizatorul nu va trebui să aștepte mai mult de 8 secunde și vom face trei noi încercări pentru a obține un răspuns în caz de eșecuri, crescând șansa unui răspuns de succes.
Aplicați configurația actualizată cu următoarea comandă:
Și verificați în graficele Grafana că numărul de răspunsuri reușite a crescut mai sus:
Îmbunătățiri ale statisticilor de răspuns de succes după adăugarea de timeout-uri și reîncercări
Înainte de a trece la următoarea secțiune (sau mai degrabă, la următoarea parte a articolului, pentru că în aceasta nu vor mai exista experimente practice - aprox. traducere), șterge sa-logic-buggy și VirtualService rulând următoarele comenzi:
Vorbim despre două modele importante în arhitectura de microservicii care vă permit să realizați auto-recuperarea (auto vindecare) Servicii.
Întrerupător de circuit("întrerupător de circuit") folosit pentru a termina cererile care vin la o instanță a unui serviciu care este considerat nesănătos și a le restabili în timp ce solicitările clientului sunt redirecționate către instanțe sănătoase ale serviciului respectiv (ceea ce crește procentul de răspunsuri reușite). (Notă: o descriere mai detaliată a modelului poate fi găsită, de exemplu, aici.)
Bulkhead(„partiție”) izolează defecțiunile serviciului de a afecta întregul sistem. De exemplu, Serviciul B este întrerupt și un alt serviciu (clientul Serviciului B) face o solicitare către Serviciul B, determinându-l să își epuizeze pool-ul de fire și să nu poată deservi alte solicitări (chiar dacă acestea nu sunt de la Serviciul B). (Notă: o descriere mai detaliată a modelului poate fi găsită, de exemplu, aici.)
Voi omite detaliile de implementare ale acestor modele deoarece sunt ușor de găsit documentație oficială, și chiar vreau să arăt autentificarea și autorizarea, despre care vor fi discutate în următoarea parte a articolului.