¿Cómo puedo implementar un clúster haproxy escalable y confiable en Amazon EC2?

25

Necesitamos una funcionalidad más avanzada que la que proporciona ELB (principalmente inspección L7), pero no es obvio cómo manejar cosas como los latidos del corazón y la alta disponibilidad con algo como haproxy usando EC2. Existe una alta probabilidad de que necesitemos 3 o más nodos haproxy en el clúster, por lo que un simple latido entre dos nodos no funcionará.

Parece que tener una capa de latidos delante de los nodos haproxy sería el camino a seguir, posiblemente usando IPVS, pero manejando los cambios de configuración a medida que cambia el clúster EC2 (ya sea a través de cambios intencionales, como expansión o no intencionales, como perder un Nodo EC2) parece no trivial.

Preferiblemente, la solución abarcaría al menos dos zonas de disponibilidad.

En respuesta a Qs: No, las sesiones no son pegajosas. Y sí, necesitaremos SSL, pero eso en teoría podría ser manejado por otra configuración completamente: podemos dirigir el tráfico SSL a una ubicación diferente que el tráfico que no es SSL.

Don MacAskill
fuente
Estoy investigando cómo hacer implementaciones canarias con un porcentaje de tráfico que aumenta lentamente a la nueva versión del software, y tengo mucha curiosidad sobre dónde terminaste con esto. ¿Terminaste probando alguna de las sugerencias de Jesper?
Iain

Respuestas:

14

OK, nunca he creado una solución de equilibrio de carga de AWS con tráfico en los niveles de SmugMug, pero solo pensando en la teoría y los servicios de AWS, se me ocurren un par de ideas.

A la pregunta original le faltan algunas cosas que tienden a afectar el diseño de equilibrio de carga:

  1. ¿Sesiones pegajosas o no? Es muy preferible no usar una sesión fija, y simplemente dejar que todos los equilibradores de carga (LB) usen round robin (RR) o selección aleatoria de back-end. Las selecciones de RR o de fondo aleatorio son simples, escalables y proporcionan una distribución de carga uniforme en todas las circunstancias.
  2. SSL o no? Si SSL está en uso o no, y sobre qué porcentaje de solicitudes, generalmente tiene un impacto en el diseño de equilibrio de carga. A menudo es preferible finalizar SSL lo antes posible, para simplificar el manejo de certificados y mantener la carga de CPU SSL lejos de los servidores de aplicaciones web.

Respondo desde la perspectiva de cómo mantener la capa de equilibrio de carga en sí misma altamente disponible. Mantener los servidores de aplicaciones HA se acaba de hacer con las comprobaciones de estado integradas en sus equilibradores de carga L7.

OK, un par de ideas que deberían funcionar:

1) "La forma AWS":

  • La primera capa, en el frente, usa ELB en modo L4 (TCP / IP).
  • Segunda capa, use instancias EC2 con su balanceador de carga L7 de elección (nginx, HAProxy, Apache, etc.).

Beneficios / idea: los equilibradores de carga L7 pueden ser AMI EC2 bastante simples, todos clonados desde el mismo AMI y utilizando la misma configuración. Por lo tanto, las herramientas de Amazon pueden manejar todas las necesidades de HA: ELB supervisa los equilibradores de carga L7. Si un L7 LB muere o deja de responder, ELB y Cloudwatch juntos generan una nueva instancia automáticamente y la llevan al grupo ELB.

2) "El round robin de DNS con forma de monitoreo:"

  • Use la operación de round robin de DNS básica para obtener una distribución de carga de grano grueso en un par de direcciones IP. Digamos que publica 3 direcciones IP para su sitio.
  • Cada una de estas 3 IP es una dirección IP elástica de AWS (EIA), vinculada a una instancia EC2, con un equilibrador de carga L7 de su elección.
  • Si un EC2 L7 LB muere, un agente de usuario compatible (navegador) debería usar una de las otras IP en su lugar.
  • Configurar un servidor de monitoreo externo. Monitoree cada uno de los 3 EIP. Si uno deja de responder, use las herramientas de línea de comandos de AWS y algunas secuencias de comandos para mover el EIP a otra instancia de EC2.

Beneficios / idea: los agentes de usuario conformes deberían cambiar automáticamente a otra dirección IP si uno deja de responder. Por lo tanto, en el caso de una falla, solo 1/3 de sus usuarios deberían verse afectados, y la mayoría de ellos no deberían notar nada, ya que su UA falla silenciosamente a otra IP. Y su caja de monitoreo externo notará que un EIP no responde y rectificará la situación en un par de minutos.

3) RR DNS a pares de servidores HA:

Básicamente, esta es la sugerencia de Don de un latido simple entre un par de servidores, pero simplificado para múltiples direcciones IP.

  • Con DNS RR, publique varias direcciones IP para el servicio. Siguiendo el ejemplo anterior, digamos que publica 3 IP.
  • Cada una de estas IP va a un par de servidores EC2, por lo que 6 instancias EC2 en total.
  • Cada uno de estos pares utiliza Heartbeat u otra solución HA junto con las herramientas de AWS para mantener 1 dirección IP activa, en una configuración activa / pasiva.
  • Cada instancia EC2 tiene instalado su balanceador de carga L7 de elección.

Beneficios / idea: en el entorno completamente virtualizado de AWS, en realidad no es tan fácil razonar sobre los servicios L4 y los modos de conmutación por error. Al simplificar a un par de servidores idénticos que mantienen viva solo una dirección IP, es más fácil razonar y probar.

Conclusión: Nuevamente, en realidad no he probado nada de esto en producción. Solo desde mi instinto, la opción uno con ELB en modo L4 y las instancias de EC2 autogestionadas como L7 LBs parecen estar más alineadas con el espíritu de la plataforma AWS, y donde es más probable que Amazon invierta y se expanda más adelante. Probablemente esta sea mi primera opción.

Jesper M
fuente
1
Así que me encanta el enfoque n. ° 1, esa es la dirección en la que me he estado inclinando, pero todavía hay algunas trampas interesantes, entre las que se encuentra que ELB no maneja muy bien todo un AZ que falla (algo que ya ha sucedido) ) La 'solución' fácil, pero asquerosa, es tener las haproxies detrás de ELB configuradas para cruzar AZ (tal vez con un clúster de respaldo en otra AZ), por lo que si al menos un haproxy está activo en cada AZ, deberíamos estar bien. Pero eso solo imita, no elimina el problema. ¿Alguna idea sobre este problema?
Don MacAskill
@Don MacAskill: Sé que AWS ha tenido un par de tiempos de inactividad de servicio a gran escala, pero es mucho mejor que la confiabilidad de AZ en AWS. Pasar a la operación multi-AZ de la interfaz podría ser fácilmente el primer paso hacia la operación multi-AZ de toda la pila, y eso es todo un hervidor de serpientes ...
Jesper M
@Don MacAskill: Una opción sería la resolución DNS con reconocimiento geográfico como DynDNS Dynect -> ELB + L7 LB dentro de una AZ, con otra ELB + L7 en espera activa en otra AZ. (Además de tener conocimiento geográfico, Dynect también tiene algunas comprobaciones de estado). DynDNS tiene un excelente historial de tiempo de actividad, pero aun así, agregar DNS con reconocimiento geográfico es otro SPOF. No me queda claro si el equilibrio de carga Dynect + en 2 AZ tiene un mejor tiempo de funcionamiento a largo plazo que un solo AWS AZ. Vea esto para obtener una descripción general de lo que quiero decir, sin las bases de datos multi-AZ: dev.bizo.com/2010/05/improving-global-application.html
Jesper M
@Don MacAskill: Solo una última cosa: tenga en cuenta que una sola instancia de ELB puede abarcar múltiples AZ. No puede abarcar regiones EC2 . Pero si el uso de ELB para L7 LB's en dos AZ dentro de la misma región es aceptable, este sería, con mucho, el más simple ... Usted escribió "ELB no maneja muy bien todo un AZ que falla", tal vez ya sepa más que Hago.
Jesper M
Sí, si un ELB abarca múltiples AZ y tiene algún tipo de falla donde no puede llegar a ninguno de los nodos de fondo en una AZ (están sobrecargados, caídos, devolviendo 503, lo que sea), los usuarios finales ven esos errores, no t Vuelva a enrutar a las otras AZ. Espero que eso esté planeado, pero ya nos ha mordido una vez.
Don MacAskill
2

Si no está haciendo sesiones fijas, o si está usando el estilo tomcat / apache (agregar ID de nodo a sessionid, en lugar de almacenar el estado en el LB), entonces usaría ELB frente a un grupo de haproxies. ELB tiene una verificación de salud incorporada, por lo que puede hacer que monitoree las haproxies y elimine las que estén fuera de la piscina. Hay mucho menos que configurar que la conmutación por error de latidos.

En cuanto a la propagación de cambios, no tengo una gran respuesta. Puppet es ideal para la configuración inicial y la implementación de cambios, pero para agregar / eliminar nodos tiende a querer una respuesta más rápida que su intervalo de sondeo de 30 minutos.

Ben Jencks
fuente
1
Esa es una buena solución (¡y una buena pregunta!) Puede usar Amazon SNS para propagar los cambios de configuración de forma automática. Necesita un sistema de notificación para agregar / eliminar nodos de la configuración de haproxy.
Rafiq Maniar
Otra opción para administrar servidores de back-end (a los que se reenvía haproxy) es hacer que cada servidor de back-end envíe todos los haproxies o un servidor de configuración, un registro periódico (aproximadamente 30 segundos). Si uno muere, no se registra rápidamente (y el haproxy debería darse cuenta de todos modos); Si aparece uno nuevo, se pone automáticamente en rotación. Esto es aparentemente lo que hace Netflix.
Ben Jencks
1

No lo he usado yo mismo, pero he visto a muchas personas mencionar el uso de títeres para manejar este tipo de problemas en EC2

JamesRyan
fuente
Sí, Puppet en EC2 hace que administrar un clúster sea bastante sencillo. Solo crea una micro instancia y úsala como tu puppetmaster.
Tom O'Connor
1
Usamos puppet en nuestros centros de datos, pero aún no lo hemos probado en EC2. ¿Puppet es consciente de EC2 de alguna manera, de modo que pueda encontrar nodos utilizando ec2-describe-Instances o algo así, y configurar / reconfigurar automáticamente en función de esa salida? ¿Y cómo manejarías que el titiritero se fuera de repente?
Don MacAskill
¿Por qué desaparecería de repente?
Tom O'Connor
No es compatible con EC2, pero puede configurarlo para que se marquen nuevos nodos para firmar cuando los inicie, y use un script de nodos externo para describirlos. Escribí algo de python para hacer esto con SimpleDB (nodos externos) y SQS (cola de solicitudes de firma para nuevos nodos); un desarrollador de ubuntu escribió scripts usando S3: ubuntumathiaz.wordpress.com/2010/04/07/…
Ben Jencks
Si el titiritero desaparece de repente, simplemente no se ejecuta el manifiesto, es decir, que deja a los nodos en cualquier estado que se encuentran.
Ben Jencks