Istio Circuit Breaker: dezactivarea containerelor defecte

Sărbătorile s-au terminat și am revenit cu a doua noastră postare din seria Istio Service Mesh.

Istio Circuit Breaker: dezactivarea containerelor defecte

Subiectul de astăzi este Circuit Breaker, care tradus în inginerie electrică rusă înseamnă „întrerupător de circuit”, în limbajul comun – „întrerupător de circuit”. Numai în Istio această mașină nu deconectează un circuit scurtcircuitat sau supraîncărcat, ci containere defecte.

Cum ar trebui să funcționeze în mod ideal

Când microserviciile sunt gestionate de Kubernetes, de exemplu în cadrul platformei OpenShift, ele se scalează automat în sus și în jos, în funcție de încărcare. Deoarece microservicii rulează în pod-uri, pot exista mai multe instanțe ale unui microserviciu containerizat pe un punct final, iar Kubernetes va direcționa solicitările și echilibrul de încărcare între ele. Și - în mod ideal - toate acestea ar trebui să funcționeze perfect.

Ne amintim că microserviciile sunt mici și efemere. Efemeritatea, care înseamnă aici ușurința de a apărea și de a dispărea, este adesea subestimată. Nașterea și moartea unei alte instanțe a unui microserviciu într-un pod sunt lucruri destul de așteptate, OpenShift și Kubernetes se descurcă bine și totul funcționează grozav - dar din nou în teorie.

Cum funcționează cu adevărat

Acum imaginați-vă că o anumită instanță a unui microserviciu, adică un container, a devenit inutilizabilă: fie nu răspunde (eroare 503), fie, ceea ce este mai neplăcut, răspunde, dar prea încet. Cu alte cuvinte, devine glitch sau nu răspunde la solicitări, dar nu este eliminat automat din pool. Ce ar trebui făcut în acest caz? Sa reincerci? Ar trebui să-l elimin din schema de rutare? Și ce înseamnă „prea lent” – câți sunt în cifre și cine le determină? Poate doar să-i dai o pauză și să încerci din nou mai târziu? Dacă da, cât mai târziu?

Ce este Pool Ejection în Istio

Și aici Istio vine în ajutor cu mașinile sale de protecție a întrerupătorilor, care îndepărtează temporar containerele defecte din pool-ul de resurse de rutare și echilibrare a sarcinii, implementând procedura Pool Ejection.

Folosind o strategie de detectare a valorii aberante, Istio detectează curbele pod care sunt în afara liniilor și le elimină din pool-ul de resurse pentru o perioadă de timp predeterminată, numită fereastră de somn.

Pentru a arăta cum funcționează acest lucru în Kubernetes pe platforma OpenShift, să începem cu o captură de ecran a microserviciilor care funcționează normal din exemplul din depozit Red Hat Developer Demos. Aici avem două poduri, v1 și v2, fiecare rulând câte un container. Când regulile de rutare Istio nu sunt utilizate, Kubernetes are în mod implicit o rutare uniform echilibrată:

Istio Circuit Breaker: dezactivarea containerelor defecte

Pregătesc pentru un accident

Înainte de a face Pool Ejection, trebuie să creați o regulă de rutare Istio. Să presupunem că vrem să distribuim cererile între poduri într-un raport de 50/50. În plus, vom crește numărul de containere v2 de la unul la doi, astfel:

oc scale deployment recommendation-v2 --replicas=2 -n tutorial

Acum setăm o regulă de rutare, astfel încât traficul să fie distribuit între poduri într-un raport de 50/50.

Istio Circuit Breaker: dezactivarea containerelor defecte
Iată cum arată rezultatul acestei reguli:

Istio Circuit Breaker: dezactivarea containerelor defecte
Puteți găsi greșeli în faptul că acest ecran nu este 50/50, ci 14:9, dar în timp situația se va îmbunătăți.

Făcând o eroare

Acum să dezactivăm unul dintre cele două containere v2, astfel încât să avem un container v1 sănătos, un container v2 sănătos și un container v2 defect:

Istio Circuit Breaker: dezactivarea containerelor defecte

Remedierea erorii

Deci, avem un container defect și este timpul pentru Ejectarea piscinei. Folosind o configurare foarte simplă, vom exclude acest container eșuat din orice scheme de rutare timp de 15 secunde, în speranța că va reveni la o stare sănătoasă (fie reporniți, fie restabiliți performanța). Iată cum arată această configurație și rezultatele muncii sale:

Istio Circuit Breaker: dezactivarea containerelor defecte
Istio Circuit Breaker: dezactivarea containerelor defecte
După cum puteți vedea, containerul v2 eșuat nu mai este utilizat pentru cererile de rutare, deoarece a fost eliminat din pool. Dar după 15 secunde se va întoarce automat la piscină. De fapt, tocmai am arătat cum funcționează Pool Ejection.

Să începem să construim arhitectura

Pool Ejection, combinată cu capabilitățile de monitorizare ale Istio, vă permite să începeți să construiți un cadru pentru înlocuirea automată a containerelor defecte pentru a reduce, dacă nu a elimina, timpul de nefuncționare și defecțiunile.

NASA are un motto tare - Eșecul nu este o opțiune, al cărui autor este considerat directorul de zbor Gene Kranz. Poate fi tradus în rusă ca „Eșecul nu este o opțiune”, iar sensul aici este că totul poate fi făcut să funcționeze dacă aveți suficientă voință. Cu toate acestea, în viața reală, eșecurile nu se întâmplă doar, ele sunt inevitabile, peste tot și în orice. Și cum să tratăm cu ele în cazul microserviciilor? În opinia noastră, este mai bine să ne bazăm nu pe voința, ci pe capacitățile containerelor, Kubernetes, Red Hat OpenShiftși Istio.

Istio, așa cum am scris mai sus, implementează conceptul de întrerupătoare, care s-a dovedit bine în lumea fizică. Și la fel cum un întrerupător de circuit electric oprește o secțiune cu probleme a unui circuit, software-ul Circuit Breaker de la Istio deschide conexiunea dintre un flux de solicitări și un container cu probleme atunci când ceva este în neregulă cu punctul final, de exemplu, când serverul s-a prăbușit sau a început să se prăbușească. încetini.

Mai mult decât atât, în cel de-al doilea caz există doar mai multe probleme, deoarece frânele unui container nu numai că provoacă o cascadă de întârzieri în serviciile care îl accesează și, ca urmare, reduc performanța sistemului în ansamblu, dar generează și repetate. solicitări către un serviciu deja lent, ceea ce nu face decât să agraveze situația .

Întrerupător de circuit în teorie

Circuit Breaker este un proxy care controlează fluxul de cereri către un punct final. Când acest punct nu mai funcționează sau, în funcție de setările specificate, începe să încetinească, proxy-ul întrerupe conexiunea cu containerul. Traficul este apoi redirecționat către alte containere, pur și simplu datorită echilibrării încărcăturii. Conexiunea rămâne deschisă pentru o anumită fereastră de somn, să zicem două minute, apoi este considerată pe jumătate deschisă. O încercare de a trimite următoarea cerere determină starea ulterioară a conexiunii. Dacă totul este în regulă cu serviciul, conexiunea revine la starea de funcționare și devine din nou închisă. Dacă tot este ceva în neregulă cu serviciul, conexiunea este deconectată și fereastra de repaus este reactivată. Iată cum arată o diagramă simplificată de stare a întrerupătorului:

Istio Circuit Breaker: dezactivarea containerelor defecte
Este important de remarcat aici că toate acestea se întâmplă la nivelul, ca să spunem așa, arhitecturii sistemului. Prin urmare, la un moment dat va trebui să înveți aplicațiile tale să lucreze cu Circuit Breaker, de exemplu, furnizând o valoare implicită ca răspuns sau, dacă este posibil, ignorând existența serviciului. Pentru aceasta este folosit un model de pereți etanși, dar acesta depășește domeniul de aplicare al acestui articol.

Circuit Breaker în practică

De exemplu, vom rula două versiuni ale microserviciului nostru de recomandare pe OpenShift. Versiunea 1 va funcționa bine, dar în v2 vom construi o întârziere pentru a simula încetinirile pe server. Pentru a vizualiza rezultatele, utilizați instrumentul asediu:

siege -r 2 -c 20 -v customer-tutorial.$(minishift ip).nip.io

Istio Circuit Breaker: dezactivarea containerelor defecte
Totul pare să funcționeze, dar cu ce preț? La prima vedere, avem disponibilitate de 100%, dar aruncați o privire mai atentă - durata maximă a tranzacției este de până la 12 secunde. Acesta este în mod clar un blocaj și trebuie extins.

Pentru a face acest lucru, vom folosi Istio pentru a elimina apelurile către containere încetinite. Iată cum arată configurația corespunzătoare folosind Circuit Breaker:

Istio Circuit Breaker: dezactivarea containerelor defecte
Ultima linie cu parametrul httpMaxRequestsPerConnection semnalează că conexiunea cu ar trebui să fie deconectată atunci când încercați să creați o altă conexiune - o a doua - în plus față de cea existentă. Deoarece containerul nostru simulează un serviciu lent, astfel de situații vor apărea periodic, iar apoi Istio va returna o eroare 503, dar aceasta este ceea ce va arăta asediu:

Istio Circuit Breaker: dezactivarea containerelor defecte

OK, avem Circuit Breaker, ce urmează?

Deci, am implementat oprirea automată fără a atinge codul sursă al serviciilor în sine. Folosind Circuit Breaker și procedura Pool Ejection descrisă mai sus, putem elimina containerele de frână din pool-ul de resurse până când revin la normal și le putem verifica starea la o frecvență specificată - în exemplul nostru, aceasta este de două minute (parametrul sleepWindow).

Rețineți că capacitatea unei aplicații de a răspunde la o eroare 503 este încă setată la nivel de cod sursă. Există multe strategii pentru utilizarea Circuit Breaker, în funcție de situație.

In urmatoarea postare: Vom vorbi despre urmărirea și monitorizarea care sunt deja încorporate sau adăugate cu ușurință în Istio, precum și despre cum să introduceți intenționat erori în sistem.

Sursa: www.habr.com

Adauga un comentariu