Scenarii de utilizare a service mesh

Scenarii de utilizare a service mesh

Nota traducătorului.: autorul acestui articol (Luc Perkins) — avocat al dezvoltării în organizația CNCF, care este casa unor proiecte Open Source, cum ar fi Linkerd, SMI (Service Mesh Interface) și Kuma (între noi fie vorba, v-ați întrebat vreodată de ce Istio nu se află pe această listă?..). Încercând din nou să aducă în comunitatea DevOps o mai bună înțelegere a hype-ului la modă numit „service mesh”, el prezintă cele 16 caracteristici distinctive pe care le oferă astfel de soluții.

Astăzi service mesh ― una dintre cele mai fierbinți teme din domeniul ingineriei software (și pe bună dreptate!). Consider că această tehnologie este incredibil de promițătoare și visul meu este să asist la răspândirea ei pe scară largă (bineînțeles, atunci când are sens). Totuși, este încă învăluită într-un halo de mister pentru majoritatea oamenilor. De asemenea, chiar și cei care sunt bine familiarizați cu aceasta, adesea au dificultăți în a formula avantajele sale și ce reprezintă de fapt (inclusiv și pe umilul meu servitor). În articolul acesta, voi încerca să remediez situația, enumerând diversele scenarii de utilizare „sau așa-numitele rețele de servicii”*.

* Notă de traducere: aici și mai departe în articol, va fi folosită această traducere („rețea de servicii”) pentru termenul încă nou service mesh.

Dar înainte, vreau să fac câteva observații:

  • Nu am lucrat niciodată cu rețele de servicii și nu le-am folosit în afara proiectelor concepute pentru propria educare. Pe de altă parte, eu am scris o mulțime de documentație pentru rețeaua de servicii interioară a companiei Twitter în 2015 (atunci nu era numită nici măcar „rețea de servicii”) și am participat la dezvoltarea site-ului și a documentației pentru Linkerd, așa că asta înseamnă ceva.
  • Lista mea este orientativă și incompletă. Este foarte posibil să existe scenarii de utilizare pe care nu le cunosc, iar noul tehnologie se va dezvolta și popularitatea ei va crește în timp.
  • În același timp, nu fiecare implementare existentă de service mesh suportă toate cazurile de utilizare enumerate. De aceea, expresiile mele cum ar fi „service mesh poate...” ar trebui citite ca „implementările populare de service mesh pot...”.
  • Ordinea exemplelor nu are nicio relevanță.

Listă scurtă:

  • descoperirea serviciilor;
  • criptare;
  • autentificarea și autorizarea;
  • împărțirea încărcăturii;
  • circuit breaking;
  • scalarea automată;
  • implementări canar;
  • implementări blue-green;
  • verificarea stării de sănătate;
  • load shedding;
  • mirror traffic;
  • izolație;
  • limitarea frecvenței cererilor, retrageri și timeout-uri;
  • telemetrie;
  • audit;
  • vizualizare.

1. Detectarea serviciilor

TL;DR: Conectați-vă la alte servicii din rețea folosind nume simple.

Serviciile trebuie să aibă capacitatea de a se 'găsi' reciproc utilizând nume adecvate — de exemplu, service.api.production, pets/staging sau cassandra. Mediile cloud se disting prin elasticitatea lor, iar sub un singur nume pot fi ascunse multiple instanțe ale serviciului. Este evident că, în această situație, nu este fizic posibil să se dureze toate adresele IP.

În plus, atunci când un serviciu găsește altul, trebuie să aibă capacitatea de a trimite cereri acelui serviciu, fără teama că acestea vor ajunge la o instanță inactivă. Cu alte cuvinte, o rețea de servicii trebuie să monitorizeze funcționarea tuturor instanțelor serviciilor și să mențină lista gazdelor actualizată.

Fiecare rețea de servicii implementează mecanismul de detectare a serviciilor în modul său propriu. În prezent, cea mai frecvent utilizată metodă este delegarea proceselor externe precum DNS Kubernetes. În trecut, în Twitter, am folosit pentru aceste scopuri sistemul de numire Finagle. În plus, tehnologia rețelei de servicii face posibilă apariția mecanismelor personalizate de numire (deși nu am întâlnit încă o implementare SM cu un astfel de funcțional).

2. Criptare

TL;DR: Scăpați de traficul necriptat între servicii și lăsați acest proces să fie automatizat și scalabil.

Este reconfortant să știți că atacatorii nu pot penetra rețeaua dvs. internă. Firewall-urile fac o treabă excelentă în acest sens. Dar ce se va întâmpla dacă un hacker reușește să pătrundă în interior? Va putea să facă tot ce vrea cu traficul inter-serviciu? Să sperăm că nu va fi cazul. Pentru a preveni un astfel de scenariu, trebuie implementat un sistem de zero trust, în care tot traficul între servicii este criptat. Majoritatea rețelelor moderne de servicii realizează acest lucru prin mutual TLS (mutual TLS, mTLS). În unele cazuri, mTLS funcționează în întregi cloud-uri și clustere (cred că și comunicațiile interplanetare vor fi organizate într-un mod similar).

Desigur, mTLS nu este opțional pentru rețelele de servicii. Fiecare serviciu poate avea grijă de propriul său TLS, dar asta înseamnă că va trebui să găsească o modalitate de a genera certificate, de a le distribui între gazdele serviciului, de a include în aplicație codul care va încărca aceste certificate din fișiere. Și, nu uitați să vă ocupați de actualizarea acestor certificate la intervale regulate. Rețelele de servicii automatizează mTLS folosind sisteme precum SPIFFE, care, la rândul lor, automatizează procesul de emitere și rotație a certificatelor.

3. Autentificare și autorizare

TL;DR: Stabiliți cine este inițiatorul cererii și definiți ce i se permite să facă înainte ca cererea să ajungă la serviciu.

Serviciile doresc adesea să știe este el. cine face cererea (autentificare) și, folosind aceste informații, decid utilizatorul (sau atacatorul) încearcă să facă, ci și ce are voie să facă acest subiect (autorizare). În acest caz, pronumele „cine” poate face referire la:

  1. Alte servicii. Acesta este numit „autentificarea peer-ului». De exemplu, serviciul web vrea să acceseze serviciul db. Rețelele de servicii rezolvă de obicei astfel de probleme folosind mTLS: certificatele, în acest caz, acționează ca un identificator necesar.
  2. Anumiți utilizatori- oameni. Acesta este numit „autentificarea cererii». De exemplu, utilizatorul haxor69 vrea să achiziționeze o lampă nouă. Rețelele de servicii oferă diverse mecanisme, cum ar fi JSON Web Tokens.

    Multi dintre noi am făcut asta în codul aplicației. Vine o cerere, verificăm tabelul aveau adrese de email pe domeniile, găsim utilizatorul și comparăm parola, apoi verificăm coloana permissions și așa mai departe. În cazul rețelei de servicii, aceasta se întâmplă chiar înainte ca cererea să ajungă la serviciu.

După ce am stabilit cine a venit cu cererea, trebuie să determinăm ce i se permite să facă acestui subiect. Unele rețele de servicii permit definirea de politici de bază (despre cine și ce poate face) sub formă de fișiere YAML sau în linia de comandă, în timp ce altele oferă integrare cu cadre precum Open Policy Agent. Obiectivul final este acela de a face ca serviciile dumneavoastră să accepte orice cererile, presupunând cu încredere că provin dintr-o sursă de încredere și acțiunea este permisă.

4. Împărțirea încărcăturii

TL;DR: Distribuiți sarcina între instanțele serviciului conform unui anumit model.

Un «serviciu» în cadrul unei rețele de servicii constă adesea din mai multe instanțe identice. De exemplu, astăzi serviciul cache constă din 5 copii, iar mâine numărul lor poate crește până la 11. Cererile care se îndreaptă către cache, trebuie distribuite conform unui obiectiv specific. De exemplu, minimizarea întârzierii sau maximizarea probabilității de a ajunge pe o instanță funcțională. Cel mai frecvent se folosește algoritmul de rotire (Round-robin), dar există și multe altele — de exemplu, metoda cererilor ponderate (weighted) cererilor (se pot selecta obiective preferate), hash-ul în cerc (ring) hashing (utilizarea hash-ului coerent pentru gazdele upstream) sau metoda cu cel mai mic număr de cereri (se prioritizează instanța cu cel mai mic număr de cereri). Balancerii clasici au și alte funcții, cum ar fi caching-ul HTTP și protecția împotriva DDoS, dar acestea nu sunt foarte relevante pentru traficul de tip est-vest (adică pentru traficul care se desfășoară în interiorul centrului de date - nota translatorului) (zona tipică de aplicare a rețelei de servicii). Desigur, nu este obligatoriu să folosești o rețea de servicii pentru echilibrarea încărcării, totuși aceasta permite stabilirea și controlul politicilor de echilibrare pentru fiecare serviciu dintr-un strat centralizat de gestionare, eliminând astfel necesitatea de a rula și configura balancere separate în stiva de rețea.

5. Încetarea circuitului (circuit breaking)

TL;DR: Oprește traficul către serviciul problematic și controlează daunele în cele mai nefaste scenarii.

Dacă dintr-un anumit motiv serviciul nu face față traficului, rețeaua de servicii oferă mai multe opțiuni pentru a rezolva această problemă (despre altele se va vorbi în secțiunile corespunzătoare). Încetarea circuitului este cea mai drastică opțiune de deconectare a serviciului de la trafic. Totuși, ea nu are sens de una singură - este necesar un plan de rezervă. Poate fi prevăzută o presiune inversă

backpressure (pentru serviciile care fac cereri (numai să nu uiți să configurezi rețeaua de servicii pentru asta!), sau, de exemplu, colorarea paginii de stare în roșu și redirecționarea utilizatorilor către o pagină alternativă cu „cita căderea” („Twitter is down”).) Rețelele de servicii permit nu doar definirea

când urmează deconectarea și va urma deconectarea și utilizatorul (sau atacatorul) încearcă să facă, ci și Acest lucru va fi urmat. În acest caz, „când” poate include orice combinație de parametri specificați: numărul total de cereri într-o anumită perioadă, numărul de conexiuni paralele, cereri în așteptare, încercări active și altele.

Probabil că nu veți dori să abuzati de circuit breaking, dar este plăcut să știți că există un plan de rezervă pentru situații extreme.

6. Scalare automată

TL;DR: Creșteți sau diminuați numărul de instanțe ale serviciului în funcție de criteriile specificate.

Service mesh-urile nu sunt planificatori, prin urmare, ele nu efectuează scalarea de sine stătătoare. Cu toate acestea, ele pot furniza informații pe baza cărora planificatorii vor lua decizii. Deoarece service mesh-urile au acces la tot traficul dintre servicii, ele dispun de informații ample despre ceea ce se întâmplă: ce servicii se confruntă cu probleme, care sunt extrem de puțin utilizate (resursele dedicate sunt irosite) etc.

De exemplu, Kubernetes scalează serviciile în funcție de utilizarea CPU-ului și a memoriei pod-urilor (vezi raportul nostru „Autoscalare și gestionarea resurselor în Kubernetes” — n. trad.), dar dacă decideți să faceți scalarea pe baza oricărui alt indicator (în cazul nostru - legat de trafic), va fi nevoie de o metrică specială. Ghidul de tipul acesta arată cum să faceți acest lucru cu ajutorul Envoy, Istio și Prometheus, dar procesul în sine este destul de complex. Ne-am dori ca service mesh-ul să-l simplifice, permițându-ne să stabilim pur și simplu condiții precum „crește numărul de instanțe ale serviciului auth, dacă numărul cererilor în așteptare depășește pragul în decurs de un minut”.

7. Implementări canar

TL;DR: Testați noi funcții sau versiuni ale serviciului pe un subset de utilizatori.

Să spunem că dezvoltați un anumit produs SaaS și intenționați să lansați o nouă versiune cool. L-ați testat în staging și a funcționat excelent. Cu toate acestea, există anumite îngrijorări cu privire la comportamentul său în condiții reale. Cu alte cuvinte, trebuie să verificați noua versiune pe sarcini reale, fără a risca încrederea utilizatorilor. Implementările de tip canary sunt ideale pentru asta. Ele permit prezentarea unei noi funcționalități unui anumit subset de utilizatori. Acest subset poate fi format din cei mai loiali utilizatori sau din cei care folosesc versiunea gratuită a produsului sau utilizatori care și-au exprimat dorința de a fi „cobai”.

Mesh-urile de servicii implementează acest lucru, permițându-vă să specificați criteriile care determină cine și ce versiune a aplicației va vedea, și rutând traficul în consecință. Cu toate acestea, pentru serviciile proprii, nimic nu se schimbă. Versiunea 1.0 a serviciului consideră că toate solicitările provin de la utilizatorii care ar trebui să o vadă, iar versiunea 1.1 crede același lucru în ceea ce privește utilizatorii săi. Între timp, puteți schimba procentul de trafic între versiunea veche și nouă, redirecționând un număr tot mai mare de utilizatori către nouă, dacă aceasta funcționează stabil și „cobaii” dvs. își dau acordul.

8. Implementări blue-green

TL;DR: Lansați o nouă funcționalitate cool, dar fiți gata să reveniți imediat.

Sensul implementărilor blue-green este de a lansa un nou serviciu „albastru”, rulându-l paralel cu cel vechi, „verde”. Dacă totul decurge bine și noul serviciu se comportă bine, atunci vechiul poate fi dezactivat treptat. (Din păcate, cândva acest nou serviciu „albastru” va repeta soarta „verde” și va dispărea…) Implementările blue-green se deosebesc de cele canary prin faptul că noua funcționalitate acoperă toți utilizatorii (nu doar o parte); sensul este să aveți pregătită un „port de salvare” în cazul în care ceva nu merge bine.

Mesh-urile de servicii oferă o modalitate foarte convenabilă de a testa un serviciu „albastru” și de a comuta instantaneu pe un „verde” operațional în caz de probleme. Nemaivorbind de faptul că, în același timp, oferă o mulțime de informații (vezi secțiunea „Telemetrie” de mai jos) despre funcționarea „albastrului”, care ajută la înțelegerea dacă acesta este pregătit pentru utilizarea completă.

Nota traducătorului.: Mai multe despre diferitele strategii de desfășurare în Kubernetes (inclusiv cele menționate canary, blue/green și altele) pot fi citite în această articole.

9. Verificarea sănătății

TL;DR: Monitorizați ce instanțe ale serviciilor sunt funcționale și reacționați la cele care nu mai sunt.

Verificarea sănătății (health check) ajută la luarea unei decizii cu privire la pregătirea instanțelor serviciului pentru a primi și procesa trafic. De exemplu, în cazul serviciilor HTTP, verificarea sănătății poate arăta ca un apel GET la endpoint-ul /health. Răspunsul 200 OK va indica faptul că instanța este sănătoasă, orice altceva înseamnă că nu este pregătită să primească trafic. Mesh-urile de servicii permit specificarea atât a modului în care se va verifica funcționalitatea, cât și a frecvenței cu care va avea loc această verificare. Această informație poate fi folosită ulterior și în alte scopuri, de exemplu, pentru balansarea încărcăturii și circuit breaking.

Astfel, verificarea sănătății nu este un scenariu de utilizare de sine stătător, ci este utilizată, de obicei, pentru atingerea altor scopuri. De asemenea, în funcție de rezultatele verificărilor de sănătate, pot fi necesare acțiuni externe (în raport cu alte obiective ale rețelelor de servicii): de exemplu, actualizarea paginii stării, crearea unei probleme pe GitHub sau completarea unui tichet JIRA. Și mesh-urile de servicii oferă un mecanism convenabil pentru automatizarea tuturor acestor procese.

10. Redirecționarea încărcării (load shedding)

TL;DR: Redirecționați traficul ca răspuns la o creștere temporară a utilizării.

Dacă un anumit serviciu se dovedește a fi supraîncărcat cu trafic, puteți redirecționa temporar o parte din acest trafic către o altă destinație (adică „a o scurge”, „a o turna” (shed) acolo). De exemplu, către un serviciu de rezervă sau un centru de date, sau către un permanent Pulsar În consecință, serviciul va continua să proceseze o parte din cereri în loc să se prăbușească și să înceteze complet procesarea. Resetează încărcătura este preferabilă decât întreruperea lanțului, dar totuși nu ar trebui să abuzezi de ea. Aceasta permite prevenirea defectărilor în cascadă, care duc la prăbușirea serviciilor downstream.

11. Paralelelizarea / mirrorizarea traficului

TL;DR: Trimiteți o cerere simultan în mai multe locuri.

Uneori apare nevoia de a trimite o cerere (sau un anumit set de cereri) simultan către mai multe servicii. Un exemplu caracteristic este trimiterea unei părți din traficul de producție către serviciul de staging. Serverul web principal al producției trimite o cerere către serviciul downstream products.production și doar către acesta. Iar service mesh-ul copiază inteligent această cerere și o trimite către products.staging, despre care serverul web nici măcar nu suspectează.

O altă situație legată de utilizarea service mesh-ului, care poate fi realizată deasupra paralelelizării traficului, este testarea de regresie. Aceasta prevede trimiterea aceleași cereri către diferite versiuni ale serviciului și verificarea dacă toate versiunile se comportă la fel. Până acum nu am întâlnit o implementare a service mesh-ului cu un sistem integrat de testare de regresie precum Diffy, dar ideea în sine pare promițătoare.

12. Izolarea

TL;DR: Împărțiți-vă service mesh-ul în mini-rețele.

De asemenea, cunoscută sub numele de segmentare, izolarea este arta de a împărți service mesh-ul în segmente logice separate, care nu știu nimic unii despre alții. Izolarea este oarecum similară cu crearea de rețele private virtuale. Diferența principală este că încă puteți beneficia de toate avantajele service mesh-ului (cum ar fi descoperirea serviciilor), dar cu o securitate suplimentară. De exemplu, dacă un atacator reușește să pătrundă într-un serviciu dintr-o subrețea, acesta nu va putea vedea ce servicii sunt active în alte subrețele sau să intercepteze traficul acestora.

În plus, avantajele pot fi și organizaționale. Poate doriți să împărțiți serviciile în subrețele în funcție de structura companiei și să eliberați dezvoltatorii de povara cognitivă generată de necesitatea de a ține în minte întreaga service mesh.

13. Limitarea frecvenței cererilor, reîncercări și timeout-uri

TL;DR: Nu mai este necesar să incluzi în baza de cod sarcinile de gestionare a cererilor.

Toate aceste lucruri ar putea fi considerate cazuri separate de utilizare, dar am decis să le unesc datorită unei caracteristici comune: preiau sarcinile de gestionare a ciclului de viață al cererilor, de obicei realizate de bibliotecile aplicațiilor. Dacă dezvolți un server web pe Ruby on Rails (neintegrat cu service mesh) care efectuează cereri către servicii backend prin gRPC, aplicația va trebui să decidă singură ce să facă dacă N cereri eșuează. De asemenea, va trebui să stabilești ce volum de trafic pot gestiona aceste servicii și să 'hardcode' aceste parametrii cu ajutorul unei biblioteci speciale. În plus, aplicația va trebui să decidă când este timpul să renunțe și să permită cererii să expire (pe timeout). Și pentru a schimba oricare dintre parametrii menționați anterior, serverul web va trebui să fie oprit, reproiectat și repornit.

Transferul acestor sarcini către service mesh înseamnă nu doar că dezvoltatorii serviciilor nu va trebui să se gândească la ele, ci și că acestea pot fi considerate într-o manieră mai globală. Dacă se utilizează un lanț complex de servicii, să zicem, A -> B -> C -> D -> E, trebuie să iei în considerare întregul ciclu de viață al cererii. Dacă scopul este de a extinde timeout-urile în serviciul C, este logic să faci asta totodată, nu în părți: actualizând codul serviciului și așteptând ca pull request-ul să fie acceptat și sistemul CI să desfășoare serviciul actualizat.

14. Telemetrie

TL;DR: Colectați toate informațiile necesare (și nu atât de necesare) de la servicii.

Telemetria este un termen general care include metrice, trasare distribuită și jurnale. Service mesh oferă mecanisme pentru colectarea și procesarea tuturor celor trei tipuri de date. Aici devine totul un pic neclar, deoarece numărul opțiunilor posibile este prea mare. Pentru colectarea metricilor există Prometheus și alte instrumente, iar pentru colectarea jurnalelor poți utiliza fluentd, Loki, Vector și altele. (de exemplu, ClickHouse cu al nostru loghouse pentru K8s — n.tr.), pentru trasare distribuită există Jaeger și altele. Fiecare service mesh poate susține anumite instrumente și nu susține altele. Va fi interesant de văzut dacă proiectul Open Telemetry va putea asigura o oarecare convergență.

În acest caz, avantajul tehnologiei service mesh este acela că containerele sidecar pot, în principiu, să colecteze toate datele menționate anterior de la serviciile lor. Cu alte cuvinte, aveți la dispoziție un sistem unic de colectare a telemetriei, iar service mesh poate procesa toate aceste informații în diverse moduri. De exemplu:

  • a urmări log-urile de la un anumit serviciu în CLI;
  • a monitoriza volumul de cereri de pe panoul de control al service mesh;
  • a colecta trasee distribuite și a le redirecționa către un sistem precum Jaeger.

Atenție, judecată subiectivă: În general, telemetria este domeniul în care intervenția serviciului mesh nu este dorită. Colectarea informațiilor de bază și urmărirea în timp real a unor „metrice de aur” precum procentul cererilor reușite și întârzierile este normal, dar să sperăm că nu ne vom confrunta cu apariția unor stive de tip Frankenstein care vor încerca să înlocuiască sistemele specializate, dintre care unele s-au dovedit deja a fi excelente și bine studiate.

15. Audit

TL;DR: Cel care uită lecțiile istoriei este sortit să le repete.

Auditul este arta de a observa evenimente importante în sistem. În cazul service mesh, acest lucru poate însemna monitorizarea celor care au făcut cereri către anumite endpoint-uri ale unor servicii sau de câte ori a avut loc un anumit eveniment legat de securitate în ultima lună.

Este clar că auditul este strâns legat de telemetrie. Diferența constă în faptul că telemetria este de obicei asociată cu lucruri precum performanța și eficiența tehnică, în timp ce auditul poate avea legătură cu probleme juridice și alte aspecte care depășesc domeniul strict tehnic (de exemplu, conformitatea cu GDPR ― Regulamentul general privind protecția datelor al UE).

16. Vizualizare

TL;DR: Trăiască React.js ― o sursă inepuizabilă de interfețe ciudate.

Poate există un termen mai adecvat, dar nu-l cunosc. Mă refer doar la reprezentarea grafică a service mesh sau a unor componente ale sale. Aceste vizualizări pot include indicatori precum întârzierile medii, informații despre configurația containerelor sidecar, rezultate ale verificărilor de sănătate și alerte.

Lucrul într-un mediu orientat pe servicii implică o sarcină cognitivă mult mai mare comparativ cu Majestatea Sa Monolit. Prin urmare, presiunea cognitivă trebuie redusă cu orice preț. O interfață grafică banală pentru service mesh, care permite clic pe un buton și obținerea rezultatului dorit, poate fi decisivă pentru creșterea popularității acestei tehnologii.

Nu au fost incluse pe listă

Inițial, am avut intenția de a include în listă încă câteva scenarii de utilizare, dar am decis să nu fac asta. Iată-le împreună cu motivele deciziei mele:

  • Multi-datacenter. În opinia mea, acesta nu este atât un scenariu de utilizare, cât o arie restrânsă și specifică de aplicare a rețelelor de servicii sau a unui set de funcționalități precum descoperirea serviciilor.
  • Ingress și egress. Aceasta este o zonă conexă, dar m-am limitat (poate, artificial) la scenariul de utilizare „trafic est-vest”. Ingress și egress merită un articol separat.

Concluzie

Asta e tot pentru acum! Din nou, această listă este destul de condiționată și, cel mai probabil, incompletă. Dacă credeți că am omis ceva sau am greșit în vreun fel, mă puteți contacta pe Twitter (@lucperkins). Vă rog să respectați bunele maniere.

P.S. de la traducător

Ca bază pentru ilustrația principală a articolului am folosit o imagine din articolul „What is a Service Mesh (and when to use one)?” (autor - Gregory MacKinnon). Aceasta arată cum parte din funcționalitatea din aplicații (în verde) a trecut la service mesh, care asigură interconexiunile între ele (în albastru).

Citiți și în blogul nostru:

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster