Istio Circuit Breaker: disabilitazione dei contenitori difettosi

Le vacanze sono finite e torniamo con il nostro secondo post della serie Istio Service Mesh.

Istio Circuit Breaker: disabilitazione dei contenitori difettosi

L’argomento di oggi è Circuit Breaker, che tradotto in ingegneria elettrica russa significa “interruttore”, nel linguaggio comune – “interruttore”. Solo in Istio questa macchina non scollega un circuito in corto o sovraccarico, ma contenitori difettosi.

Come dovrebbe funzionare idealmente

Quando i microservizi sono gestiti da Kubernetes, ad esempio all'interno della piattaforma OpenShift, si adattano automaticamente verso l'alto e verso il basso a seconda del carico. Poiché i microservizi vengono eseguiti in pod, possono esserci più istanze di un microservizio containerizzato su un endpoint e Kubernetes instraderà le richieste e bilancerà il carico tra di esse. E – idealmente – tutto ciò dovrebbe funzionare alla perfezione.

Ricordiamo che i microservizi sono piccoli ed effimeri. L’effimero, che qui significa la facilità di apparire e scomparire, viene spesso sottovalutato. La nascita e la morte di un'altra istanza di un microservizio in un pod sono cose abbastanza previste, OpenShift e Kubernetes lo gestiscono bene e tutto funziona alla grande, ma sempre in teoria.

Come funziona davvero

Immaginiamo ora che un'istanza specifica di un microservizio, ovvero un contenitore, sia diventata inutilizzabile: o non risponde (errore 503) o, cosa più spiacevole, risponde, ma troppo lentamente. In altre parole, diventa difettoso o non risponde alle richieste, ma non viene rimosso automaticamente dal pool. Cosa si dovrebbe fare in questo caso? Per riprovare? Dovrei rimuoverlo dallo schema di routing? E cosa significa "troppo lento": quanti sono in numeri e chi li determina? Forse semplicemente fare una pausa e riprovare più tardi? Se sì, quanto tempo dopo?

Cos'è l'espulsione del pool in Istio

E qui Istio viene in soccorso con le sue macchine di protezione Circuit Breaker, che rimuovono temporaneamente i contenitori difettosi dal pool di risorse di routing e bilanciamento del carico, implementando la procedura Pool Ejection.

Utilizzando una strategia di rilevamento dei valori anomali, Istio rileva i pod della curva che non sono in linea e li rimuove dal pool di risorse per un periodo di tempo specificato, chiamato finestra di sospensione.

Per mostrare come funziona in Kubernetes sulla piattaforma OpenShift, iniziamo con uno screenshot dei microservizi normalmente funzionanti dall'esempio nel repository Demo per sviluppatori Red Hat. Qui abbiamo due pod, v1 e v2, ciascuno dei quali esegue un contenitore. Quando le regole di routing Istio non vengono utilizzate, Kubernetes utilizza per impostazione predefinita il routing round-robin bilanciato in modo uniforme:

Istio Circuit Breaker: disabilitazione dei contenitori difettosi

Prepararsi per un incidente

Prima di eseguire l'espulsione del pool, devi creare una regola di routing Istio. Supponiamo di voler distribuire le richieste tra i pod in un rapporto 50/50. Inoltre, aumenteremo il numero di contenitori v2 da uno a due, in questo modo:

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

Ora impostiamo una regola di routing in modo che il traffico venga distribuito tra i pod in un rapporto 50/50.

Istio Circuit Breaker: disabilitazione dei contenitori difettosi
Ecco come appare il risultato di questa regola:

Istio Circuit Breaker: disabilitazione dei contenitori difettosi
Puoi trovare da ridire sul fatto che questo schermo non è 50/50, ma 14:9, ma col tempo la situazione migliorerà.

Fare un problema tecnico

Ora disabilitiamo uno dei due contenitori v2 in modo da avere un contenitore v1 sano, un contenitore v2 sano e un contenitore v2 difettoso:

Istio Circuit Breaker: disabilitazione dei contenitori difettosi

Risolvere il problema tecnico

Quindi, abbiamo un contenitore difettoso ed è il momento dell'espulsione del pool. Utilizzando una configurazione molto semplice, escluderemo questo contenitore guasto da qualsiasi schema di routing per 15 secondi nella speranza che ritorni a uno stato integro (riavvio o ripristino delle prestazioni). Ecco come appare questa configurazione e i risultati del suo lavoro:

Istio Circuit Breaker: disabilitazione dei contenitori difettosi
Istio Circuit Breaker: disabilitazione dei contenitori difettosi
Come puoi vedere, il contenitore v2 con errori non viene più utilizzato per l'instradamento delle richieste perché è stato rimosso dal pool. Ma dopo 15 secondi tornerà automaticamente in piscina. In realtà, abbiamo appena mostrato come funziona Pool Ejection.

Cominciamo a costruire architettura

Pool Ejection, combinato con le funzionalità di monitoraggio di Istio, ti consente di iniziare a creare un framework per la sostituzione automatica dei contenitori difettosi per ridurre, se non eliminare, tempi di inattività e guasti.

La NASA ha un motto forte: il fallimento non è un'opzione, il cui autore è considerato il direttore di volo Gene Kranz. Può essere tradotto in russo come “Il fallimento non è un’opzione”, e il significato qui è che tutto può funzionare se si ha abbastanza volontà. Tuttavia, nella vita reale, i fallimenti non accadono e basta, sono inevitabili, ovunque e in ogni cosa. E come affrontarli nel caso dei microservizi? A nostro avviso è meglio fare affidamento non sulla forza di volontà, ma sulle capacità dei contenitori, kubernetes, Red Hat OpenShiftE Istio.

Istio, come abbiamo scritto sopra, implementa il concetto di interruttori automatici, che si è dimostrato efficace nel mondo fisico. E proprio come un interruttore elettrico spegne una sezione problematica di un circuito, il software Circuit Breaker di Istio apre la connessione tra un flusso di richieste e un contenitore di problemi quando qualcosa non va con l'endpoint, ad esempio quando il server si è bloccato o ha iniziato a bloccarsi. rallentare.

Inoltre, nel secondo caso ci sono solo più problemi, poiché i freni di un container non solo provocano una cascata di ritardi nei servizi che vi accedono e, di conseguenza, riducono le prestazioni del sistema nel suo insieme, ma generano anche ripetuti richieste ad un servizio già lento, il che non fa altro che aggravare la situazione.

Interruttore automatico in teoria

Circuit Breaker è un proxy che controlla il flusso di richieste verso un endpoint. Quando questo punto smette di funzionare o, a seconda delle impostazioni specificate, inizia a rallentare, il proxy interrompe la connessione con il contenitore. Il traffico viene quindi reindirizzato ad altri contenitori, semplicemente a causa del bilanciamento del carico. La connessione rimane aperta per una determinata finestra di sospensione, ad esempio due minuti, quindi viene considerata semiaperta. Un tentativo di inviare la richiesta successiva determina l'ulteriore stato della connessione. Se tutto va bene con il servizio, la connessione ritorna in condizioni di lavoro e viene nuovamente chiusa. Se c'è ancora qualcosa che non va nel servizio, la connessione viene interrotta e la finestra di sospensione viene riattivata. Ecco come appare un diagramma di stato semplificato dell'interruttore automatico:

Istio Circuit Breaker: disabilitazione dei contenitori difettosi
È importante notare qui che tutto ciò avviene a livello, per così dire, dell'architettura del sistema. Quindi ad un certo punto dovrai insegnare alle tue applicazioni a funzionare con Circuit Breaker, ad esempio fornendo un valore predefinito in risposta o, se possibile, ignorando l'esistenza del servizio. A questo scopo viene utilizzato un modello a paratia, ma va oltre lo scopo di questo articolo.

Interruttore automatico in pratica

Ad esempio, eseguiremo due versioni del nostro microservizio di consigli su OpenShift. La versione 1 funzionerà bene, ma nella v2 inseriremo un ritardo per simulare rallentamenti sul server. Per visualizzare i risultati, utilizzare lo strumento assedio:

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

Istio Circuit Breaker: disabilitazione dei contenitori difettosi
Tutto sembra funzionare, ma a quale costo? A prima vista abbiamo una disponibilità del 100%, ma guarda più da vicino: la durata massima della transazione è di 12 secondi. Questo è chiaramente un collo di bottiglia e deve essere ampliato.

Per fare ciò, utilizzeremo Istio per eliminare le chiamate ai contenitori lenti. Ecco come appare la configurazione corrispondente utilizzando Circuit Breaker:

Istio Circuit Breaker: disabilitazione dei contenitori difettosi
L'ultima riga con il parametro httpMaxRequestsPerConnection segnala che la connessione con deve essere interrotta quando si tenta di crearne un'altra, una seconda, oltre a quella esistente. Poiché il nostro contenitore simula un servizio lento, tali situazioni si verificheranno periodicamente e quindi Istio restituirà un errore 503, ma questo è ciò che verrà mostrato da Siege:

Istio Circuit Breaker: disabilitazione dei contenitori difettosi

OK, abbiamo Circuit Breaker, qual è il prossimo passo?

Pertanto, abbiamo implementato lo spegnimento automatico senza toccare affatto il codice sorgente dei servizi stessi. Utilizzando Circuit Breaker e la procedura Pool Ejection descritta sopra, possiamo rimuovere i contenitori dei freni dal pool di risorse finché non tornano alla normalità e controllarne lo stato con una frequenza specifica - nel nostro esempio, si tratta di due minuti (parametro sleepWindow).

Tieni presente che la capacità di un'applicazione di rispondere a un errore 503 è ancora impostata a livello di codice sorgente. Esistono molte strategie per utilizzare Circuit Breaker, a seconda della situazione.

Nel prossimo post: Parleremo del tracciamento e del monitoraggio già integrati o facilmente aggiunti a Istio, nonché di come introdurre intenzionalmente errori nel sistema.

Fonte: habr.com

Aggiungi un commento