Comment configurer des serveurs Web hautement disponibles avec des IP persistantes 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 un service Web hautement disponible. Nous allons configurer unfloating IP address qui peut être déplacé entre deux serveurs Web capables. Si le serveur principal tombe en panne, l'adresse IP flottante sera automatiquement déplacée vers le second serveur, permettant ainsi au service de reprendre.

Conditions préalables

Afin de compléter ce guide, vous devrez créer deux serveurs Ubuntu 14.04 sur votre compte DigitalOcean. Les deux serveurs doivent être situés dans le même centre de données et la mise en réseau privée doit être activée.

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.

Lorsque vous êtes prêt à commencer, connectez-vous à vos deux serveurs avec votre utilisateur non root.

Installer et configurer Nginx

Alors quekeepalived est souvent utilisé pour surveiller et basculer les équilibreurs de charge, afin de réduire notre complexité opérationnelle, nous utiliserons Nginx comme un simple serveur Web dans ce guide.

Commencez par mettre à jour l'index de package local sur chacun de vos serveurs. Nous pouvons alors installer Nginx:

sudo apt-get update
sudo apt-get install nginx

Dans la plupart des cas, pour une configuration hautement disponible, vous voudriez que les deux serveurs servent exactement le même contenu. Toutefois, dans un souci de clarté, nous utiliserons dans ce guide Nginx pour indiquer lequel des deux serveurs répond à nos demandes à un moment donné. Pour ce faire, nous allons changer la page par défautindex.html sur chacun de nos hôtes. Ouvrez le fichier maintenant:

sudo nano /usr/share/nginx/html/index.html

Sur votre premier serveur, remplacez le contenu du fichier par ceci:

Le serveur principal /usr/share/nginx/html/index.html

Primary

Sur votre deuxième serveur, remplacez le contenu du fichier par ceci:

Le serveur secondaire /usr/share/nginx/html/index.html

Secondary

Enregistrez et fermez les fichiers lorsque vous avez terminé.

Construire et installer Keepalived

Ensuite, nous installerons le démonkeepalived sur nos serveurs. 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êchent 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-packagebuild-essential fournira les outils de compilation dont nous avons besoin, tandis que le packagelibssl-dev contient les bibliothèques 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, puis accédez au 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 le système.

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 notre fichier 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 serveurs:

sudo mkdir -p /etc/keepalived

Collecte des adresses IP privées de vos serveurs

Avant de créer le fichier de configuration, nous devons trouver les adresses IP privées de nos deux serveurs. Sur les serveurs DigitalOcean, vous pouvez obtenir notre adresse IP privée via le service de métadonnées en tapant:

curl http://169.254.169.254/metadata/v1/interfaces/private/0/ipv4/address && echo
Output10.132.7.107

Cela peut également être trouvé avec les outilsiproute2 en tapant:

ip -4 addr show dev eth1

La valeur que vous recherchez se trouve ici:

Output3: eth1:  mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    inet 10.132.7.107/16 brd 10.132.255.255 scope global eth1
       valid_lft forever preferred_lft forever

Copiez cette valeur à partir de vos deux systèmes. Nous devrons faire référence à ces adresses dans nos fichiers de configuration ci-dessous.

Création de la configuration du serveur principal

Ensuite, sur votre serveur principal, 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 Nginx en ouvrant un blocvrrp_script. Cela permettra àkeepalived de surveiller notre serveur Web 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énginx réclame toujours unpid:

/Etc/keepalived/keepalived.conf du serveur principal

vrrp_script chk_nginx {
    script "pidof nginx"
    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 serveurprimary que nous avons récupérée précédemment. Nous allons définirunicast_peer sur l'adresse IP privée de notre serveursecondary:

/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

    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é des serveurs en question. 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_nginx {
    script "pidof nginx"
    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 la routine que nous avons créée en haut du fichier, étiquetéechk_nginx, 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_nginx {
    script "pidof nginx"
    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_nginx
    }

    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 du serveur secondaire

Ensuite, nous allons créer le script compagnon sur notre serveur 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_nginx {
    script "pidof nginx"
    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_nginx
    }

    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 devrons 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 le Droplet dans la liste que vous avez attribuée en tant que serveur «principal»:

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 visitez l'adresse IP flottante dans votre navigateur Web, vous devriez voir la page du serveur «principal»index.html:

DigitalOcean primary 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 sur les serveursboth 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 machines 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 Nginx local et écoutera les signaux du processus distantkeepalived.

Lorsque les deux serveurs sont en bon état, si vous consultez votre IP flottante dans votre navigateur Web, vous devriez accéder à la page Nginx du serveur principal:

DigitalOcean primary index.html

Nous sommes maintenant prêts à tester les fonctionnalités de basculement de notre configuration.

Le basculement doit avoir lieu lorsque l'une des conditions suivantes est remplie:

  • When the Nginx health check on the primary server indicates that Nginx is no longer running. Dans ce cas, le démonkeepalived du serveur primaire passera à l'état «fault». Il informera le serveur secondaire qu'il doit passer à l'état maître et revendiquer l'adresse IP flottante.

  • When the secondary server loses its keepalived connection to the primary server. Si le serveur secondaire ne peut pas atteindre le serveur principal pour une raison quelconque, il passera à l'état «maître» et tentera de revendiquer l'adresse IP flottante.

Si le serveur principal récupère plus tard, il reviendra à l'état maître et récupérera l'adresse IP flottante car il initiera une nouvelle élection (il aura toujours le numéro de priorité le plus élevé).

Test d'échec Nginx

Nous pouvons tester la première condition en arrêtant le service Nginx sur le serveur principal:

sudo service nginx stop

Si vous actualisez votre navigateur Web, vous pourriez initialement obtenir une réponse indiquant que la page n'est pas disponible:

DigitalOcean page not available

Cependant, au bout de quelques secondes à peine, si vous actualisez la page plusieurs fois, vous constaterez que le serveur secondaire a revendiqué l'adresse IP flottante:

DigitalOcean secondary index.html

Nous pouvons récupérer de l’échec en redémarrant le démon Nginx sur le serveur principal:

sudo service nginx start

Après quelques secondes, si vous actualisez la page, vous constaterez que le serveur principal a de nouveau récupéré la propriété de l'adresse IP flottante:

DigitalOcean primary index.html

Test de panne de serveur

L'autre scénario à tester consiste à déterminer si le serveur secondaire passe correctement à l'état maître s'il ne peut pas se connecter au serveur principal. Nous pouvons redémarrer le serveur maître pour tester ceci:

sudo reboot

Encore une fois, nous devrions d’abord voir une interruption de service à l’adresse IP flottante:

DigitalOcean page not available

Quelques secondes plus tard, le serveur secondaire récupérera les demandes:

DigitalOcean secondary index.html

Un instant plus tard, lorsque le serveur principal aura terminé le redémarrage, il récupérera l'adresse IP:

DigitalOcean primary index.html

Ceci vérifie notre deuxième scénario d'échec.

Conclusion

Dans ce guide, nous avons configuré un environnement de serveur Web hautement disponible à l'aide dekeepalived, de l'API DigitalOcean et d'une adresse IP flottante. L'infrastructure réelle était plutôt simple, mais les concepts peuvent être appliqués à tout type d'infrastructure où la disponibilité et la disponibilité des services sont importantes.

Related