Comment configurer l’équilibrage de charge global en utilisant Digital Ocean DNS et Nginx?

MISE À JOUR: Voir la réponse que j’ai fournie ci-dessous pour la solution que j’ai finalement installée sur AWS.

J’expérimente actuellement des méthodologies sur la meilleure manière d’implémenter une couche globale d’équilibrage de la charge pour mes serveurs d’applications sur Digital Ocean et il rest quelques pièces à assembler.

Le but

Offrez un service hautement disponible à mes utilisateurs en acheminant toutes les connexions vers le «cluster» de serveurs le plus proche, à savoir SFO, NYC, LON et éventuellement Singapour.

De plus, je souhaiterais éventuellement automatiser la maintenance en écrivant un démon capable de surveiller, de mettre à l’échelle et de soigner tous les serveurs du système. Ou je vais combiner différents services pour atteindre les mêmes objectives d’automatisation. Je dois d’abord comprendre comment le faire manuellement.

La stack

  1. Ubuntu 14.04
  2. Nginx 1.4.6
  3. node.js
  4. MongoDB de Compose.io (anciennement MongoHQ)

Répartition du domaine global

Une fois que tout est monté, mon domaine ressemblerait à ceci:

**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 

Et puis, s’il ya une contrainte sur une couche donnée, dans une région donnée, je peux simplement créer une nouvelle goutte pour aider: nyc-app-4.myapp.com , lon-load-balancing-5.myapp.com , etc…

Méthode de travail actuelle

  • Un sortingo (minimum) de serveurs d’ global-balancing reçoit tout le trafic. Ces serveurs sont équilibrés DNS Round-Robin comme illustré dans cet article (franchement déroutant): Comment configurer l’équilibrage de la charge de type Round-Robin DNS .

  • En utilisant le module GeoIP Nginx et les données GeoIP MaxMind, l’origine de toute requête donnée est déterminée jusqu’à $geoip_city_continent_code .

  • La couche d’ global-balancing achemine ensuite la demande vers le serveur le least connected sur la couche d’ load-balancing de charge du cluster approprié: nyc-load-balancing-1 , sfo-load-balancing-3 , lon-load-balancing-2 , etc. .. Cette couche est aussi un sortingo (minimum) de gouttelettes.

  • La couche d’ load-balancing régionale achemine ensuite la requête vers le serveur le least connected de la couche application ou api: nyc-app-2 , sfo-api-1 , lon-api-3 , etc.

Les détails du kung-fu de Nginx peuvent être trouvés dans ce tutoriel: Villiage Idiot: Configurer Nginx avec GSLB / Reverse Proxy sur AWS . Des informations plus générales sur l’équilibrage de charge Nginx sont disponibles ici et ici .

Des questions

Où puis-je mettre les serveurs d’ global-balancing ?

Il me semble étrange que je les mette tous au même endroit ou que je les diffuse dans le monde entier. Dis, par exemple, je les ai tous mis à New York. Alors quelqu’un de France frappe mon domaine. La demande irait de France à NYC, puis serait renvoyée à LON. Ou si je mets un de chacun dans SFO, NYC et LON, n’est-il pas encore possible qu’un utilisateur de Toronto (représentant Parkdale) puisse envoyer une demande qui finit par être envoyée à LON pour être renvoyée à NYC?

Les requêtes suivantes sont-elles acheminées vers la même adresse IP?

Comme dans, si un utilisateur de Toronto envoie une demande que la couche d’ global-balancing détermine devrait aller à NYC, la prochaine demande de cette origine va-t-elle directement à NYC, ou est-ce que le tirage au sort serveur d’ global-balancing (NYC dans ce cas).

Qu’en est-il des sessions?

J’ai configuré Nginx pour utiliser le ip_hash; directive donc il dirigera l’utilisateur vers le même point d’extrémité d’ app ou d’ api (un processus de nœud, dans mon cas) mais comment cet équilibrage global affectera-t-il cela, voire pas du tout?

Des exemples de DNS?

Je ne suis pas exactement un expert DNS (j’essaie actuellement de comprendre pourquoi mes enregistrements CNAME ne sont pas résolus), mais je suis une étude rapide lorsque vous en avez un exemple solide. Quelqu’un a-t-il déjà suivi ce processus et peut fournir un échantillon de ce à quoi ressemblent les enregistrements DNS pour une installation réussie?

Qu’en est-il de SSL / TLS?

Aurais-je besoin d’un certificate pour chaque serveur ou uniquement pour les trois serveurs d’ global-balancing donné que c’est la seule passerelle publique?

Si vous lisez tout cela, récompensez-vous avec un petit gâteau. Merci d’avance pour votre aide.

L’objective: offrir un service hautement disponible à mes utilisateurs en acheminant toutes les connexions vers le «cluster» de serveurs le plus proche, à savoir SFO, NYC, LON et, éventuellement, Singapour.

La couche d’équilibrage global achemine ensuite la requête vers le serveur le moins connecté …

Si je lis correctement votre configuration, vous passez directement de vos équilibreurs globaux aux équilibreurs de chaque région. Cela ne correspond pas à votre objective d’acheminer les utilisateurs vers la région la plus proche.

Il y a trois façons dont je sais pour obtenir ce que vous recherchez:

  1. 30x Redirect
    Vos équilibreurs globaux reçoivent la requête HTTP, puis la redirigent vers un groupe de serveurs situé dans la région ou près de la région qui, selon elle, provient de la demande, en fonction de l’adresse IP. Cela ressemble à ce que vous essayez de mettre en place. Cette méthode a des effets secondaires pour certaines applications et augmente également le temps nécessaire à l’utilisateur pour obtenir des données, car vous ajoutez une tonne de surcharge. Cela n’a de sens que si les ressources que vous redirigez sont très importantes et que le cluster régional local sera en mesure de servir beaucoup plus efficacement.

  2. Anycast (profitant du routage BGP)
    C’est ce que les grands acteurs comme Akamai utilisent pour leur CDN. Fondamentalement, il existe plusieurs serveurs sur Internet avec la même adresse IP routable. Supposons que j’ai des serveurs dans plusieurs régions et qu’ils aient l’adresse IP 192.0.2.1. Si je suis aux États-Unis et que je tente de me connecter à 192.0.2.1 et que quelqu’un en Europe essaie de se connecter à 192.0.2.1, il est probable que nous serons acheminés vers le serveur le plus proche. Cela utilise le routage propre à Internet pour trouver le meilleur chemin (basé sur les conditions du réseau) pour le trafic. Malheureusement, vous ne pouvez pas simplement utiliser cette méthode. Vous avez besoin de votre propre numéro AS et de votre matériel physique. Si vous trouvez un fournisseur de VPS qui vous permet d’avoir une partie de leur bloc Anycast, faites le moi savoir!

  3. Géo-DNS
    Certains fournisseurs de DNS proposent un service souvent commercialisé sous le nom de “Geo-DNS”. Ils ont un groupe de serveurs DNS hébergés sur des adresses anycast qui peuvent acheminer le trafic vers les serveurs les plus proches. Si un client interroge un serveur DNS européen, il doit renvoyer l’adresse de vos serveurs de région européenne par rapport à d’autres dans d’autres régions. Il existe de nombreuses variantes sur les services Geo DNS. D’autres maintiennent simplement une firebase database géo-IP et renvoient le serveur pour la région qu’ils considèrent plus proche, tout comme la méthode de redirection, mais pour DNS avant la requête HTTP. C’est généralement la bonne option, pour le prix et la facilité d’utilisation.

Les requêtes suivantes sont-elles acheminées vers la même adresse IP?

De nombreux équilibreurs de charge ont une option “stickiness” qui indique que les requêtes provenant de la même adresse réseau doivent être routées vers le même serveur d’extrémité (à condition que le serveur d’extrémité soit toujours opérationnel).

Qu’en est-il des sessions?

C’est exactement pour cela que vous voudriez cette viscosité. En ce qui concerne les données de session, vous devrez trouver un moyen de garder tous vos serveurs à jour. De manière réaliste, cela n’est pas toujours garanti. Comment vous le traitez dépend de votre application. Pouvez-vous garder une instance de Redis ou autre pour que tous vos serveurs soient accessibles de manière fiable dans le monde entier? Avez-vous vraiment besoin de ces données de session dans chaque région? Ou pouvez-vous que vos serveurs d’applications principaux traitent les données de session en un seul endroit?

Des exemples de DNS?

Postez des questions séparées pour ceux-ci. La “configuration réussie” de tout le monde est différente.

Qu’en est-il de SSL / TLS?

Si vous dépêchez des données, seuls vos équilibreurs globaux doivent gérer HTTPS. Si vous redirigez, tous les serveurs doivent le gérer.

Une solution de travail

J’ai eu une course folle au cours des derniers mois pour déterminer la configuration globale de Global-HA. Des tonnes de plaisir et je me suis finalement installé avec une plate-forme qui fonctionne très bien et qui ne ressemble en rien à celle décrite ci-dessus.

Je prévois toujours d’écrire cela sous forme de tutoriel, mais le temps est compté alors que je me dirige vers le sprint final pour lancer mon application au début de l’année prochaine, alors voici un aperçu du périphérique que j’ai utilisé.


Vue d’ensemble

J’ai fini par transférer tout mon déploiement sur AWS. J’aime Digital Ocean, mais la réalité est qu’AWS est en avance sur eux (et tout le monde, vraiment) en ce qui concerne les services offerts sous un même toit. Mes dépenses mensuelles ont légèrement augmenté, mais une fois que j’ai fini de peaufiner et de rationaliser, je me suis retrouvé avec une solution qui coûte environ 75 $ / mois par région pour le déploiement le plus élémentaire (2 instances derrière un ELB). Et une nouvelle région peut être créée et déployée en 30 minutes environ.


Équilibrage global

J’ai rapidement découvert (grâce à la réponse de @ Brad ci-dessus) que tenter de faire tourner ma propre couche DNS d’équilibrage global est insensé. Ce fut très amusant de voir comment une couche comme celle-ci fonctionne, mais à moins de monter dans un avion et de me gratter les doigts pour installer des millions de dollars d’équipements à travers le monde, il ne serait pas possible de rouler posséder.

Quand j’ai finalement compris ce que je cherchais, j’ai trouvé mon nouveau meilleur ami: AWS Route 53 . Il offre un réseau DNS robuste avec environ 50 nœuds globalement et la possibilité de réaliser des astuces de routage vraiment intéressantes comme le routage basé sur la localisation, le routage basé sur la latence (ce qui est plutôt génial) et AWS Alias ​​enregistre ce trafic à d’autres services AWS que vous utiliserez (comme ELB pour l’équilibrage de charge).

J’ai fini par utiliser un routage basé sur la latence qui dirige le trafic global vers le système Elastic Load Balancer le plus proche, auquel est associé un groupe Auto-Scaling dans une région donnée.

Je vous laisse le soin de faire vos devoirs sur les autres fournisseurs: http://www.f5.com , http://www.dyn.com , http://www.akamai.com , http://www.dnsmadeeasy.com . Selon vos besoins, il existe peut-être une meilleure solution pour vous, mais cela fonctionne très bien pour moi.


Réseau de diffusion de contenu

Route 53 s’intègre très bien avec AWS Cloudfront . Je configure un compartiment S3 que j’utilise pour stocker tous les fichiers multimédias statiques que mes utilisateurs vont télécharger, et j’ai configuré une dissortingbution Cloudfront sur la source depuis mon media.myapp.com S3. Il y a d’autres fournisseurs de CDN, alors faites vos courses. Mais Cloudfront obtient de bonnes critiques et il est facile à configurer.


Équilibrage de charge et terminaison SSL

J’utilise actuellement AWS Elastic Load Balancer pour équilibrer la charge entre mes instances d’application, qui vivent dans un groupe de mise à l’échelle automatique . La requête est d’abord reçue par ELB. À ce stade, SSL est terminé et la demande est transmise à une instance du groupe Auto-Scaling.

NOTE: Une mise en garde géante pour ELB est que, ironiquement, elle ne gère pas très bien les pics massifs. Cela peut prendre jusqu’à 15 minutes pour qu’un ELB déclenche un événement de montée en charge pour lui-même, créant 500 / timeouts entre-temps. Une augmentation constante et constante du trafic est censée être assez bien gérée, mais si vous êtes touché par un pic, cela peut vous faire échouer. Si vous savez que vous allez être touché, vous pouvez «appeler à l’avance» et AWS mettra votre ELB à l’écoute pour vous, ce qui est assez ridicule et anti-modèle pour l’essence même d’AWS, mais je ou l’ignorer parce que ce n’est pas vraiment un gros problème. Vous pouvez toujours créer votre propre couche d’équilibrage de charge HAProxy ou Nginx si ELB ne fonctionne pas pour vous.


Groupe de mise à l’échelle automatique

Chaque région a un ASG programmé pour évoluer lorsque la charge passe une certaine mésortingque:

 IF CPU > 90% FOR 5 MINUTES: SCALEUP IF CPU < 70% FOR 5 MINUTES: SCALEDN 

Je n'ai pas encore mis le combo ELB / ASG à l'épreuve. C'est un peu loin de ma liste de tâches à faire, mais je sais qu'il y a beaucoup d'autres utilisateurs de cette configuration et que cela ne semble pas avoir de problèmes de performance majeurs.

La configuration d'un groupe Auto-Scaling est un peu compliquée à mon avis. C'est en fait un processus en trois étapes:

  1. Créez une AMI configurée à votre guise.
  2. Créez une configuration de lancement qui utilise l’AMI que vous avez créée.
  3. Créez un groupe de mise à l'échelle automatique utilisant la configuration de lancement que vous avez créée pour déterminer le type d'AMI et d'instance à lancer pour un événement SCALEUP donné.

Pour gérer le déploiement de la configuration et des applications lors du lancement d'une instance, utilisez le champ "Données utilisateur" pour saisir un script qui s'exécutera une fois qu'une instance donnée sera lancée. C'est peut-être la pire nomenclature de l'histoire. Comment "User Data" décrit un script de démarrage que seul l'auteur connaît. En tout cas, c'est là que vous collez le script qui gère tous vos apt-get, mkdirs, clones git, etc.


Instances et équilibrage interne

J'ai également ajouté un autre "niveau d'équilibrage interne" utilisant Nginx, ce qui me permet de "mettre à plat" toutes mes applications Node.js (app.myapp.com, api.myapp.com, mobile.myapp.com, www. myapp.com, etc.myapp.com) sur chaque instance. Lorsqu'une instance reçoit une requête transmise par ELB, Nginx gère le routage de la demande vers le port Node.js approprié pour une application donnée. Un peu comme une conteneurisation pauvre. Cela a l'avantage supplémentaire que chaque fois qu'une de mes applications a besoin de parler à l'autre (comme lorsqu'app app. Doit envoyer une requête à api. ), Cela se fait via localhost:XXXX plutôt que de devoir passer par le réseau AWS, ou l'Internet lui-même.

Cette configuration maximise également l'utilisation de mes ressources en éliminant toute infrastructure inactive si la couche d'application qu'elle héberge reçoit un trafic léger. Cela évite aussi d'avoir à combiner ELB / ASG pour chaque application, économisant ainsi plus d'argent.

Il n'y a pas de pièges ou de mises en garde que j'ai rencontrés en utilisant ce type de configuration, mais il y a un remaniement qui doit être mis en place en ce qui concerne la vérification de la santé (voir ci-dessous).

Il y a également un avantage certain dans le fait que toutes les instances ont un rôle IAM, ce qui signifie que vos annonces AWS sont intégrées à chaque instance dès leur naissance et accessibles via vos vars ENV. Et AWS fait automatiquement pivoter vos créations pour vous. Très sécurisé, très cool.


Bilans de santé

Si vous suivez le chemin de la configuration ci-dessus, en mettant à plat toutes vos applications sur une boîte et en exécutant un équilibreur de charge interne, vous devez créer un petit utilitaire pour gérer les vérifications de santé ELB . J'ai créé une application supplémentaire appelée ping.myapp.com. Et puis j'ai configuré mes vérifications de santé ELB pour envoyer des vérifications de santé au port sur lequel mon application ping s'exécute, comme ceci:

 Ping Protocol: HTTP Ping Port: XXXX Ping Path: /ping 

Cela envoie tous les contrôles de santé à mon petit assistant de ping, qui à son tour frappe localhost:XXXX/ping sur toutes les applications résidant sur l'instance. S'ils renvoient tous une réponse 200, mon application ping renvoie alors une réponse 200 à la vérification de l'état ELB et les instances peuvent vivre pendant 30 secondes supplémentaires.

REMARQUE: N'utilisez pas les contrôles de santé Auto-Scaling si vous utilisez un ELB. Utilisez les contrôles de santé ELB. C'est un peu déroutant, je pensais que c'était la même chose, ils ne le sont pas. Vous avez la possibilité d'activer l'un ou l'autre. Aller avec ELB.


La couche de données

La couche de données est une chose absente de ma configuration. J'utilise Compose.io comme fournisseur de couche de données gérée et je déploie sur AWS, ce qui me permet d'obtenir une latence très faible entre mes couches d'application et ma couche de données. J'ai fait quelques recherches préliminaires sur la manière dont je déploierais ma couche de données à l'échelle mondiale et j'ai constaté qu'elle était très complexe et très coûteuse. J'ai donc lancé ma liste comme un problème qui n'a pas encore besoin d'être résolu. Le pire des cas est que je vais utiliser ma couche de données aux États-Unis uniquement et améliorer le matériel. Ce n'est pas la pire chose au monde, car mon API est ssortingctement constituée de données JSON sur le câble, donc la réponse moyenne est relativement faible. Mais je peux voir que cela devient un goulot d’étranglement à une très grande échelle mondiale - si j’y arrive. Si quelqu'un a quelque chose à dire sur cette couche, j'adorerais entendre ce que vous avez à dire.


Ta-Da!

Haute disponibilité mondiale sur un budget de bière. Il ne m'a fallu que 6 mois pour le comprendre.

J'adore entendre toute consortingbution ou idée de quiconque a lu cela.

Vous pouvez utiliser Anycast pour votre service Web gratuitement si vous utilisez un plan gratuit Cloudflare.

Digital Ocean prend désormais en charge l’équilibrage de charge des serveurs. Il est extrêmement facile à configurer et fonctionne très bien! Vous évite d’avoir à append des composants inutiles tels que nginx (si vous souhaitez uniquement utiliser l’équilibrage de charge).

Nous avions des problèmes avec les téléchargements de fichiers SSL avec nginx sur un serveur numérique, mais depuis la mise à jour de Digital Ocean, nous avons supprimé nginx et utilisons maintenant la fonction d’équilibrage de charge de Digital Ocean.