Come posso distribuire un cluster haproxy scalabile e affidabile su Amazon EC2?


25

Abbiamo bisogno di alcune funzionalità più avanzate di quelle fornite da ELB (principalmente l'ispezione L7), ma non è ovvio come gestire cose come il battito cardiaco e l'alta disponibilità con qualcosa come haproxy usando EC2. C'è un'alta probabilità che avremmo bisogno di 3 o più nodi haproxy nel cluster, quindi il semplice battito cardiaco tra due nodi non funzionerà.

Sembra che avere un livello di battito cardiaco di fronte ai nodi haproxy sarebbe la strada da percorrere, possibilmente usando IPVS, ma gestendo le modifiche alla configurazione mentre cambia il cluster EC2 (o tramite modifiche intenzionali, come l'espansione o involontario, come perdere un Nodo EC2) sembra non banale.

Preferibilmente la soluzione si estenderebbe su almeno due zone di disponibilità.

In risposta a Qs: No, le sessioni non sono appiccicose. E sì, avremo bisogno di SSL, ma in teoria potrebbe essere gestito completamente da un'altra configurazione: siamo in grado di indirizzare il traffico SSL verso una posizione diversa rispetto al traffico non SSL.


Sto studiando come eseguire le distribuzioni di canarini con una percentuale di traffico in lento aumento verso la nuova versione del software e sono super curioso di sapere dove sei finito. Hai finito per provare qualcuno dei suggerimenti di Jesper?
Iain,

Risposte:


14

OK, non ho mai creato una soluzione di bilanciamento del carico AWS con traffico sui livelli di SmugMug da solo, ma solo pensando alla teoria e ai servizi di AWS, mi vengono in mente un paio di idee.

Alla domanda originale mancano alcune cose che tendono a influire sul design del bilanciamento del carico:

  1. Sessioni appiccicose o no? È molto preferibile non usare la sessione appiccicosa e lasciare che tutti i bilanciatori del carico (LB) utilizzino il round robin (RR) o la selezione casuale del backend. Le selezioni RR o di backend casuali sono semplici, scalabili e forniscono una distribuzione uniforme del carico in tutte le circostanze.
  2. SSL o no? Se SSL è in uso o meno e su quale percentuale di richieste, generalmente ha un impatto sulla progettazione del bilanciamento del carico. Spesso è preferibile terminare SSL il più presto possibile, per semplificare la gestione dei certificati e mantenere il carico della CPU SSL lontano dai server delle applicazioni web.

Sto rispondendo dal punto di vista di come mantenere lo strato di bilanciamento del carico stesso altamente disponibile. Mantenere i server delle applicazioni HA è appena fatto con i controlli di integrità integrati nei sistemi di bilanciamento del carico L7.

OK, un paio di idee che dovrebbero funzionare:

1) "Il modo AWS":

  • Il primo strato, nella parte anteriore, utilizza ELB in modalità L4 (TCP / IP).
  • Secondo livello, utilizzare le istanze EC2 con il bilanciamento del carico L7 scelto (nginx, HAProxy, Apache ecc.).

Vantaggi / idea: i bilanciatori di carico L7 possono essere AMI EC2 abbastanza semplici, tutti clonati dalla stessa AMI e utilizzando la stessa configurazione. Pertanto, gli strumenti di Amazon sono in grado di gestire tutte le esigenze di HA: ELB monitora i sistemi di bilanciamento del carico L7. Se un L7 LB muore o non risponde, ELB e Cloudwatch generano insieme automaticamente una nuova istanza e la portano nel pool ELB.

2) "Il round robin DNS con modalità di monitoraggio:"

  • Utilizzare il round robin DNS di base per ottenere una distribuzione del carico a grana grossa su un paio di indirizzi IP. Diciamo solo che pubblichi 3 indirizzi IP per il tuo sito.
  • Ognuno di questi 3 IP è un indirizzo IP elastico AWS (EIA), associato a un'istanza EC2, con un bilanciamento del carico L7 a scelta.
  • Se un LB EC7 L7 si spegne, un agente utente (browser) conforme dovrebbe semplicemente utilizzare uno degli altri IP .
  • Configurare un server di monitoraggio esterno. Monitorare ciascuno dei 3 EIP. Se uno non risponde, utilizzare gli strumenti della riga di comando di AWS e alcuni script per spostare l'EIP su un'altra istanza EC2.

Vantaggi / idea: gli user agent conformi dovrebbero passare automaticamente a un altro indirizzo IP se uno non risponde. Pertanto, in caso di guasto, solo 1/3 dei tuoi utenti dovrebbero essere interessati, e la maggior parte di questi non dovrebbe notare nulla dal momento che il loro UA fallisce silenziosamente su un altro IP. E la tua scatola di monitoraggio esterna noterà che un PEI non risponde e correggerà la situazione in un paio di minuti.

3) DNS RR a coppie di server HA:

Fondamentalmente questo è il suggerimento di Don del semplice battito cardiaco tra una coppia di server, ma semplificato per più indirizzi IP.

  • Utilizzando DNS RR, pubblicare un numero di indirizzi IP per il servizio. Seguendo l'esempio sopra, diciamo solo che pubblichi 3 IP.
  • Ognuno di questi IP va su una coppia di server EC2, quindi in totale 6 istanze EC2.
  • Ognuna di queste coppie utilizza Heartbeat o un'altra soluzione HA insieme agli strumenti AWS per mantenere attivo 1 indirizzo IP, in una configurazione attiva / passiva.
  • Su ogni istanza EC2 è installato il bilanciamento del carico L7 scelto.

Vantaggi / idea: nell'ambiente completamente virtualizzato di AWS non è in realtà facile ragionare sui servizi L4 e sulle modalità di failover. Semplificando su una coppia di server identici mantenendo attivo solo 1 indirizzo IP, diventa più semplice ragionare e testare.

Conclusione: Ancora una volta, in realtà non ho provato nulla di tutto questo in produzione. Proprio dal mio istinto, l'opzione 1 con ELB in modalità L4 e istanze EC2 autogestite come L7 LBs sembrano più in linea con lo spirito della piattaforma AWS e dove Amazon ha maggiori probabilità di investire ed espandersi in seguito. Questa sarebbe probabilmente la mia prima scelta.


1
Quindi adoro l'approccio n. 1, questa è la direzione in cui mi sono appoggiato, ma ci sono ancora alcuni aspetti interessanti - non ultimo il fatto che ELB non gestisce molto bene un'intera AZ (qualcosa che abbiamo già accaduto ). La 'soluzione' semplice, ma schifosa, è quella di avere i proxy dietro ELB configurati per attraversare AZ (forse con un cluster di backup in un'altra AZ) quindi se almeno un haproxy è presente in ogni AZ, dovremmo andare bene. Ma questo non fa che mimare, non elimina il problema. Qualche idea su questo problema?
Don MacAskill,

@Don MacAskill: So che AWS ha avuto un paio di downtime di servizio su larga scala, ma fare meglio dell'affidabilità AZ su AWS è difficile. Passare all'operazione multi-AZ del frontend potrebbe facilmente essere il primo passo verso l'operazione multi-AZ dell'intero stack, e questo è un intero bollitore di serpenti ...
Jesper M

@Don MacAskill: un'opzione sarebbe la risoluzione DNS geo-consapevole come DynDNS Dynect -> ELB + L7 LB all'interno di una AZ, con un altro ELB + L7 in hot standby in un'altra AZ. (Oltre ad essere geo-consapevole, Dynect ha anche alcuni controlli di integrità.) DynDNS ha un ottimo track record per i tempi di attività, ma anche così, l'aggiunta di DNS geo-consapevoli è un altro SPOF. Non è chiaro se il bilanciamento del carico di Dynect + in 2 AZ abbia un tempo di attività a lungo termine migliore di un solo AWS AZ. Vedere questo per una panoramica di ciò che intendo, senza i database multi-AZ: dev.bizo.com/2010/05/improving-global-application.html
Jesper M

@Don MacAskill: solo un'ultima cosa: tieni presente che una singola istanza ELB può comprendere più AZ. Non può estendersi attraverso le regioni EC2 . Ma se solo usare ELB su L7 LB in due AZ nella stessa regione è accettabile, questo sarebbe di gran lunga il più semplice ... Hai scritto "ELB non gestisce molto bene un'intera AZ", forse sai già più di Lo voglio.
Jesper M,

Sì, se un ELB si estende su più AZ e presenta una sorta di errore in cui non è in grado di accedere a nessuno dei nodi back-end in una AZ (sono sovraccarichi, in calo, restituendo 503s, qualunque cosa), gli utenti finali vedono quegli errori - no t reindirizzare verso le altre AZ (s). Spero che sia pianificato, ma ci ha già morso una volta.
Don MacAskill,

2

Se non stai facendo sessioni appiccicose, o se stai usando lo stile tomcat / apache (aggiungi l'ID nodo a sessionid, al contrario dello stato di memorizzazione nell'LB), allora userei ELB davanti a un gruppo di haproxies. ELB ha un controllo di salute integrato, quindi puoi farlo monitorare i problemi e eliminare quelli fuori dal pool. Molto meno da configurare rispetto al failover del battito cardiaco.

Per quanto riguarda la propagazione dei cambiamenti, non ho un'ottima risposta. Puppet è ottimo per la configurazione iniziale e l'implementazione delle modifiche, ma per l'aggiunta / rimozione di nodi si tende a desiderare una risposta più rapida rispetto al suo intervallo di polling di 30 minuti.


1
Questa è una buona soluzione (e una buona domanda!) Puoi utilizzare Amazon SNS per propagare le modifiche alla configurazione in modo push. È necessario un sistema di notifica per aggiungere / rimuovere nodi dalla configurazione haproxy.
Rafiq Maniar il

Un'altra opzione per la gestione dei server di back-end (quelli a cui è inoltrato haproxy) è di fare in modo che ciascun server di back-end invii tutti i proxy o un server di configurazione, una registrazione periodica (circa 30 secondi). Se uno muore, non viene registrato rapidamente (e comunque deve essere presente l'apolidia); se ne esce uno nuovo, questo viene automaticamente messo in rotazione. Questo è apparentemente ciò che fa Netflix.
Ben Jencks il

1

Non l'ho usato da solo, ma ho visto molte persone menzionare l'uso di marionette per gestire questo tipo di problemi su EC2


Sì, Puppet su EC2 semplifica la gestione di un cluster. Basta creare una microistanza e usarla come burattinaio.
Tom O'Connor il

1
Usiamo le marionette nei nostri datacenter, ma non abbiamo ancora provato su EC2. Puppet è in grado di riconoscere EC2 in qualche modo, in modo tale da poter trovare nodi usando ec2-descrizioni-istanze o qualcosa del genere e configurare / riconfigurare automagicamente in base a quell'output? E come gestiresti il ​​burattinaio che va via all'improvviso?
Don MacAskill,

Perché dovrebbe andare via all'improvviso?
Tom O'Connor il

Non è compatibile con EC2, ma è possibile configurarlo in modo che i nuovi nodi vengano contrassegnati per la firma all'avvio e utilizzare uno script di nodi esterni per descriverli. Ho scritto un python per farlo con SimpleDB (nodi esterni) e SQS (coda di richieste di firma per nuovi nodi); uno sviluppatore ubuntu ha scritto degli script usando S3: ubuntumathiaz.wordpress.com/2010/04/07/…
Ben Jencks il

Se il burattinaio se ne va improvvisamente, semplicemente non esegue il manifest, ovvero lascia i nodi in qualunque stato si trovino.
Ben Jencks,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.