gratis - ¿Cómo configurar el equilibrio de carga global utilizando Digital Ocean DNS y Nginx?
digitalocean web hosting (4)
ACTUALIZACIÓN: consulte la respuesta que he proporcionado a continuación para la solución que finalmente configuré en AWS.
Actualmente estoy experimentando con metodologías sobre cómo implementar mejor una capa de equilibrio de carga global para mis servidores de aplicaciones en Digital Ocean y todavía quedan algunas piezas por confeccionar.
La meta
Ofrezco un servicio altamente disponible a mis usuarios mediante el enrutamiento de todas las conexiones al "cluster" de servidores más cercano en SFO, NYC, LON y, eventualmente, en Singapur.
Además, eventualmente me gustaría automatizar el mantenimiento de esto al escribir un daemon que pueda monitorear, escalar y curar cualquiera de los servidores en el sistema. O combinaré varios servicios para lograr los mismos objetivos de automatización. Primero necesito descubrir cómo hacerlo manualmente.
La pila
- Ubuntu 14.04
- Nginx 1.4.6
- node.js
- MongoDB de Compose.io (anteriormente MongoHQ)
Desglose del dominio global
Una vez que arregle todo, mi dominio se vería así:
**GLOBAL**
global-balancing-1.myapp.com
global-balancing-2.myapp.com
global-balancing-3.myapp.com
**NYC**
nyc-load-balancing-1.myapp.com
nyc-load-balancing-2.myapp.com
nyc-load-balancing-3.myapp.com
nyc-app-1.myapp.com
nyc-app-2.myapp.com
nyc-app-3.myapp.com
nyc-api-1.myapp.com
nyc-api-2.myapp.com
nyc-api-3.myapp.com
**SFO**
sfo-load-balancing-1.myapp.com
sfo-load-balancing-2.myapp.com
sfo-load-balancing-3.myapp.com
sfo-app-1.myapp.com
sfo-app-2.myapp.com
sfo-app-3.myapp.com
sfo-api-1.myapp.com
sfo-api-2.myapp.com
sfo-api-3.myapp.com
**LON**
lon-load-balancing-1.myapp.com
lon-load-balancing-2.myapp.com
lon-load-balancing-3.myapp.com
lon-app-1.myapp.com
lon-app-2.myapp.com
lon-app-3.myapp.com
lon-api-1.myapp.com
lon-api-2.myapp.com
lon-api-3.myapp.com
Y luego, si hay una tensión en una capa determinada, en cualquier región dada, puedo nyc-app-4.myapp.com
una nueva gota para ayudar: nyc-app-4.myapp.com
, lon-load-balancing-5.myapp.com
, etc ...
Metodología de trabajo actual
Un (mínimo) trío de servidores de
global-balancing
recibe todo el tráfico. Estos servidores sonDNS Round-Robin
balanceados como se ilustra en este artículo (francamente confuso): Cómo configurar DNS Round-Robin Load Balancing .Usando el Módulo GeoIP Nginx y los datos MaxMind GeoIP, el origen de cualquier solicitud dada se determina hasta el
$geoip_city_continent_code
.La capa de
global-balancing
enruta la solicitud al servidorleast connected
en la capa deload-balancing
del clúster apropiado:nyc-load-balancing-1
sfo-load-balancing-3
nyc-load-balancing-1
,sfo-load-balancing-3
,lon-load-balancing-2
, etc. .. Esta capa también es un (mínimo) trío de gotitas.La capa de
load-balancing
regional enruta la solicitud al servidorleast connected
en la aplicación o capa api:nyc-app-2
,sfo-api-1
,lon-api-3
, etc ...
Los detalles del Nginx kung-fu se pueden encontrar en este tutorial: Villiage Idiot: configuración de Nginx con GSLB / Reverse Proxy en AWS . Más información general sobre el equilibrio de carga Nginx está disponible here y here .
Preguntas
¿Dónde pongo los servidores de global-balancing
?
Me parece extraño que los ponga o todos en un solo lugar, o que extienda esa capa por todo el mundo tampoco. Digamos, por ejemplo, los puse todos en NYC. Entonces alguien de Francia golpea mi dominio. La solicitud iría de Francia a NYC y luego se enviaría a LON. O si pongo uno de cada uno en SFO, NYC y LON, ¿no es posible que un usuario de Toronto (Parkdale, represent) envíe una solicitud que termine en LON solo para enviarla a Nueva York?
¿Las solicitudes posteriores se enrutan a la misma IP?
Como en, si un usuario de Toronto envía una solicitud que la capa de global-balancing
determina que debe ir a Nueva York, ¿la próxima solicitud de ese origen va directamente a Nueva York, o es todavía suerte del sorteo que golpeará al más cercano servidor de global-balancing
(NYC en este caso).
¿Qué hay de las sesiones?
Configuré Nginx
para usar ip_hash; directiva, por lo que dirigirá al usuario a la misma app
o punto final de api
(un proceso de nodo, en mi caso), pero ¿cómo lo afectará el equilibrio global, si es que lo hace?
Cualquier ejemplo de DNS?
No soy exactamente un experto en DNS (actualmente estoy tratando de descubrir por qué mis registros CNAME no se están resolviendo), pero soy un estudio rápido cuando se proporciona un ejemplo sólido. ¿Alguien ha realizado este proceso anteriormente y puede proporcionar una muestra de cómo se ven los registros DNS para una instalación exitosa?
¿Qué pasa con SSL / TLS?
¿Necesitaría un certificado para cada servidor o solo para los tres servidores de global-balancing
ya que esa es la única puerta de enlace pública?
Si lees todo esto, entonces recompénsate con un pastelito. Gracias de antemano por cualquier ayuda.
El objetivo: ofrecer un servicio altamente disponible a mis usuarios mediante el enrutamiento de todas las conexiones al "cluster" de servidores más cercano en SFO, NYC, LON y, eventualmente, en Singapur.
La capa de equilibrio global luego enruta la solicitud al servidor conectado al menos ...
Si estoy leyendo su configuración correctamente, en realidad está procesando desde sus balanceadores globales a los balanceadores en cada región. Esto no cumple su objetivo de enrutar a los usuarios a la región más cercana.
Hay tres formas que conozco para obtener lo que estás buscando:
30x Redirigir
Sus equilibradores globales reciben la solicitud HTTP y luego la redireccionan a un grupo de servidores en o cerca de la región de la que cree que proviene la solicitud, en función de la dirección IP. Esto suena como lo que estabas tratando de configurar. Este método tiene efectos secundarios para algunas aplicaciones y también aumenta el tiempo que le toma a un usuario obtener datos, ya que está agregando una tonelada de sobrecarga. Esto solo tiene sentido si los recursos a los que redirige son muy grandes, y el clúster regional local podrá prestar servicios de manera mucho más eficiente.Anycast (aprovechando el enrutamiento BGP)
Esto es lo que usan los grandes jugadores como Akamai para su CDN. Básicamente, hay varios servidores en Internet con la misma dirección IP enrutable. Supongamos que tengo servidores en varias regiones y que tienen la dirección IP de 192.0.2.1. Si estoy en los Estados Unidos y trato de conectarme a 192.0.2.1, y alguien está en Europa que intenta conectarse a 192.0.2.1, es probable que nos dirijan al servidor más cercano. Utiliza el enrutamiento de Internet para encontrar la mejor ruta (en función de las condiciones de la red) para el tráfico. Lamentablemente, no puedes usar este método. Necesita su propio número AS y hardware físico. Si encuentras un proveedor de VPS que te permite tener un pedazo de su bloque Anycast, ¡házmelo saber!Geo-DNS
Hay algunos proveedores de DNS que ofrecen un servicio que a menudo se comercializa como "Geo-DNS". Tienen un grupo de servidores DNS alojados en direcciones de difusión ilimitada que pueden enrutar el tráfico a los servidores más cercanos. Si un cliente consulta un servidor DNS europeo, debe devolver la dirección de los servidores de la región europea, frente a algunos en otras regiones. Hay muchas variaciones en los servicios Geo DNS. Otros simplemente mantienen una base de datos de geo-IP y devuelven el servidor para la región que piensan que está más cerca, al igual que el método de redirección, pero para DNS antes de que se realice la solicitud HTTP. Esta suele ser la buena opción, por el precio y la facilidad de uso.
¿Las solicitudes posteriores se enrutan a la misma IP?
Muchos equilibradores de carga tienen una opción "pegajosa" que dice que las solicitudes de la misma dirección de red deben enrutarse al mismo servidor final (siempre que el servidor final aún esté funcionando).
¿Qué hay de las sesiones?
Esto es exactamente por lo que querrías esa pegajosidad. Cuando se trata de datos de sesión, tendrá que encontrar la manera de mantener todos sus servidores actualizados. Siendo realistas, esto no siempre está garantizado. Cómo lo manejas depende de tu aplicación. ¿Puede mantener una instancia de Redis o lo que sea que haya para todos sus servidores que lleguen de manera confiable desde todo el mundo? ¿Realmente necesita los datos de la sesión en cada región? ¿O puede hacer que sus servidores de aplicaciones principales manejen los datos de sesión en una ubicación?
Cualquier ejemplo de DNS?
Publique preguntas separadas para estos. La "configuración exitosa" de todos se ve de manera diferente.
¿Qué pasa con SSL / TLS?
Si está transmitiendo datos, solo sus equilibradores globales deben manejar HTTPS. Si está redirigiendo, entonces todos los servidores deben manejarlo.
Digital Ocean ahora es compatible con Load Balancing of servers. ¡Es extremadamente fácil de configurar y funciona genial! Le ahorra tener que agregar componentes innecesarios como nginx (si solo desea usar para balanceo de carga).
Estábamos teniendo problemas con la carga de archivos SSL con nginx en un servidor digital marino, sin embargo, desde la actualización de Ocean Digital, hemos eliminado nginx y ahora utilizamos la función de equilibrio de carga de Digital Ocean y ¡funciona como lo necesitamos!
Puede usar Anycast para su servicio web de forma gratuita si utiliza el plan gratuito Cloudflare.
Una solución de trabajo
Durante los últimos meses, he tenido un viaje desenfrenado descubriendo toda la configuración de Global-HA. Toneladas de diversión y finalmente me conformé con una plataforma que funciona muy bien, y no se parece en nada a la descrita en la pregunta anterior.
Todavía planeo escribir esto en forma de tutorial, pero el tiempo es escaso ya que me dirijo al sprint final para lanzar mi aplicación a principios del próximo año, así que aquí hay un resumen rápido de la plataforma de trabajo con la que terminé.
Visión de conjunto
Terminé moviendo todo mi despliegue a AWS. Me encanta Digital Ocean, pero la realidad es que AWS está a años luz de ellos (y todo el mundo, realmente) cuando se trata de los servicios ofrecidos bajo un mismo techo. Mis gastos mensuales aumentaron ligeramente, pero una vez que terminé de ajustar y agilizar, terminé con una solución que cuesta aproximadamente $ 75 / mes por región para la implementación más básica (2 instancias detrás de un ELB). Y una nueva región puede activarse y desplegarse en aproximadamente 30 minutos.
Equilibrio global
Rápidamente descubrí (gracias a la respuesta de @ Brad anterior) que tratar de hacer girar mi propia capa de DNS de equilibrio global es una locura. Fue muy divertido descifrar cómo funciona una capa como esta, pero a menos que subiera a un avión y me raspara los nudillos instalando equipos por valor de millones de dólares en todo el mundo, no iba a ser posible rodar mi propio.
Cuando finalmente descubrí lo que estaba buscando, encontré a mi nuevo mejor amigo: AWS Route 53 . Ofrece una sólida red DNS con alrededor de 50 nodos en todo el mundo y la capacidad de hacer algunos trucos de enrutamiento realmente geniales como enrutamiento basado en ubicación, enrutamiento basado en latencia (que es algo increíble) y registros de AWS Alias que enrutan el tráfico ''automágicamente''. a otros servicios de AWS que utilizará (como ELB para el equilibrio de carga).
Terminé usando un enrutamiento basado en latencia que dirige el tráfico global al equilibrador de carga elástico regional más cercano, que tiene un grupo de escala automática asociado a él en cualquier región determinada.
Dejaré que usted haga su tarea con los otros proveedores: www.f5.com , www.dyn.com , www.akamai.com , www.dnsmadeeasy.com . Dependiendo de sus necesidades, puede haber una solución mejor para usted, pero esto funciona muy bien para mí.
Red de entrega de contenidos
La ruta 53 se integra muy bien con AWS Cloudfront . Configuré un depósito S3 que estoy usando para almacenar todos los archivos de medios estáticos que cargarán mis usuarios, y configuré una distribución de Cloudfront para el origen de mi cubo de S3 media.myapp.com
. Hay otros proveedores de CDN, así que haz tus compras. Pero Cloudfront recibe críticas muy buenas y es muy fácil de configurar.
Equilibrio de carga y terminación de SSL
Actualmente estoy usando AWS Elastic Load Balancer para equilibrar la carga entre las instancias de mi aplicación, que viven en un Grupo de escalamiento automático . La solicitud primero es recibida por ELB, en cuyo punto SSL finaliza y la solicitud se transfiere a una instancia en el Grupo de escalamiento automático.
NOTA: Una advertencia importante para ELB es que, irónicamente, no maneja muy bien los picos masivos. Puede tardar hasta 15 minutos para que un ELB desencadene un evento de ampliación, mientras tanto, crea 500 / timeouts. Se supone que un aumento constante y constante del tráfico se maneja bastante bien, pero si te golpean con una espiga puede fallar. Si sabe que va a recibir un golpe, puede ''llamar con anticipación'' y AWS calentará su ELB para usted, lo cual es bastante ridículo y antipatrón para la esencia de AWS, pero imagino que están trabajando en o ignorarlo porque realmente no es un gran problema. Siempre puede girar su propia capa de balanceo de carga HAProxy o Nginx si ELB no funciona para usted.
Grupo de escalado automático
Cada región tiene un ASG que está programado para escalar cuando la carga pasa una determinada métrica:
IF CPU > 90% FOR 5 MINUTES: SCALEUP
IF CPU < 70% FOR 5 MINUTES: SCALEDN
Todavía no he puesto el combo ELB / ASG a su ritmo. Eso está un poco más abajo en mi lista de cosas por hacer, pero sé que hay muchos otros que usan esta configuración y no parece tener problemas importantes de rendimiento.
La configuración para un Grupo de escalamiento automático es un poco intrincada en mi opinión. En realidad, es un proceso de tres pasos:
- Crea un AMI configurado a tu gusto.
- Cree una configuración de lanzamiento que use la AMI que ha creado.
- Cree un Grupo de escalamiento automático que use la Configuración de lanzamiento que ha creado para determinar qué AMI y tipo de instancia lanzar para cualquier evento SCALEUP dado.
Para manejar la implementación de la configuración y la aplicación cuando se inicia cualquier instancia, utiliza el campo "Datos del usuario" para ingresar una secuencia de comandos que se ejecutará una vez que se inicie cada instancia determinada. Esta es posiblemente la peor nomenclatura en la historia del tiempo. Cómo "Datos de usuario" describe una secuencia de comandos de inicio que solo el autor conoce. De todos modos, ahí es donde pegas el script que maneja todos tus apt-get, mkdirs, git clones, etc.
Instancias y equilibrio interno
También agregué una ''capa de equilibrio interna'' adicional usando Nginx que me permite ''empaquetar'' todas mis aplicaciones Node.js (app.myapp.com, api.myapp.com, mobile.myapp.com, www. myapp.com, etc.myapp.com) en cada instancia. Cuando una instancia recibe una solicitud que se le pasa desde ELB, Nginx maneja el enrutamiento de la solicitud al puerto Node.js correcto para cualquier aplicación determinada. Algo así como una contenedorización de pobres. Esto tiene el beneficio adicional de que cada vez que una de mis aplicaciones necesita hablar con la otra (como cuando la app.
necesita enviar una solicitud a la api.
), se hace a través de localhost:XXXX
lugar de tener que salir por la red de AWS, o el internet mismo.
Esta configuración también maximiza el uso de mis recursos al eliminar cualquier infraestructura inactiva si la capa de aplicaciones que aloja pasa a recibir tráfico ligero. También obvia la necesidad de tener un combo ELB / ASG para cada aplicación, ahorrando más efectivo.
No hay errores ni advertencias con los que me haya topado utilizar este tipo de configuración, pero hay una solución alternativa que debe implementarse en relación con la comprobación de la salud (ver más abajo).
También hay un beneficio agradable en el sentido de que todas las instancias tienen un rol de IAM, lo que significa que sus credenciales de AWS están ''incorporadas'' en cada instancia al momento del nacimiento y se puede acceder a ellas a través de sus ENV vars. Y AWS ''automágicamente'' rota sus créditos por usted. Muy seguro, muy bueno.
Chequeos de salud
Si sigue la ruta de la configuración anterior, empaquetando todas sus aplicaciones en una sola caja y ejecutando un equilibrador de carga interno, entonces debe crear una pequeña utilidad para manejar las verificaciones de estado de ELB . Lo que hice fue crear una aplicación adicional llamada ping.myapp.com. Y luego configuré mis verificaciones de salud ELB para enviar comprobaciones de estado al puerto en el que se ejecuta mi aplicación ping, así:
Ping Protocol: HTTP
Ping Port: XXXX
Ping Path: /ping
Esto envía todas las comprobaciones de estado a mi pequeño ping helper, que a su vez golpea localhost:XXXX/ping
en todas las aplicaciones que residen en la instancia. Si todos devuelven una respuesta de 200, mi aplicación ping luego devuelve una respuesta de 200 a la verificación de salud ELB y las instancias se ponen a vivir otros 30 segundos.
NOTA: No use las verificaciones de estado de escalamiento automático si está utilizando un ELB. Use los controles de salud ELB. Es un poco confuso, pensé que eran lo mismo, no lo son. Usted tiene la opción de habilitar uno u otro. Ve con ELB.
La capa de datos
Una cosa que brilla por su ausencia en mi configuración es la capa de datos. Uso Compose.io como mi proveedor de capa de datos administrada y despliegue en AWS, por lo que tengo una latencia muy baja entre mis capas de aplicaciones y mi capa de datos. Hice una investigación preliminar sobre cómo distribuir mi capa de datos globalmente y descubrí que es muy compleja, y muy costosa, así que la eliminé de mi lista como un problema que aún no necesita ser resuelto. El peor caso es que voy a ejecutar mi capa de datos solo en el este de EE. UU. Y reforzar el hardware. Esto no es lo peor en el mundo ya que mi API es estrictamente datos JSON en el cable por lo que la respuesta promedio es relativamente pequeña. Pero puedo ver que esto se convierte en un cuello de botella a gran escala, a escala mundial, si alguna vez llego allí. Si alguien tiene alguna entrada en esta capa, me encantaría escuchar lo que tiene que decir.
Ta-Da!
Alta disponibilidad global en un presupuesto de cerveza. Solo me llevó 6 meses averiguarlo.
Me encanta escuchar las opiniones o ideas de cualquier persona que lea esto.