Le vacanze sono finite e torniamo con il nostro secondo post della serie Istio Service Mesh.
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
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.
Ecco come appare il risultato di questa regola:
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:
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:
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
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:
È 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
siege -r 2 -c 20 -v customer-tutorial.$(minishift ip).nip.io
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:
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:
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