Comment puis-je déployer un cluster haproxy évolutif et fiable sur Amazon EC2?

25

Nous avons besoin de fonctionnalités plus avancées que celles fournies par ELB (principalement l'inspection L7), mais il n'est pas évident de gérer des choses comme le rythme cardiaque et la haute disponibilité avec quelque chose comme un haproxy utilisant EC2. Il est fort probable que nous ayons besoin de 3 nœuds haproxy ou plus dans le cluster, donc un simple battement de cœur entre deux nœuds ne fonctionnera pas.

On dirait que la couche à battre devant les nœuds haproxy serait la voie à suivre, peut-être en utilisant IPVS, mais en gérant les changements de configuration au fur et à mesure que le cluster EC2 change (soit via des changements intentionnels, comme l'expansion, soit involontaire, comme la perte d'un Nœud EC2) semble non trivial.

De préférence, la solution couvrirait au moins deux zones de disponibilité.

En réponse aux questions: Non, les sessions ne sont pas collantes. Et oui, nous aurons besoin de SSL, mais cela pourrait en théorie être entièrement géré par une autre configuration - nous pouvons diriger le trafic SSL vers un emplacement différent du trafic non SSL.

Don MacAskill
la source
Je recherche comment faire des déploiements de canaris avec un pourcentage de trafic qui augmente lentement vers la nouvelle version du logiciel, et je suis très curieux de savoir où vous vous êtes retrouvé avec cela. Avez-vous fini par essayer l'une des suggestions de Jesper?
Iain

Réponses:

14

OK, je n'ai jamais construit de solution d'équilibrage de charge AWS avec du trafic aux niveaux de SmugMug moi-même, mais juste en pensant à la théorie et aux services AWS, quelques idées me viennent à l'esprit.

La question d'origine manque quelques éléments qui ont tendance à avoir un impact sur la conception de l'équilibrage de charge:

  1. Sessions collantes ou pas? Il est très préférable de ne pas utiliser de session persistante et de laisser tous les équilibreurs de charge (LB) utiliser le round robin (RR) ou la sélection de backend aléatoire. Les sélections RR ou backend aléatoires sont simples, évolutives et fournissent une répartition uniforme de la charge en toutes circonstances.
  2. SSL ou pas? Que SSL soit utilisé ou non, et sur quel pourcentage de demandes, a généralement un impact sur la conception de l'équilibrage de charge. Il est souvent préférable de mettre fin à SSL le plus tôt possible, pour simplifier la gestion des certificats et garder la charge du processeur SSL à l'écart des serveurs d'applications Web.

Je réponds du point de vue de la façon de maintenir la couche d'équilibrage de charge elle-même hautement disponible. Garder les serveurs d'applications HA se fait simplement avec les contrôles d'intégrité intégrés à vos équilibreurs de charge L7.

OK, quelques idées qui devraient fonctionner:

1) "La manière AWS":

  • La première couche, à l'avant, utilise ELB en mode L4 (TCP / IP).
  • Deuxième couche, utilisez les instances EC2 avec votre équilibreur de charge L7 de choix (nginx, HAProxy, Apache, etc.).

Avantages / idée: Les équilibreurs de charge L7 peuvent être des AMI EC2 assez simples, tous clonés à partir de la même AMI et utilisant la même configuration. Ainsi, les outils d'Amazon peuvent gérer tous les besoins HA: ELB surveille les équilibreurs de charge L7. Si un L7 LB meurt ou ne répond plus, ELB et Cloudwatch génèrent ensemble une nouvelle instance automatiquement et l'intègrent dans le pool ELB.

2) "Le tournoi à la ronde DNS avec méthode de surveillance:"

  • Utilisez le round robin DNS de base pour obtenir une distribution de charge à grain grossier sur quelques adresses IP. Disons simplement que vous publiez 3 adresses IP pour votre site.
  • Chacune de ces 3 IP est une adresse IP élastique AWS (EIA), liée à une instance EC2, avec un équilibreur de charge L7 de votre choix.
  • Si un EC2 L7 LB meurt, un agent utilisateur conforme (navigateur) doit simplement utiliser l'un des autres IP à la place.
  • Configurez un serveur de surveillance externe. Surveillez chacun des 3 EIP. Si l'un ne répond plus, utilisez les outils de ligne de commande d'AWS et certains scripts pour déplacer l'EIP vers une autre instance EC2.

Avantages / idée: les agents utilisateurs conformes doivent automatiquement basculer vers une autre adresse IP si l'un d'eux ne répond plus. Ainsi, en cas d'échec, seulement 1/3 de vos utilisateurs devraient être impactés, et la plupart d'entre eux ne devraient rien remarquer puisque leur UA bascule silencieusement vers une autre IP. Et votre boîtier de surveillance externe remarquera qu'un EIP ne répond pas et rectifiera la situation en quelques minutes.

3) DNS RR vers des paires de serveurs HA:

Fondamentalement, c'est la propre suggestion de Don d'un battement de cœur simple entre une paire de serveurs, mais simplifié pour plusieurs adresses IP.

  • À l'aide de DNS RR, publiez un certain nombre d'adresses IP pour le service. En suivant l'exemple ci-dessus, disons simplement que vous publiez 3 adresses IP.
  • Chacun de ces IP va à une paire de serveurs EC2, donc 6 instances EC2 au total.
  • Chacune de ces paires utilise Heartbeat ou une autre solution HA avec des outils AWS pour conserver 1 adresse IP active, dans une configuration active / passive.
  • Chaque instance EC2 a votre équilibreur de charge L7 de choix installé.

Avantages / idée: dans l'environnement complètement virtualisé d'AWS, il n'est en fait pas si facile de raisonner sur les services L4 et les modes de basculement. En simplifiant à une paire de serveurs identiques en gardant une seule adresse IP en vie, il devient plus simple de raisonner et de tester.

Conclusion: Encore une fois, je n'ai en fait rien essayé en production. D'après mon intuition, l'option 1 avec ELB en mode L4 et les instances EC2 autogérées en tant que L7 LB semblent les plus conformes à l'esprit de la plate-forme AWS, et où Amazon est le plus susceptible d'investir et de se développer plus tard. Ce serait probablement mon premier choix.

Jesper M
la source
1
J'adore donc l'approche n ° 1, c'est la direction que j'ai suivie, mais il y a encore des problèmes intéressants - dont le moindre n'est pas que ELB ne gère pas très bien tout un AZ en échec (quelque chose que nous avons déjà eu ). La `` solution '' facile, mais dégoûtante, consiste à configurer les haproxys derrière ELB pour traverser les AZ (peut-être avec un cluster de sauvegarde dans un autre AZ), donc si au moins un haproxy est en place dans chaque AZ, cela devrait aller. Mais cela ne fait que minimiser, pas éliminer le problème. Des idées sur ce problème?
Don MacAskill
@Don MacAskill: Je sais qu'AWS a connu quelques temps d'arrêt de service à grande échelle, mais faire mieux que la fiabilité AZ sur AWS est difficile. Passer à un fonctionnement multi-AZ du frontend pourrait facilement être la première étape vers un fonctionnement multi-AZ de la pile entière, et c'est toute une marmite de serpents ...
Jesper M
@Don MacAskill: Une option serait une résolution DNS géo-consciente comme DynDNS Dynect -> ELB + L7 LB dans un AZ, avec un autre ELB + L7 en veille à chaud dans un autre AZ. (En plus d'être géo-conscient, Dynect a également quelques contrôles de santé.) DynDNS a un excellent bilan de disponibilité, mais même ainsi, l'ajout de DNS géo-conscient est un autre SPOF. Je ne sais pas si l'équilibrage de charge Dynect + dans 2 AZ a une meilleure disponibilité à long terme qu'un seul AWS AZ. Voir ceci pour un aperçu de ce que je veux dire, sans les bases de données multi-AZ: dev.bizo.com/2010/05/improving-global-application.html
Jesper M
@Don MacAskill: Juste une dernière chose - gardez à l'esprit qu'une seule instance ELB peut s'étendre sur plusieurs AZ. Il ne peut pas s'étendre sur les régions EC2 . Mais si l'utilisation d'ELB à L7 LB dans deux AZ dans la même région est acceptable, ce serait de loin la plus simple ... Vous avez écrit "ELB ne gère pas très bien un AZ entier", peut-être que vous en savez déjà plus que Je fais.
Jesper M
Oui, si un ELB s'étend sur plusieurs AZ et a une sorte d'échec où il ne peut accéder à aucun des nœuds principaux dans un AZ (ils sont surchargés, en panne, retournant 503, peu importe), les utilisateurs finaux voient ces erreurs - ce n'est pas le cas '' t réacheminer vers les autres AZ. J'espère que c'est prévu, mais cela nous a déjà mordu une fois.
Don MacAskill
2

Si vous ne faites pas de sessions persistantes, ou si vous utilisez le style tomcat / apache (ajoutez l'ID du nœud à l'ID de session, par opposition au stockage de l'état dans le LB), j'utiliserais ELB devant un groupe de haproxies. ELB a un contrôle de santé intégré, vous pouvez donc le faire surveiller les haproxys et en retirer tous ceux de la piscine. Beaucoup moins à configurer que le basculement de pulsation.

En ce qui concerne la propagation des changements, je n'ai pas de bonne réponse. Puppet est idéal pour la configuration initiale et la mise en œuvre des modifications, mais pour ajouter / supprimer des nœuds, vous avez tendance à vouloir une réponse plus rapide que son intervalle d'interrogation de 30 minutes.

Ben Jencks
la source
1
C'est une bonne solution (et une bonne question!) Vous pouvez utiliser Amazon SNS pour propager les modifications de configuration de manière poussée. Vous avez besoin d'un système de notification pour ajouter / supprimer des nœuds de la configuration haproxy.
Rafiq Maniar
Une autre option pour gérer les serveurs backend (ceux vers lesquels haproxy est redirigé) consiste à demander à chaque serveur backend d'envoyer soit tous les haproxies, soit un serveur de configuration, un enregistrement périodique (30 secondes environ). Si quelqu'un meurt, il est rapidement non enregistré (et haproxy devrait le remarquer de toute façon); si un nouveau apparaît, il est automatiquement mis en rotation. C'est apparemment ce que fait Netflix.
Ben Jencks
1

Je ne l'ai pas utilisé moi-même mais j'ai vu beaucoup de gens mentionner l'utilisation de marionnettes pour gérer ce genre de problèmes sur EC2

JamesRyan
la source
Oui, Puppet sur EC2 rend la gestion d'un cluster assez simple. Créez simplement une micro-instance et utilisez-la comme votre marionnettiste.
Tom O'Connor
1
Nous utilisons des marionnettes dans nos centres de données, mais nous n'avons pas encore essayé EC2. La marionnette est-elle compatible avec EC2 d'une manière ou d'une autre, de telle sorte qu'elle puisse trouver des nœuds en utilisant des instances ec2-describe-instances ou quelque chose, et configurer / reconfigurer automatiquement en fonction de cette sortie? Et comment gérerais-tu que le marionnettiste s'en aille soudainement?
Don MacAskill
Pourquoi cela disparaîtrait-il soudainement?
Tom O'Connor
Il n'est pas compatible avec EC2, mais vous pouvez le configurer pour que les nouveaux nœuds soient marqués pour signature lorsque vous les démarrez et utilisez un script de nœuds externes pour les décrire. J'ai écrit du python pour le faire avec SimpleDB (nœuds externes) et SQS (file d'attente de demandes de signature pour de nouveaux nœuds); un développeur ubuntu a écrit des scripts en utilisant S3: ubuntumathiaz.wordpress.com/2010/04/07/…
Ben Jencks
Si le marionnettiste s'en va soudainement, il ne lance tout simplement pas le manifeste, c'est-à-dire qu'il laisse les nœuds dans l'état dans lequel ils se trouvent.
Ben Jencks