Wie kann ich einen skalierbaren, zuverlässigen Haproxy-Cluster auf Amazon EC2 bereitstellen?

25

Wir benötigen einige erweiterte Funktionen, die von ELB bereitgestellt werden (meistens L7-Inspektion), aber es ist nicht klar, wie mit EC2 mit so etwas wie Haproxy umgegangen werden kann, wenn Herzschlag und Hochverfügbarkeit erreicht werden. Es besteht eine hohe Wahrscheinlichkeit, dass wir drei oder mehr Haproxy-Knoten im Cluster benötigen, sodass ein einfacher Herzschlag zwischen zwei Knoten nicht funktioniert.

Es scheint, als wäre eine Heartbeat-Schicht vor den Haproxy-Knoten der richtige Weg, möglicherweise mithilfe von IPVS, die Konfigurationsänderungen jedoch so zu behandeln, wie sich der EC2-Cluster ändert (entweder durch absichtliche Änderungen wie Erweiterung oder unbeabsichtigt wie Verlust eines EC2-Knoten) scheint nicht trivial.

Vorzugsweise würde die Lösung mindestens zwei Availability Zones umfassen.

In Beantwortung von Qs: Nein, Sitzungen sind nicht klebrig. Ja, wir brauchen SSL, aber das könnte theoretisch von einem anderen Setup übernommen werden - wir können SSL-Datenverkehr an einen anderen Ort als Nicht-SSL-Datenverkehr leiten.

Don MacAskill
quelle
Ich recherchiere, wie Canary Deployments mit einem langsam ansteigenden Prozentsatz des Datenverkehrs durchgeführt werden, der auf die neue Version der Software zugreift, und ich bin sehr gespannt, wo Sie am Ende dabei gelandet sind. Haben Sie am Ende einen von Jespers Vorschlägen ausprobiert?
Iain

Antworten:

14

OK, ich habe noch nie eine AWS-Lösung für den Lastenausgleich mit Datenverkehr auf der Ebene von SmugMug erstellt, aber wenn ich nur an die Theorie und die Dienste von AWS denke, fallen mir ein paar Ideen ein.

In der ursprünglichen Frage fehlen einige Punkte, die sich auf das Lastenausgleichsdesign auswirken können:

  1. Sticky Sessions oder nicht? Es ist sehr zu bevorzugen, keine Sticky-Sitzung zu verwenden und alle Load Balancer (LBs) nur Round-Robin (RR) oder zufällige Backend-Auswahl verwenden zu lassen. RR- oder zufällige Backend-Auswahlen sind einfach, skalierbar und bieten unter allen Umständen eine gleichmäßige Lastverteilung.
  2. SSL oder nicht? Ob SSL verwendet wird oder nicht, und über welchen Prozentsatz der Anforderungen hinaus, wirkt sich im Allgemeinen auf den Lastenausgleich aus. Es ist häufig vorzuziehen, SSL so früh wie möglich zu beenden, um die Verarbeitung von Zertifikaten zu vereinfachen und die SSL-CPU-Last von Webanwendungsservern fernzuhalten.

Ich antworte aus der Perspektive, wie die Lastausgleichsschicht selbst hoch verfügbar gehalten werden kann. Das Beibehalten der Anwendungsserver-HA erfolgt nur mit den Integritätsprüfungen, die in Ihren L7-Load-Balancern integriert sind.

OK, ein paar Ideen, die funktionieren sollten:

1) "Der AWS-Weg":

  • Erste Ebene ganz vorne: Verwenden Sie ELB im L4-Modus (TCP / IP).
  • Zweite Ebene: Verwenden Sie EC2-Instanzen mit dem L7-Load-Balancer Ihrer Wahl (Nginx, HAProxy, Apache usw.).

Vorteile / Idee: Die L7-Load-Balancer können relativ einfache EC2-AMIs sein, die alle von demselben AMI geklont wurden und dieselbe Konfiguration verwenden. Somit können die Tools von Amazon alle HA-Anforderungen erfüllen: ELB überwacht die L7-Load-Balancer. Wenn ein L7-LB stirbt oder nicht mehr reagiert, erzeugen ELB und Cloudwatch automatisch eine neue Instanz und bringen sie in den ELB-Pool.

2) Das DNS-Round-Robin mit Überwachungsmöglichkeit:

  • Verwenden Sie das einfache DNS-Round-Robin-Verfahren, um eine grobkörnige Lastverteilung über mehrere IP-Adressen zu erzielen. Angenommen, Sie veröffentlichen drei IP-Adressen für Ihre Site.
  • Jede dieser drei IP-Adressen ist eine AWS Elastic IP-Adresse (EIA), die an eine EC2-Instanz mit einem L7-Load-Balancer Ihrer Wahl gebunden ist.
  • Wenn ein EC2 L7 LB stirbt, ein nachgiebiger User - Agent (Browser) sollte verwendet nur eine der anderen IP - Adressen statt.
  • Richten Sie einen externen Überwachungsserver ein. Überwachen Sie jedes der 3 EIPs. Wenn einer nicht mehr reagiert, verwenden Sie die Befehlszeilentools von AWS und einige Skripts, um die EIP auf eine andere EC2-Instanz zu verschieben.

Vorteile / Idee: Kompatible Benutzeragenten sollten automatisch auf eine andere IP-Adresse umschalten, wenn eine nicht mehr reagiert. Daher sollte im Falle eines Fehlers nur 1/3 Ihrer Benutzer betroffen sein, und die meisten von ihnen sollten nichts bemerken, da ihre UA stillschweigend auf eine andere IP-Adresse umschaltet. Und Ihre externe Überwachungsbox merkt, dass ein EIP nicht reagiert, und behebt die Situation innerhalb weniger Minuten.

3) DNS-RR an HA-Serverpaare:

Grundsätzlich ist dies Dons eigener Vorschlag für einen einfachen Heartbeat zwischen zwei Servern, der jedoch für mehrere IP-Adressen vereinfacht wird.

  • Veröffentlichen Sie mithilfe von DNS RR eine Reihe von IP-Adressen für den Dienst. Nehmen wir an, Sie veröffentlichen gemäß dem obigen Beispiel drei IPs.
  • Jede dieser IPs wird an ein Paar EC2-Server gesendet, also insgesamt 6 EC2-Instanzen.
  • Jedes dieser Paare verwendet Heartbeat oder eine andere HA-Lösung zusammen mit AWS-Tools, um 1 IP-Adresse in einer aktiven / passiven Konfiguration am Leben zu erhalten.
  • Auf jeder EC2-Instanz ist der L7-Load-Balancer Ihrer Wahl installiert.

Vorteile / Idee: In der vollständig virtualisierten Umgebung von AWS ist es nicht so einfach, über L4-Services und Failover-Modi nachzudenken. Durch die Vereinfachung auf ein Paar identischer Server, die nur 1 IP-Adresse am Leben erhalten, wird das Überlegen und Testen einfacher.

Fazit: Auch hier habe ich in der Produktion noch nichts ausprobiert. Nur aus meinem Bauch heraus, Option eins mit ELB im L4-Modus und selbstverwalteten EC2-Instanzen, da L7-LBs am ehesten mit dem Geist der AWS-Plattform übereinstimmen und Amazon wahrscheinlich später investieren und expandieren wird. Dies wäre wahrscheinlich meine erste Wahl.

Jesper M
quelle
1
Ich liebe Ansatz Nr. 1, das ist die Richtung, in die ich mich begeben habe, aber es gibt immer noch einige interessante Fallstricke - nicht zuletzt, dass ELB nicht mit einem kompletten AZ-Fehler zurechtkommt (etwas, das wir bereits erlebt haben) ). Die einfache, aber glückliche "Lösung" besteht darin, die Haproxies hinter ELB so zu konfigurieren, dass sie AZs kreuzen (möglicherweise mit einem Backup-Cluster in einem anderen AZ). Wenn also in jedem AZ mindestens ein Haproxy vorhanden ist, sollte es in Ordnung sein. Aber das minimiert nur, nicht beseitigt das Problem. Irgendwelche Ideen zu diesem Problem?
Don MacAskill
@Don MacAskill: Ich weiß, dass AWS einige große Service-Ausfallzeiten hatte, aber es ist schwierig, die Zuverlässigkeit von AWS besser als AZ zu machen. Der Übergang zum Multi-AZ-Betrieb des Frontends könnte leicht der erste Schritt zum Multi-AZ-Betrieb des gesamten Stacks sein, und das ist eine ganze Menge Schlangen ...
Jesper M
@Don MacAskill: Eine Option wäre eine geobewusste DNS-Auflösung wie DynDNS Dynect -> ELB + L7-LBs in einem AZ, wobei ein anderer ELB + L7 in einem anderen AZ im Hot-Standby-Modus ist. (Abgesehen davon, dass Dynect geobewusst ist, verfügt Dynect auch über einige Integritätsprüfungen.) DynDNS verfügt über eine hervorragende Erfolgsbilanz in Bezug auf die Betriebszeit. Dennoch ist das Hinzufügen von geobewusstem DNS ein weiterer SPOF. Ob Dynect + Load Balancing in 2 AWS langfristig eine bessere Verfügbarkeit hat als nur ein AWS AZ, ist mir nicht klar. Sehen Sie sich dies für einen Überblick darüber an, was ich meine, ohne die Multi-AZ-Datenbanken: dev.bizo.com/2010/05/improving-global-application.html
Jesper M
@Don MacAskill: Nur eine letzte Sache - denken Sie daran, dass eine einzelne ELB-Instanz mehrere AZs umfassen kann. Es kann sich nicht über EC2- Regionen erstrecken . Aber wenn es akzeptabel ist, ELB auf L7-LBs in zwei AZs innerhalb derselben Region anzuwenden, ist dies bei weitem die einfachste ... Sie haben geschrieben, dass ELB nicht mit einem vollständigen AZ-Fehler zurechtkommt, vielleicht wissen Sie bereits mehr als Ich mache.
Jesper M
Ja, wenn eine ELB mehrere AZs umfasst und einen Fehler aufweist, bei dem sie keinen der Back-End-Knoten in einer AZ erreichen kann (sie sind überlastet, inaktiv, geben 503s zurück, was auch immer), sehen die Endbenutzer diese Fehler. t Umleiten zu den anderen AZ (s). Ich hoffe, das ist geplant, aber es hat uns schon einmal gebissen.
Don MacAskill
2

Wenn Sie keine dauerhaften Sitzungen durchführen oder den Tomcat / Apache-Stil verwenden (die Knoten-ID an die Sitzungs-ID anhängen, anstatt den Status in der LB zu speichern), würde ich ELB vor einer Gruppe von Haproxies verwenden. ELB verfügt über einen integrierten Healthcheck, mit dem Sie die Haproxies überwachen und alle aus dem Pool entfernen können. Viel weniger einzurichten als Heartbeat-Failover.

Was die Verbreitung von Veränderungen angeht, habe ich keine gute Antwort. Puppet eignet sich hervorragend für die Erstkonfiguration und das Implementieren von Änderungen, aber zum Hinzufügen / Entfernen von Knoten möchten Sie in der Regel eine schnellere Antwort als das 30-minütige Abfrageintervall.

Ben Jencks
quelle
1
Das ist eine gute Lösung (und eine gute Frage!). Sie können Amazon SNS verwenden, um Konfigurationsänderungen auf Push-Weise zu verbreiten. Sie benötigen ein Benachrichtigungssystem zum Hinzufügen / Entfernen von Knoten aus der Haproxy-Konfiguration.
Rafiq Maniar
Eine weitere Möglichkeit zum Verwalten von Back-End-Servern (an die Haproxy weiterleitet) besteht darin, dass jeder Back-End-Server entweder alle Haproxies oder einen Konfigurationsserver mit einer regelmäßigen Registrierung (ca. 30 Sekunden) sendet. Wenn man stirbt, wird es schnell unregistriert (und haproxy sollte es trotzdem bemerken); Wenn ein neues auftaucht, wird es automatisch in Rotation versetzt. Dies ist anscheinend, was Netflix tut.
Ben Jencks
1

Ich habe es selbst nicht benutzt, aber ich habe viele Leute gesehen, die erwähnt haben, wie sie Puppet verwendet haben, um solche Probleme auf EC2 zu lösen

JamesRyan
quelle
Ja, mit Puppet auf EC2 lässt sich ein Cluster ganz einfach verwalten. Erstellen Sie einfach eine Mikroinstanz und verwenden Sie diese als Puppenmeister.
Tom O'Connor
1
Wir verwenden Puppet in unseren Rechenzentren, haben EC2 aber noch nicht ausprobiert. Ist Puppet EC2 irgendwie bewusst, so dass es Knoten mit ec2-describe-Instances oder so finden und basierend auf dieser Ausgabe automatisch konfigurieren / rekonfigurieren kann? Und wie würden Sie damit umgehen, dass der Puppenspieler plötzlich weggeht?
Don MacAskill
Warum sollte es plötzlich verschwinden?
Tom O'Connor
Es ist nicht EC2-fähig, aber Sie können es so einrichten, dass neue Knoten zum Signieren markiert werden, wenn Sie sie starten, und ein externes Knotenskript verwenden, um sie zu beschreiben. Ich habe Python für SimpleDB (externe Knoten) und SQS (Warteschlange für Signaturanforderungen für neue Knoten) geschrieben. Ein Ubuntu- Entwickler
Ben Jencks
Wenn der Puppenspieler plötzlich verschwindet, wird das Manifest nicht ausgeführt, dh die Knoten bleiben in dem Zustand, in dem sie sich befinden.
Ben Jencks