Comment configurer des serveurs HAProxy hautement disponibles avec des IP conservées et flottantes sur Ubuntu 14.04

introduction

La haute disponibilité est une fonction de la conception du système qui permet à une application de redémarrer ou de rediriger automatiquement le travail vers un autre système capable en cas de panne. En termes de serveurs, plusieurs technologies différentes sont nécessaires pour configurer un système hautement disponible. Il doit exister un composant capable de rediriger le travail et un mécanisme permettant de surveiller les défaillances et de faire la transition du système si une interruption est détectée.

Le démonkeepalived peut être utilisé pour surveiller des services ou des systèmes et pour basculer automatiquement en mode veille en cas de problème. Dans ce guide, nous montrerons comment utiliserkeepalived pour configurer la haute disponibilité pour vos équilibreurs de charge. Nous allons configurer unfloating IP address qui peut être déplacé entre deux équilibreurs de charge compatibles. Ceux-ci seront chacun configurés pour répartir le trafic entre deux serveurs Web principaux. Si l'équilibreur de charge principal tombe en panne, l'adresse IP flottante sera automatiquement déplacée vers le second équilibreur de charge, permettant ainsi au service de reprendre.

High Availability diagram

[.note] #Note:DigitalOcean Load Balancers est un service d'équilibrage de charge entièrement géré et hautement disponible. Le service Load Balancer peut remplir le même rôle que la configuration manuelle de haute disponibilité décrite ici. Suivez nosguide on setting up Load Balancers si vous souhaitez évaluer cette option.
#

Conditions préalables

Afin de compléter ce guide, vous devrez créer quatre serveurs Ubuntu 14.04 dans votre compte DigitalOcean. Tous les serveurs doivent être situés dans le même centre de données et le réseau privé doit être activé.

Sur chacun de ces serveurs, vous aurez besoin d'un utilisateur non root configuré avec un accèssudo. Vous pouvez suivre nosUbuntu 14.04 initial server setup guide pour savoir comment configurer ces utilisateurs.

Recherche d'informations sur le réseau du serveur

Avant de commencer la configuration réelle de nos composants d'infrastructure, il est préférable de collecter des informations sur chacun de vos serveurs.

Pour compléter ce guide, vous devez disposer des informations suivantes sur vos serveurs:

  • web servers: adresse IP privée

  • load balancers Adresses IP privées et ancrées

Recherche d'adresses IP privées

Le moyen le plus simple de trouver l’adresse IP privée de votre Droplet consiste à utilisercurl pour récupérer l’adresse IP privée du service de métadonnées DigitalOcean. Cette commande doit être exécutée à partir de vos gouttelettes. Sur chaque gouttelette, tapez:

curl 169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address && echo

L'adresse IP correcte doit être imprimée dans la fenêtre du terminal:

Output10.132.20.236

Recherche d'adresses IP d'ancrage

“L'ancre IP” est l'adresse IP privée locale à laquelle l'IP flottante se liera lorsqu'elle sera attachée à un serveur DigitalOcean. Il s'agit simplement d'un alias pour l'adresse normale deeth0, implémentée au niveau de l'hyperviseur.

Le moyen le plus simple et le moins sujet aux erreurs de saisir cette valeur est directement issu du service de métadonnées DigitalOcean. En utilisantcurl, vous pouvez atteindre ce point de terminaison sur chacun de vos serveurs en tapant:

curl 169.254.169.254/metadata/v1/interfaces/public/0/anchor_ipv4/address && echo

L'ancre IP sera imprimée sur sa propre ligne:

Output10.17.1.18

Installer et configurer le serveur Web

Après avoir rassemblé les données ci-dessus, nous pouvons passer à la configuration de nos services.

Note

[.note] # Dans cette configuration, le logiciel sélectionné pour la couche serveur Web est assez interchangeable. Ce guide utilisera Nginx car il est générique et plutôt facile à configurer. Si vous êtes plus à l'aise avec Apache ou un serveur Web spécifique à la langue (capable de production), n'hésitez pas à l'utiliser à la place. HAProxy transmettra simplement les demandes des clients aux serveurs Web principaux qui peuvent gérer les demandes de la même manière qu'il traiterait les connexions directes des clients.
#

Nous allons commencer par configurer nos serveurs Web backend. Ces deux serveurs serviront exactement le même contenu. Ils n'accepteront que les connexions Web sur leurs adresses IP privées. Cela vous aidera à vous assurer que le trafic est dirigé vers l'un des deux serveurs HAProxy que nous configurerons plus tard.

La configuration de serveurs Web derrière un équilibreur de charge nous permet de répartir la charge des demandes entre plusieurs serveurs Web identiques. Au fur et à mesure que nos besoins en trafic évoluent, nous pouvons facilement répondre aux nouvelles demandes en ajoutant ou en supprimant des serveurs Web de ce niveau.

Installer Nginx

Nous installerons Nginx sur nos machines de service Web pour fournir cette fonctionnalité.

Commencez par vous connecter avec votre utilisateursudo aux deux machines que vous souhaitez utiliser comme serveurs Web. Mettez à jour l'index de paquetage local sur chacun de vos serveurs Web et installez Nginx en tapant:

sudo apt-get update
sudo apt-get install nginx

Configurer Nginx pour n'autoriser que les demandes des équilibreurs de charge

Ensuite, nous allons configurer nos instances Nginx. Nous voulons dire à Nginx de n'écouter que les demandes sur l'adresse IP privée du serveur. De plus, nous ne servirons que les demandes provenant des adresses IP privées de nos deux équilibreurs de charge.

Pour apporter ces modifications, ouvrez le fichier de blocage du serveur Nginx par défaut sur chacun de vos serveurs Web:

sudo nano /etc/nginx/sites-available/default

Pour commencer, nous allons modifier les directiveslisten. Modifiez la directivelisten pour écouter lesweb server’s private IP address actuels sur le port 80. Supprimez la lignelisten supplémentaire. Ça devrait ressembler a quelque chose comme ca:

/etc/nginx/sites-available/default

server {
    listen web_server_private_IP:80;

    . . .

Ensuite, nous mettrons en place deux directivesallow pour autoriser le trafic provenant des adresses IP privées de nos deux équilibreurs de charge. Nous allons suivre cela avec une règledeny all pour interdire tout autre trafic:

/etc/nginx/sites-available/default

server {
    listen web_server_private_IP:80;

    allow load_balancer_1_private_IP;
    allow load_balancer_2_private_IP;
    deny all;

    . . .

Enregistrez et fermez les fichiers lorsque vous avez terminé.

Vérifiez que les modifications que vous avez apportées représentent la syntaxe Nginx valide en tapant:

sudo nginx -t

Si aucun problème n'a été signalé, redémarrez le démon Nginx en tapant:

sudo service nginx restart

Tester les changements

Pour vérifier que vos serveurs Web sont correctement limités, vous pouvez effectuer des requêtes en utilisantcurl à partir de divers emplacements.

Sur vos serveurs Web eux-mêmes, vous pouvez essayer une simple demande du contenu local en tapant:

curl 127.0.0.1

En raison des restrictions que nous avons définies dans nos fichiers de blocage de serveur Nginx, cette demande sera en réalité refusée:

Outputcurl: (7) Failed to connect to 127.0.0.1 port 80: Connection refused

Ceci est prévu et reflète le comportement que nous avons tenté d'implémenter.

Désormais, à partir de l’un ou l’autre desload balancers, nous pouvons faire une demande pour l’une des adresses IP publiques de notre serveur Web:

curl web_server_public_IP

Encore une fois, cela devrait échouer. Les serveurs Web n'écoutent pas sur l'interface publique. De plus, lors de l'utilisation de l'adresse IP publique, nos serveurs Web ne voient pas les adresses IP privées autorisées dans la demande de nos équilibreurs de charge:

Outputcurl: (7) Failed to connect to web_server_public_IP port 80: Connection refused

Cependant, si nous modifions l’appel pour faire la requête en utilisant lesprivate IP address du serveur Web, cela devrait fonctionner correctement:

curl web_server_private_IP

La page par défaut de Nginxindex.htmldoit être renvoyée:

Output


Welcome to nginx!

. . .

Testez ceci des deux équilibreurs de charge vers les deux serveurs Web. Chaque demande d'adresse IP privée doit aboutir tandis que chaque demande adressée aux adresses publiques doit échouer.

Une fois que le comportement ci-dessus est démontré, nous pouvons passer à autre chose. La configuration de notre serveur Web principal est maintenant terminée.

Installer et configurer HAProxy

Nous allons ensuite configurer les équilibreurs de charge HAProxy. Celles-ci seront chacune devant nos serveurs Web et répartiront les demandes entre les deux serveurs principaux. Ces équilibreurs de charge sont complètement redondants. Un seul recevra du trafic à un moment donné.

La configuration HAProxy transmet les requêtes aux deux serveurs Web. Les équilibreurs de charge écouteront les demandes sur leur adresse IP d'ancrage. Comme mentionné précédemment, il s'agit de l'adresse IP à laquelle l'adresse IP flottante se liera lorsqu'elle sera attachée au Droplet. Cela garantit que seul le trafic provenant de l'adresse IP flottante sera transféré.

Installer HAProxy

La première étape que nous devons entreprendre sur nos équilibreurs de charge sera d'installer le packagehaproxy. Nous pouvons le trouver dans les référentiels Ubuntu par défaut. Mettez à jour l'index de paquetage local sur vos équilibreurs de charge et installez HAProxy en tapant:

sudo apt-get update
sudo apt-get install haproxy

Configurer HAProxy

Le premier élément que nous devons modifier lorsque nous traitons avec HAProxy est le fichier/etc/default/haproxy. Ouvrez ce fichier maintenant dans votre éditeur:

sudo nano /etc/default/haproxy

Ce fichier détermine si HAProxy démarrera au démarrage. Puisque nous voulons que le service démarre automatiquement à chaque mise sous tension du serveur, nous devons changer la valeur deENABLED sur «1»:

/etc/default/haproxy

# Set ENABLED to 1 if you want the init script to start haproxy.
ENABLED=1
# Add extra flags here.
#EXTRAOPTS="-de -m 16"

Enregistrez et fermez le fichier après avoir apporté la modification ci-dessus.

Ensuite, nous pouvons ouvrir le fichier de configuration principal de HAProxy:

sudo nano /etc/haproxy/haproxy.cfg

Le premier élément que nous devons ajuster est le mode dans lequel HAProxy fonctionnera. Nous voulons configurer TCP, ou couche 4, l'équilibrage de charge. Pour ce faire, nous devons modifier la lignemode dans la sectiondefault. Nous devrions également changer l'option immédiatement après qui traite du journal:

/etc/haproxy/haproxy.cfg

. . .

defaults
    log     global
    mode    tcp
    option  tcplog

. . .

À la fin du fichier, nous devons définir notre configuration front-end. Cela dictera comment HAProxy écoute les connexions entrantes. Nous allons lier HAProxy à l'adresse IP d'ancrage de l'équilibreur de charge. Cela lui permettra d'écouter le trafic provenant de l'adresse IP flottante. Nous appellerons notre front end «www» pour plus de simplicité. Nous allons également spécifier un backend par défaut pour le trafic (que nous allons configurer dans un instant):

/etc/haproxy/haproxy.cfg

. . .

defaults
    log     global
    mode    tcp
    option  tcplog

. . .

frontend www
    bind    load_balancer_anchor_IP:80
    default_backend nginx_pool

Ensuite, nous pouvons configurer notre section backend. Cela spécifiera les emplacements en aval où HAProxy transmettra le trafic reçu. Dans notre cas, il s’agit des adresses IP privées des deux serveurs Web Nginx que nous avons configurés. Nous allons spécifier l’équilibrage à tour de rôle traditionnel et régler le mode sur «tcp» à nouveau:

/etc/haproxy/haproxy.cfg

. . .

defaults
    log     global
    mode    tcp
    option  tcplog

. . .

frontend www
    bind load_balancer_anchor_IP:80
    default_backend nginx_pool

backend nginx_pool
    balance roundrobin
    mode tcp
    server web1 web_server_1_private_IP:80 check
    server web2 web_server_2_private_IP:80 check

Lorsque vous avez terminé les modifications ci-dessus, enregistrez et fermez le fichier.

Vérifiez que les modifications de configuration que nous avons apportées représentent la syntaxe HAProxy valide en tapant:

sudo haproxy -f /etc/haproxy/haproxy.cfg -c

Si aucune erreur n'a été signalée, redémarrez votre service en tapant:

sudo service haproxy restart

Tester les changements

Nous pouvons nous assurer que notre configuration est valide en testant à nouveau aveccurl.

A partir des serveurs de l’équilibreur de charge, essayez de demander à l’hôte local, à sa propre adresse IP publique ou à l’adresse IP privée du serveur:

curl 127.0.0.1
curl load_balancer_public_IP
curl load_balancer_private_IP

Ceux-ci devraient tous échouer avec des messages qui ressemblent à ceci:

Outputcurl: (7) Failed to connect to address port 80: Connection refused

Cependant, si vous envoyez une requête auxanchor IP address de l'équilibreur de charge, elle devrait aboutir:

curl load_balancer_anchor_IP

Vous devriez voir la page par défaut de Nginxindex.html, acheminée depuis l'un des deux serveurs Web principaux:

Output


Welcome to nginx!

. . .

Si ce comportement correspond à celui de votre système, vos équilibreurs de charge sont configurés correctement.

Construire et installer Keepalived

Notre service actuel est maintenant opérationnel. Toutefois, notre infrastructure n’est pas encore très disponible car nous n’avons aucun moyen de rediriger le trafic si notre équilibreur de charge actif rencontre des problèmes. Afin de remédier à cela, nous installerons le démonkeepalived sur nos serveurs d'équilibrage de charge. C'est le composant qui fournira des fonctionnalités de basculement si notre équilibreur de charge actif devient indisponible.

Il existe une version dekeepalived dans les référentiels par défaut d'Ubuntu, mais elle est obsolète et souffre de quelques bogues qui empêcheraient notre configuration de fonctionner. Au lieu de cela, nous installerons la dernière version dekeepalived à partir des sources.

Avant de commencer, nous devrions saisir les dépendances dont nous aurons besoin pour construire le logiciel. Le méta-paquetbuild-essential fournira les outils de compilation dont nous avons besoin, tandis que le paquetlibssl-dev contient les bibliothèques de développement SSL sur lesquelleskeepalived doit construire:

sudo apt-get install build-essential libssl-dev

Une fois les dépendances en place, nous pouvons télécharger l'archive tar pourkeepalived. Visitezthis page pour trouver la dernière version du logiciel. Cliquez avec le bouton droit sur la dernière version et copiez l'adresse du lien. De retour sur vos serveurs, accédez à votre répertoire personnel et utilisezwget pour récupérer le lien que vous avez copié:

cd ~
wget http://www.keepalived.org/software/keepalived-1.2.19.tar.gz

Utilisez la commandetar pour développer l'archive. Déplacez-vous dans le répertoire résultant:

tar xzvf keepalived*
cd keepalived*

Construisez et installez le démon en tapant:

./configure
make
sudo make install

Le démon doit maintenant être installé sur les deux systèmes d'équilibrage de charge.

Créer un script Keepalived Upstart

L'installation dekeepalived a déplacé tous les binaires et les fichiers de support en place sur notre système. Cependant, un élément non inclus était un script Upstart pour nos systèmes Ubuntu 14.04.

Nous pouvons créer un script Upstart très simple qui peut gérer notre servicekeepalived. Ouvrez un fichier appelékeepalived.conf dans le répertoire/etc/init pour commencer:

sudo nano /etc/init/keepalived.conf

À l'intérieur, nous pouvons commencer par une simple description de la fonctionnalité fournie parkeepalived. Nous utiliserons la description de la pageman incluse. Ensuite, nous spécifierons les niveaux d'exécution dans lesquels le service doit être démarré et arrêté. Nous souhaitons que ce service soit actif dans toutes les conditions normales (niveaux d'exécution 2-5) et arrêté pour tous les autres niveaux d'exécution (lors du lancement du mode redémarrage, extinction ou mono-utilisateur, par exemple):

/etc/init/keepalived.conf

description "load-balancing and high-availability service"

start on runlevel [2345]
stop on runlevel [!2345]

Ce service étant essentiel pour garantir la disponibilité de notre service Web, nous souhaitons le redémarrer en cas de panne. Nous pouvons alors spécifier la ligneexec réelle qui démarrera le service. Nous devons ajouter l'option--dont-fork pour que Upstart puisse suivre correctement lespid:

/etc/init/keepalived.conf

description "load-balancing and high-availability service"

start on runlevel [2345]
stop on runlevel [!2345]

respawn

exec /usr/local/sbin/keepalived --dont-fork

Enregistrez et fermez les fichiers lorsque vous avez terminé.

Créer le fichier de configuration Keepalived

Avec nos fichiers Upstart en place, nous pouvons maintenant passer à la configuration dekeepalived.

Le service recherche ses fichiers de configuration dans le répertoire/etc/keepalived. Créez ce répertoire maintenant sur vos deux équilibreurs de charge:

sudo mkdir -p /etc/keepalived

Création de la configuration de l’équilibreur de charge principal

Ensuite, sur le serveur d'équilibrage de charge que vous souhaitez utiliser comme serveurprimary, créez le fichier de configuration principal dekeepalived. Le démon recherche un fichier appelékeepalived.conf dans le répertoire/etc/keepalived:

sudo nano /etc/keepalived/keepalived.conf

À l'intérieur, nous commencerons par définir une vérification de l'état de notre service HAProxy en ouvrant un blocvrrp_script. Cela permettra àkeepalived de surveiller notre équilibreur de charge pour les échecs afin qu'il puisse signaler que le processus est arrêté et commencer les mesures de récupération.

Notre chèque sera très simple. Toutes les deux secondes, nous vérifierons qu'un processus appeléhaproxy réclame toujours unpid:

/Etc/keepalived/keepalived.conf du serveur principal

vrrp_script chk_haproxy {
    script "pidof haproxy"
    interval 2
}

Ensuite, nous allons ouvrir un bloc appelévrrp_instance. Il s'agit de la section de configuration principale qui définit la manière dontkeepalived implémentera la haute disponibilité.

Nous commencerons par dire àkeepalived de communiquer avec ses pairs viaeth1, notre interface privée. Puisque nous configurons notre serveur principal, nous allons définir la configuration destate sur «MASTER». C'est la valeur initiale quekeepalived utilisera jusqu'à ce que le démon puisse contacter son homologue et organiser une élection.

Lors de l'élection, l'optionpriority est utilisée pour décider quel membre est élu. La décision est simplement basée sur le serveur qui a le numéro le plus élevé pour ce paramètre. Nous allons utiliser "200" pour notre serveur principal:

/Etc/keepalived/keepalived.conf du serveur principal

vrrp_script chk_nginx {
    script "pidof nginx"
    interval 2
}

vrrp_instance VI_1 {
    interface eth1
    state MASTER
    priority 200


}

Ensuite, nous attribuerons un identifiant à ce groupe de clusters qui sera partagé par les deux nœuds. Nous allons utiliser "33" pour cet exemple. Nous devons définirunicast_src_ip sur l'adresse IP privée de notre équilibreur de chargeprimary. Nous allons définirunicast_peer sur l'adresse IP privée de notre équilibreur de chargesecondary:

/Etc/keepalived/keepalived.conf du serveur principal

vrrp_script chk_haproxy {
    script "pidof haproxy"
    interval 2
}

vrrp_instance VI_1 {
    interface eth1
    state MASTER
    priority 200

    virtual_router_id 33
    unicast_src_ip primary_private_IP
    unicast_peer {
        secondary_private_IP
    }


}

Ensuite, nous pouvons configurer une authentification simple pour que nos démonskeepalived communiquent entre eux. Il s’agit simplement d’une mesure de base visant à garantir la légitimité du pair contacté. Créez un sous-blocauthentication. À l'intérieur, spécifiez l'authentification par mot de passe en définissant lesauth_type. Pour le paramètreauth_pass, définissez un secret partagé qui sera utilisé par les deux nœuds. Malheureusement, seuls les huit premiers caractères sont significatifs:

/Etc/keepalived/keepalived.conf du serveur principal

vrrp_script chk_haproxy {
    script "pidof haproxy"
    interval 2
}

vrrp_instance VI_1 {
    interface eth1
    state MASTER
    priority 200

    virtual_router_id 33
    unicast_src_ip primary_private_IP
    unicast_peer {
        secondary_private_IP
    }

    authentication {
        auth_type PASS
        auth_pass password
    }


}

Ensuite, nous dirons àkeepalived d'utiliser le chèque que nous avons créé en haut du fichier, étiquetéchk_haproxy, pour déterminer la santé du système local. Enfin, nous allons définir un scriptnotify_master, qui est exécuté chaque fois que ce nœud devient le «maître» de la paire. Ce script sera responsable du déclenchement de la réaffectation d'adresse IP flottante. Nous allons créer ce script momentanément:

/Etc/keepalived/keepalived.conf du serveur principal

vrrp_script chk_haproxy {
    script "pidof haproxy"
    interval 2
}

vrrp_instance VI_1 {
    interface eth1
    state MASTER
    priority 200

    virtual_router_id 33
    unicast_src_ip primary_private_IP
    unicast_peer {
        secondary_private_IP
    }

    authentication {
        auth_type PASS
        auth_pass password
    }

    track_script {
        chk_haproxy
    }

    notify_master /etc/keepalived/master.sh
}

Une fois que vous avez configuré les informations ci-dessus, enregistrez et fermez le fichier.

Création de la configuration de l’équilibreur de charge secondaire

Ensuite, nous allons créer le script compagnon sur notre équilibreur de charge secondaire. Ouvrez un fichier à/etc/keepalived/keepalived.conf sur votre serveur secondaire:

sudo nano /etc/keepalived/keepalived.conf

A l’intérieur, le script que nous allons utiliser sera largement équivalent au script du serveur principal. Les éléments que nous devons changer sont:

  • state: Cela doit être changé en «SAUVEGARDE» sur le serveur secondaire afin que le nœud s'initialise à l'état de sauvegarde avant les élections.

  • priority: il doit être défini sur une valeur inférieure à celle du serveur principal. Nous allons utiliser la valeur «100» dans ce guide.

  • unicast_src_ip: il doit s'agir de l'adresse IP privée du serveursecondary.

  • unicast_peer: il doit contenir l'adresse IP privée du serveurprimary.

Lorsque vous modifiez ces valeurs, le script du serveur secondaire doit ressembler à ceci:

/Etc/keepalived/keepalived.conf du serveur secondaire

vrrp_script chk_haproxy {
    script "pidof haproxy"
    interval 2
}

vrrp_instance VI_1 {
    interface eth1
    state BACKUP
    priority 100

    virtual_router_id 33
    unicast_src_ip secondary_private_IP
    unicast_peer {
        primary_private_IP
    }

    authentication {
        auth_type PASS
        auth_pass password
    }

    track_script {
        chk_haproxy
    }

    notify_master /etc/keepalived/master.sh
}

Une fois que vous avez entré le script et modifié les valeurs appropriées, enregistrez et fermez le fichier.

Créer les scripts de transition IP flottants

Ensuite, nous devons créer une paire de scripts que nous pouvons utiliser pour réaffecter l'adresse IP flottante au Droplet actuel chaque fois que l'instance locale dekeepalived devient le serveur maître.

Téléchargez le script d'affectation d'adresses IP flottantes

Tout d'abord, nous allons télécharger un script Python générique (écrit par unDigitalOcean community manager) qui peut être utilisé pour réaffecter une adresse IP flottante à un Droplet à l'aide de l'API DigitalOcean. Nous devrions télécharger ce fichier dans le répertoire/usr/local/bin:

cd /usr/local/bin
sudo curl -LO http://do.co/assign-ip

Ce script vous permet de réaffecter une adresse IP flottante existante en exécutant:

python /usr/local/bin/assign-ip floating_ip droplet_ID

Cela ne fonctionnera que si vous avez une variable d'environnement appeléeDO_TOKEN définie sur un jeton d'API DigitalOcean valide pour votre compte.

Créer un jeton d'API DigitalOcean

Pour utiliser le script ci-dessus, nous devrons créer un jeton d'API DigitalOcean dans notre compte.

Dans le panneau de configuration, cliquez sur le lien "API" en haut. Sur le côté droit de la page API, cliquez sur “Générer un nouveau jeton”:

DigitalOcean generate API token

Sur la page suivante, sélectionnez un nom pour votre jeton et cliquez sur le bouton “Générer un jeton”:

DigitalOcean make new token

Sur la page API, votre nouveau jeton sera affiché:

DigitalOcean token

Copiez le jetonnow. Pour des raisons de sécurité, il n'est pas possible d'afficher ce jeton ultérieurement. Si vous perdez ce jeton, vous devrez le détruire et en créer un autre.

Configurer une IP flottante pour votre infrastructure

Ensuite, nous allons créer et attribuer une adresse IP flottante à utiliser pour nos serveurs.

Dans le panneau de commande DigitalOcean, cliquez sur l'onglet «Réseau» et sélectionnez l'élément de navigation «IP flottantes». Sélectionnez votre équilibreur de charge principal dans le menu pour l'affectation initiale:

DigitalOcean add floating IP

Une nouvelle adresse IP flottante sera créée dans votre compte et attribuée au droplet spécifié:

DigitalOcean floating IP assigned

Si vous consultez l'adresse IP flottante dans votre navigateur Web, vous devriez voir la page Nginx par défaut servie depuis l'un des serveurs Web principaux:

DigitalOcean default index.html

Copiez l'adresse IP flottante. Vous aurez besoin de cette valeur dans le script ci-dessous.

Créer le script wrapper

Maintenant, nous avons les éléments dont nous avons besoin pour créer le script wrapper qui appellera notre script/usr/local/bin/assign-ip avec les informations d'identification correctes.

Créez le fichier maintenant surboth de vos équilibreurs de charge en tapant:

sudo nano /etc/keepalived/master.sh

À l'intérieur, commencez par affecter et exporter une variable appeléeDO_TOKEN qui contient le jeton API que vous venez de créer. En dessous, nous pouvons attribuer une variable appeléeIP qui contient votre adresse IP flottante:

/etc/keepalived/master.sh

export DO_TOKEN='digitalocean_api_token'
IP='floating_ip_addr'

Ensuite, nous utiliseronscurl pour demander au service de métadonnées l'ID de droplet du serveur sur lequel nous sommes actuellement. Cela sera affecté à une variable appeléeID. Nous demanderons également si cette Droplet a actuellement l'adresse IP flottante qui lui est attribuée. Nous stockerons les résultats de cette requête dans une variable appeléeHAS_FLOATING_IP:

/etc/keepalived/master.sh

export DO_TOKEN='digitalocean_api_token'
IP='floating_ip_addr'
ID=$(curl -s http://169.254.169.254/metadata/v1/id)
HAS_FLOATING_IP=$(curl -s http://169.254.169.254/metadata/v1/floating_ip/ipv4/active)

Maintenant, nous pouvons utiliser les variables ci-dessus pour appeler le scriptassign-ip. Nous n'appellerons le script que si l'adresse IP flottante n'est pas déjà associée à notre Droplet. Cela contribuera à minimiser les appels à l'API et à éviter les demandes conflictuelles adressées à l'API dans les cas où l'état maître basculera rapidement entre vos serveurs.

Pour gérer les cas où l'IP flottante a déjà un événement en cours, nous réessayerons le scriptassign-ip plusieurs fois. Ci-dessous, nous essayons d'exécuter le script 10 fois, avec un intervalle de 3 secondes entre chaque appel. La boucle se terminera immédiatement si le déplacement d'adresse IP flottante est réussi:

/etc/keepalived/master.sh

export DO_TOKEN='digitalocean_api_token'
IP='floating_ip_addr'
ID=$(curl -s http://169.254.169.254/metadata/v1/id)
HAS_FLOATING_IP=$(curl -s http://169.254.169.254/metadata/v1/floating_ip/ipv4/active)

if [ $HAS_FLOATING_IP = "false" ]; then
    n=0
    while [ $n -lt 10 ]
    do
        python /usr/local/bin/assign-ip $IP $ID && break
        n=$((n+1))
        sleep 3
    done
fi

Enregistrez et fermez le fichier lorsque vous avez terminé.

Maintenant, nous avons juste besoin de rendre le script exécutable pour quekeepalived puisse l'appeler:

sudo chmod +x /etc/keepalived/master.sh

Démarrer le service Keepalived et tester le basculement

Le démonkeepalived et tous ses scripts compagnons devraient maintenant être complètement configurés. Nous pouvons démarrer le service sur nos deux équilibreurs de charge en tapant:

sudo start keepalived

Le service doit démarrer sur chaque serveur et contacter son homologue en s’authentifiant avec le secret partagé que nous avons configuré. Chaque démon surveillera le processus HAProxy local et écoutera les signaux du processus distantkeepalived.

Votre équilibreur de charge principal, auquel l'adresse IP flottante doit être affectée actuellement, dirigera les requêtes vers chacun des serveurs Nginx principaux. Il y a une certaine rigidité de session qui est généralement appliquée, ce qui augmente les chances que vous obteniez le même backend lorsque vous effectuez des demandes via un navigateur Web.

Nous pouvons tester le basculement de manière simple en désactivant simplement HAProxy sur notre équilibreur de charge principal:

sudo service haproxy stop

Si nous visitons notre adresse IP flottante dans notre navigateur, il est possible que nous obtenions momentanément une erreur indiquant que la page était introuvable.

http://floating_IP_addr

DigitalOcean page not available

Si nous actualisons la page plusieurs fois, dans quelques instants, notre page Nginx par défaut reviendra:

DigitalOcean default index.html

Notre service HAProxy est toujours en panne sur notre équilibreur de charge principal. Cela indique donc que notre équilibreur de charge secondaire a pris le relais. À l'aide dekeepalived, le serveur secondaire a pu déterminer qu'une interruption de service s'était produite. Il est ensuite passé à l'état «maître» et a revendiqué l'adresse IP flottante à l'aide de l'API DigitalOcean.

Nous pouvons maintenant relancer HAProxy sur l’équilibreur de charge principal:

sudo service haproxy start

L'équilibreur de charge principal reprendra le contrôle de l'adresse IP flottante dans un instant, même si cela devrait être plutôt transparent pour l'utilisateur.

Visualiser la transition

Afin de mieux visualiser la transition entre les équilibreurs de charge, nous pouvons surveiller certains journaux de notre serveur pendant la transition.

Etant donné que les informations sur le serveur proxy utilisé ne sont pas renvoyées au client, le meilleur endroit pour afficher les journaux est celui des serveurs Web principaux. Chacun de ces serveurs doit conserver des journaux sur les clients qui demandent des actifs. Du point de vue du service Nginx, le client est l’équilibreur de charge qui effectue les demandes pour le compte du client réel.

Tail the Logs sur les serveurs Web

Sur chacun de nos serveurs web backend, nous pouvonstail l'emplacement de/var/log/nginx/access.log. Cela montrera chaque demande faite au serveur. Étant donné que nos équilibreurs de charge divisent le trafic de manière uniforme en utilisant une rotation alternée, chaque serveur Web principal doit voir environ la moitié des demandes effectuées.

L'adresse du client est heureusement le tout premier champ du journal des accès. Nous pouvons extraire la valeur en utilisant une simple commandeawk. Exécutez ce qui suit surboth de vos serveurs Web Nginx:

sudo tail -f /var/log/nginx/access.log | awk '{print $1;}'

Ceux-ci montreront probablement principalement une seule adresse:

Output. . .

primary_lb_private_IP
primary_lb_private_IP
secondary_lb_private_IP
secondary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP

Si vous référencez les adresses IP de votre serveur, vous remarquerez qu'elles proviennent principalement de votre équilibreur de charge principal. Notez que la distribution réelle sera probablement un peu différente en raison de la simplicité de la session que HAProxy implémente.

Laissez la commandetail s'exécuter sur vos deux serveurs Web.

Automatiser les requêtes sur l'IP flottant

Maintenant, sur votre ordinateur local, nous demanderons le contenu Web à l'adresse IP flottante une fois toutes les 2 secondes. Cela nous permettra de voir facilement le changement d’équilibreur de charge. Dans votre terminal local, tapez ce qui suit (nous rejetons la réponse réelle, car elle devrait être identique quel que soit l'équilibreur de charge utilisé):

while true; do curl -s -o /dev/null floating_IP; sleep 2; done

Sur vos serveurs Web, vous devriez commencer à voir de nouvelles demandes arriver. Contrairement aux requêtes effectuées via un navigateur Web, les requêtescurl simples ne présentent pas la même persistance de session. Vous devriez voir une répartition plus homogène des demandes adressées à vos serveurs Web principaux.

Interrompre le service HAProxy sur l’équilibreur de charge principal

Maintenant, nous pouvons à nouveau arrêter le service HAProxy sur notre équilibreur de charge principal:

sudo service haproxy stop

Au bout de quelques secondes, sur vos serveurs Web, vous verrez la liste des adresses IP passer de l’adresse IP privée de l’équilibreur de charge principal à l’adresse IP privée de celui-ci:

Output. . .

primary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
secondary_lb_private_IP
secondary_lb_private_IP
secondary_lb_private_IP
secondary_lb_private_IP

Toutes les nouvelles demandes proviennent de votre équilibreur de charge secondaire.

Maintenant, relancez l’instance HAProxy sur votre équilibreur de charge principal:

sudo service haproxy start

Vous verrez les demandes des clients revenir à l’adresse IP privée de l’équilibreur de charge principal en quelques secondes:

Output. . .

primary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
secondary_lb_private_IP
secondary_lb_private_IP
secondary_lb_private_IP
secondary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP
primary_lb_private_IP

Le serveur principal a repris le contrôle de l'adresse IP flottante et a repris son travail d'équilibreur de charge principal pour l'infrastructure.

Configurer Nginx pour consigner l'adresse IP réelle du client

Comme vous l'avez vu, les journaux d'accès Nginx montrent que toutes les demandes client proviennent de l'adresse IP privée de l'équilibreur de charge actuel, et non de l'adresse IP réelle du client qui a initialement effectué la demande (c'est-à-dire. votre machine locale). Il est souvent utile de consigner l'adresse IP du client d'origine au lieu du serveur de l'équilibreur de charge. Ceci est facilement réalisé en apportant quelques modifications à la configuration de Nginx sur tous vos serveurs Web principaux.

Sur les deux serveurs Web, ouvrez le fichiernginx.conf dans un éditeur:

sudo nano /etc/nginx/nginx.conf

Recherchez la section «Paramètres de journalisation» (dans le blochttp) et ajoutez la ligne suivante:

ajouter à /etc/nginx/nginx.conf

log_format haproxy_log 'ProxyIP: $remote_addr - ClientIP: $http_x_forwarded_for - $remote_user [$time_local] ' '"$request" $status $body_bytes_sent "$http_referer" ' '"$http_user_agent"';

Sauvegarder et quitter. Cela spécifie un nouveau format de journal appeléhaproxy_log, qui ajoute la valeur$http_x_forwarded_for - l'adresse IP du client qui a effectué la demande d'origine - aux entrées du journal d'accès par défaut. Nous incluons également$remote_addr, qui est l'adresse IP de l'équilibreur de charge de proxy inverse (c.-à-d. le serveur d'équilibrage de charge actif).

Ensuite, pour utiliser ce nouveau format de journal, nous devons ajouter une ligne à notre bloc de serveur par défaut.

Sur les deux serveurs Web, ouvrez la configuration du serveurdefault:

sudo nano /etc/nginx/sites-available/default

Dans le blocserver (juste en dessous de la directivelisten est un bon endroit), ajoutez la ligne suivante:

ajouter à / etc / nginx / sites-available / default

        access_log /var/log/nginx/access.log haproxy_log;

Sauvegarder et quitter. Cela indique à Nginx d'écrire ses journaux d'accès en utilisant le format de journalhaproxy_log que nous avons créé ci-dessus.

Sur les deux serveurs Web, redémarrez Nginx pour appliquer les modifications:

sudo service nginx restart

Désormais, vos journaux d’accès Nginx doivent contenir les adresses IP réelles des clients qui font les demandes. Vérifiez cela en ajustant les journaux de vos serveurs d'applications, comme nous l'avons fait dans la section précédente. Les entrées du journal doivent ressembler à ceci:

New Nginx access logs:. . .
ProxyIP: load_balancer_private_IP - ClientIP: local_machine_IP - - [05/Nov/2015:15:05:53 -0500] "GET / HTTP/1.1" 200 43 "-" "curl/7.43.0"
. . .

Si vos journaux sont corrects, vous êtes prêt!

Conclusion

Dans ce guide, nous avons expliqué le processus complet de mise en place d’une infrastructure hautement disponible et équilibrée. Cette configuration fonctionne bien car le serveur HAProxy actif peut répartir la charge sur le pool de serveurs Web du backend. Vous pouvez facilement adapter ce pool à mesure que votre demande augmente ou diminue.

La configuration IP flottante etkeepalived élimine le point de défaillance unique au niveau de la couche d'équilibrage de charge, permettant à votre service de continuer à fonctionner même lorsque l'équilibreur de charge principal échoue complètement. Cette configuration est assez flexible et peut être adaptée à votre propre environnement d’application en configurant votre pile Web préférée derrière les serveurs HAProxy.

Related