URL: https://linuxfr.org/news/ameliorer-la-disponibilite-de-ses-services Title: Améliorer la disponibilité de ses services Authors: Denis Dordoigne BAud, Nÿco, palm123, Tonton Th, Benoît Sibaud, Nils Ratusznik et Bruno Michel Date: 2014年07月15日T06:54:24+02:00 License: CC By-SA Tags: haute_disponibilité, architecture, disponibilité, répartiteur, actif_actif, actif_passif et hébergement Score: 59 Votre aventure d'hébergeur amateur prend de l'ampleur. Depuis quelques mois, vous avez réussi à [gérer plusieurs services de façon transparente](http://linuxfr.org/news/gerer-plusieurs-services-de-facon-transparente), mais maintenant que vous avez de plus en plus d'utilisateurs de vos services, vous vous rendez compte que votre unique serveur web est surchargé et que chaque maintenance provoque des coupures de service que ne comprennent pas vos visiteurs. Afin de répondre à cette problématique, le plus simple est de multiplier les serveurs : la charge sera répartie entre les différents serveurs et vous pourrez couper un serveur pour une maintenance, sans couper le service associé. ---- ---- # Étape 1 : digérer quelques concepts # Afin de simplifier les explications et de coller à ce qui est probablement votre cas d'usage, nous considérerons dans ce tutoriel que nous travaillons dans une infrastructure totalement [[IPv4]]. ## Répartition de charge ## La [[répartition de charge]] « _est un ensemble de techniques permettant de distribuer une charge de travail entre différents ordinateurs d'un groupe. Ces techniques permettent à la fois de répondre à une charge trop importante d'un service en la répartissant sur plusieurs serveurs, et de réduire l'indisponibilité potentielle de ce service que pourrait provoquer la panne logicielle ou matérielle d'un unique serveur_ »[^1] . On distingue deux grands types de répartition de charge : * la répartition parallèle (« actif / actif ») : plusieurs serveurs offrent de façon simultanée le service, le répartiteur de charge peut envoyer une requête indifféremment à chaque serveur ; * la répartition séquentielle (« actif / passif ») : plusieurs serveurs sont capables de rendre le service, mais le répartiteur de charge n'envoie des requêtes qu'à un seul d'entre eux ; l'envoi de requête à un autre serveur ne sera fait que si le serveur nominal n'est plus en mesure de prendre en compte les requêtes. Le mode séquentiel ne permet pas de répartir la charge de travail à proprement parler puisque seul un serveur rend le service à la fois, en revanche cela répond bien au besoin de ne pas interrompre le service en cas de coupure d'un serveur. ## Adresse IP virtuelle ## Une adresse IP virtuelle (parfois appelée « vIP » ou « serveur virtuel », même si l'usage de ce dernier terme est tombé en désuétude suite à l'arrivée des « machines virtuelles » et le risque de confusion associé) est l'adresse IP d'un service faisant l'objet d'une répartition de charge : l'adresse est dite virtuelle parce qu'elle n'est portée par aucun serveur à proprement parler, mais par un groupe de serveurs, défini dans la configuration du répartiteur de charge. L'adresse IP virtuelle peut être utilisée comme n'importe quelle adresse IP, on doit notamment en autoriser l'accès depuis le pare-feu comme on le ferait pour l'adresse IP d'un serveur. ## Test de vie ## Puisqu'on demande au répartiteur de charge de n'envoyer les requêtes qu'aux serveurs en état de les traiter, il faut lui donner les moyens de définir quels serveurs sont hors-service. Pour cela, on va configurer un ou plusieurs tests de vie par service, par exemple : * un ping du serveur cible (test rarement pertinent, mais dans le cadre d'un réseau local non filtré et non routé, on peut considérer que si un serveur ne répond pas au ping c'est qu'il n'est plus en état de rendre le service) * une connexion TCP sur un port (si le serveur ne permet pas d'ouvrir une connexion sur le port 443, il ne rend à priori pas le service HTTPS) * un test applicatif (pour un serveur HTTP on peut vérifier qu'un « GET / » ne renvoie pas une erreur 500) * un test de service (pour un serveur HTTP hébergeant un wiki on peut aller jusqu'à tester qu'une modification de page réussit). Les tests de vie sont associés à une fréquence d'exécution, qui définira la durée maximale pendant laquelle on accepte qu'un serveur HS continue de recevoir des requêtes (par exemple, si on veut que le serveur ne reçoive plus de requêtes moins de 2 secondes après être tombé, il faut mettre en place un test de vie toutes les secondes), il faut donc veiller : * à avoir un test de vie plus rapide que votre fréquence d'exécution (si vous lancez un test qui prend 5 secondes chaque seconde, ceux-ci vont s'empiler sur les serveurs) ; * à ne pas avoir des tests de vie qui deviennent une cause de surcharge des serveurs rendant le service (pour reprendre l'exemple du wiki, si vous avez 30 éditions par jour habituellement en faisant une édition par test de vie vous allez subitement en avoir des milliers). ## Ordonnanceur de répartition ## Dans le cadre d'une répartition parallèle, chaque requête vers une adresse IP virtuelle est envoyée à un ordonnanceur qui se charge de définir par quel serveur la requête doit être traitée, parmi tous les serveurs détectés comme vivants. Il y a 3 grandes familles d'ordonnanceurs : * les ordonnanceurs impartiaux : si on a 1000 requêtes réparties entre 4 serveurs, chaque serveur en traitera 250 ; pour cela l'algorithme généralement utilisé est le [round-robin](http://fr.wikipedia.org/wiki/Round-robin_%28informatique%29) (les serveurs reçoivent une requête chacun leur tour), mais certains répartiteurs de charge proposent également des ordonnanceurs basés sur un algorithme [aléatoire](http://fr.wikipedia.org/wiki/Pseudo-al%C3%A9atoire) * les ordonnanceurs compensateurs : la requête est envoyée au serveur qui la traitera le plus vite (l'algorithme généralement utilisé est d'envoyer au serveur qui a le moins de connexions actives), l'ordonnanceur se charge donc de compenser l'éventuelle lenteur d'un serveur en lui envoyant moins de requêtes ; attention : même si cela n'est pas intuitif, un serveur défaillant traite souvent les requêtes plus rapidement qu'un serveur fonctionnel (un accès refusé à une base de données peut prendre quelques millisecondes quand le traitement d'une requête peut prendre plusieurs secondes), donc ce type d'ordonnanceur favorisera les serveurs défaillants si votre test de vie n'est pas suffisamment bien conçu pour que ceux-ci ne soient plus considérés comme vivants * les ordonnanceurs déterministes : une [[fonction de hachage]] appliquée à la requête reçue permet de définir le serveur qui traitera la requête ; il y a deux principaux types de déterminisme : * déterminisme [réseau](http://fr.wikipedia.org/wiki/Couche_r%C3%A9seau) : une même adresse IP source (ou un même couple adresse/port) enverra toujours au même serveur ; à noter que si vous avez de nombreux utilisateurs derrière un même proxy la répartition ne sera pas optimale ; * déterminisme [applicatif](http://fr.wikipedia.org/wiki/Couche_application) : la même demande (par exemple "GET /login.php") enverra toujours au même serveur (en général la requête est analysée au niveau de la [[couche application]], l'analyse du paquet TCP n'étant pas suffisante pour calculer un hash pertinent). Les ordonnanceurs acceptent parfois des options : * gestion des poids : on peut donner des poids différents aux serveurs pointés par une adresse virtuelle afin que ceux-ci soient privilégiés par l'algorithme de répartition (par exemple un ordonnanceur impartial enverra deux fois plus de connexions à un serveur de poids 10 qu'à un serveur de poids 5). * persistance de session : l'ordonnanceur n'est appelé que pour la première connexion d'un client, puis le répartiteur de charge conserve dans une table de sessions le serveur cible associé à ce client : tant que ce serveur sera vu vivant, toutes les requêtes du client lui seront envoyées. ## Un peu de routage ## Vous allez donc avoir des connexions qui vont arriver depuis vos répartiteurs de charge vers vos serveurs ; maintenant, il faut se poser une question : comment répondre au client qui a fait la requête ? Il y a deux écoles, chacune ayant ses avantages et inconvénients. ### Méthode 1 : tout passe par le répartiteur de charge ###  Les connexions arrivent au répartiteur de charge ? Qu'elles y retournent ! Cette méthode qui est la plus utilisée consiste à répondre aux requêtes envoyées par le répartiteur de charge au répartiteur de charge lui-même, celui-ci s'occupant de les renvoyer sur Internet. Il y a deux façons de procéder : * le NAT source : le repartiteur de charge se présente au serveur avec sa propre adresse IP, la réponse est faite naturellement à cette adresse * avantages : cela fonctionne avec à peu près tous les services imaginables sans avoir à modifier le serveur cible, si on n'a pas que du logiciel libre côté serveur cela simplifiera grandement les choses ; * inconvénients : comme dans le cas d'un proxy, le serveur ne verra pas l'adresse IP d'origine, cela complique la gestion des traces que l'on doit conserver dans le cadre de la loi pour la confiance dans l'économie numérique, le diagnostic des problématiques rencontrées par certains utilisateurs et la mise en place de contrôles d'accès. * le routage statique : le répartiteur de charge envoie les connexions telles quelles au serveur, mais celui-ci dispose d'un routage statique pour renvoyer toutes les requêtes provenant d'Internet au répartiteur de charge * avantages : on n'a pas les inconvénients du NAT ; * inconvénients : il faut maintenir une table de routage pour chaque serveur en y listant l'ensemble des réseaux et services auxquels on est susceptible de devoir accéder sans passer par le répartiteur de charge. ### Méthode 2 : faisons travailler le serveur ###  Cette méthode consiste à déléguer au serveur la réponse aux clients, sans repasser par le répartiteur de charge : * avantage : le répartiteur de charge se comporte comme un simple routeur, il consomme donc peu de ressources système, une machine virtuelle minuscule est suffisante pour rendre ce service ; * inconvénient : cela nécessite de bidouiller les serveurs pour que ceux-ci acceptent de gérer des communications réseau peu orthodoxes et, en général, et dans ce cas hors système Linux cela s'avère complexe à mettre en œuvre. Il y a deux façons de gérer ces connexions : * le routage direct : on fait croire à chaque serveur qu'il est porteur de l'adresse IP virtuelle afin qu'il traite les connexions concernant cette adresse IP comme une connexion à une adresse IP locale ; * le tunnel IP-IP : le répartiteur de charge envoie la connexion dans un tunnel et le serveur traite les connexions venant de son interface tunnel comme une connexion à une adresse IP locale (on préfère cette méthode au routage direct uniquement quand le répartiteur de charge n'est pas dans le même réseau que le serveur). # Étape 2 : multiplier les serveurs # Maintenant que vous savez que vous pouvez repartir la charge entre plusieurs serveurs, vous allez pouvoir commencer à multiplier ceux-ci : attention cependant à vous poser les bonnes questions. ## Mon service est-il multipliable ? ## Certains services nécessitant une ressource locale ne peuvent pas faire l'objet d'une répartition de charge. Par exemple, une base SQLite ne garantit sa cohérence que si elle est capable de poser un verrou sur un fichier : un verrou de fichier étant local à un serveur, il n'est pas possible de partager une telle base de données entre différents serveurs. Dans ce type de cas, un répartiteur de charge séquentiel peut devenir intéressant : on peut installer plusieurs serveurs mais demander au répartiteur de charge de n'en adresser qu'un seul à la fois, ainsi toutes les requêtes accéderont à la même ressource locale. ## Mes ressources sont-elles accessibles de partout ? ## Votre service utilise probablement des fichiers locaux et/ou des informations en mémoire pour fonctionner, il convient donc de s'assurer que celles-ci sont accessibles par tous les serveurs rendant le service. Il faut surtout se poser la question des informations de session que peut porter le service : celles-ci doivent être dans un espace partagé (il est commun de stocker des sessions php dans un montage NFS par exemple) ou dans un outil qui sait gérer la replication (une base de données en réseau par exemple). Si vous ne pouvez pas partager ou répliquer les informations de session entre vos différents serveurs, il conviendra de veiller à ce qu'un client ne change jamais de serveur pendant sa session, soit en utilisant la fonctionnalité de persistance de session de votre répartiteur de charge, soit en utilisant un ordonnanceur déterministe. ## Comment gérer mon routage ? ## On peut se contenter de faire du NAT et ne pas se poser la question. C'est même la solution préconisée par de nombreux outils de répartition de charge. Cependant, si le NAT ne répond pas à votre besoin pour une des raisons indiquées précédemment (obligation légale, contrôle d'accès, besoin d'investigation) ou tout simplement parce que votre applicatif ou votre protocole ne le gère pas, la mise en place d'une infrastructure répartie peut affecter la configuration de votre serveur. ### Définition d'un routage statique ### Le plus simple lorsqu'on fait le choix d'un routage statique est de configurer le répartiteur de charge comme passerelle par défaut de votre serveur. Cependant, si votre serveur ne fait pas que répondre à des requêtes en utilisant des ressources locales (par exemple s'il s'agit d'un serveur mail, il doit aussi communiquer avec le reste du monde pour envoyer des mails), il va falloir gérer un routage différent pour ces autres besoins : si votre applicatif le permet vous pouvez envoyer ces connexions à une interface réseau spécifique qui ne passera pas par la passerelle par défaut, sinon il faudra envisager l'usage d'un [système de routage intelligent](https://en.m.wikipedia.org/wiki/Policy_based_routing). ### Gérer le routage direct ### Si vous avez une plate-forme 100% Linux, n'hésitez pas à faire ce choix, il faudra juste autoriser le trafic d'ARP en ajoutant cela dans votre sysctl.conf : ``` net.ipv4.conf.all.arp_ignore=1 net.ipv4.conf.all.arp_announce=2 net.ipv4.conf.eth0.arp_ignore=1 net.ipv4.conf.eth0.arp_announce=2 ``` (il faut le faire pour all et pour l'interface avec laquelle vous communiquez avec le répartiteur de charge) ; si vous n'avez pas prévu de redémarrer votre serveur, vous pouvez forcer la prise en compte de vos modifications : ``` # sysctl -p ``` Ensuite, il convient de faire comprendre au serveur qu'il gère l'adresse IP virtuelle. Le plus propre pour faire cela est de déclarer celle-ci comme un alias de l'interface de loopback : ``` # ifconfig lo:9 lo:4 Link encap:Boucle locale inet adr:192.168.10.9 Masque:255.255.255.255 UP LOOPBACK RUNNING MTU:16436 Metric:1 ``` # Étape 3 : mon premier répartiteur de charge # [[Linux Virtual Server]], abrégé en LVS, est un logiciel répartiteur de charge pour GNU/Linux. Il peut se configurer simplement en ligne de commande, mais afin de gérer simplement la configuration on utilise en général un logiciel spécialisé, dans ce tutoriel ce sera _keepalived_. ## installation ## ### Machines ### Pour installer ce service, une simple machine virtuelle avec quelques centaines de Mo d'espace disque et quelques dizaines de Mo de mémoire suffira. Et puis comme on veut gérer la redondance en cas de panne, on va même en installer deux ! ### Paquets ### Sur une Debian fraîchement installée avec le système de base, installer le paquet **keepalived** avec toutes ses dépendances mais sans les paquets recommandés : ``` # apt-get install keepalived Lecture des listes de paquets... Fait Construction de l'arbre des dépendances Lecture des informations d'état... Fait Les paquets supplémentaires suivants seront installés : ipvsadm libnl1 Paquets suggérés : heartbeat ldirectord Les NOUVEAUX paquets suivants seront installés : ipvsadm keepalived libnl1 0 mis à jour, 3 nouvellement installés, 0 à enlever et 0 non mis à jour. Il est nécessaire de prendre 331 ko dans les archives. Après cette opération, 995 ko d'espace disque supplémentaires seront utilisés. ``` Bien entendu ça fonctionne aussi bien avec d'autres distributions... ### Paramètres système ### Ajouter le paramètre suivants dans **/etc/sysctl.conf*** : ``` # Parametres pour le LVS net.ipv4.ip_forward=1 ``` Charger la configuration : ``` # sysctl -p net.ipv4.ip_forward = 1 ``` ### Configuration de base ### Source : http://www.keepalived.org/documentation.html Debian ne génère aucune configuration à l'installation, il faut donc créer le fichier **/etc/keepalived/keepalived.conf** après l'installation. Pour commencer, il faut y mettre la section globaldefs qui permet de définir la configuration de base : ``` global_defs { notification_email { georgette@example.com } notification_email_from lvs@example.com smtp_server relayhost.example.com smtp_connect_timeout 30 router_id LVS } vrrp_sync_group VG1 { group { linuxfr } } ``` Voici l'explication des paramètres : * **notification_email** : liste des adresses (séparées par des sauts de ligne) notifiées en cas de changement d'état d'une adresse IP virtuelle (enverra par exemple un e-mail lorsqu'un serveur ne répond plus) ; ne pas mettre cette ligne si on ne désire pas être notifié * **notification_email_from**, **smtp_server**, **smtp_connect_timeout** : paramètres d'expédition des mails * **router_id** : le petit nom donné au service LVS, comme on n'en a qu'un sur la plateforme, on va faire simple en mettant _LVS_, mais on peut faire plus intelligent * **group** : liste des instances déclarées (voir ci-dessous) ### Configuration de l'instance ### Toujours sans keepalived.conf, on peut créer plusieurs instances ayant chacune leur configuration (par exemple "prod" et "dev"), pour commencer on ne va en créer qu'une, nommée linuxfr : ``` vrrp_instance linuxfr { state MASTER interface eth0 smtp_alert virtual_router_id 51 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 192.168.2.9 } } ``` Explication des paramètres : * **vrrp_instance** : début du bloc de paramètres de l'instance, doit être suivi du nom de l'instance (ici _linuxfr_) * **state** : il s'agit de la seule différence entre la configuration du LVS primaire et du LVS secondaire : l'un d'entre eux doit être "MASTER", l'autre "SLAVE" (c'est pour cela qu'on peut se permettre de metre en place deux serveurs dès le début, la mise en place du second tient à un copier/coller suivi de cette seule modification) * **interface** : nom de l'interface surveillée par le service * **smtp_alert** : à positionner ou non selon que l'on souhaite avoir des notification par courriel des défaillances * **virtual_router_id** : on peut mettre n'importe quel nombre entre 0 et 255, il faut juste qu'il soit différent entre les différentes instances * **authentication**, **auth_type**, **auth_pass** : identifiants utilisés par les serveurs LVS pour communiquer entre eux, notez cependant que ces informations circulent en clair dans le réseau * **virtual_ipaddress** : liste des adresses virtuelles portées par le LVS (une par ligne, 20 maximum) ; c'est la partie que vous oublierez systématiquement de remplir en ajoutant de nouvelles adresses IP virtuelles, et vous perdrez 5 minutes à chercher pourquoi ça ne marche pas ## Ma première adresse IP virtuelle ## Dans cet exemple, nous déclarons une adresse virtuelle suivante 192.168.10.9 qui renvoie le port 80 vers le port 80 des serveurs 192.168.10.98 et 192.168.10.85. ### Rappel des pré-requis pour le routage direct ### * vos répartiteurs de charge doivent être dans le même réseau que vos serveurs (sinon configurez votre LVS pour utiliser des tunnels) * vos serveurs doivent accepter le trafic ARP entre leurs interfaces (cf. paramètres systcl plus haut, si vous n'avez pas la main sur vos serveurs, configurez votre LVS pour faire du NAT source) * chaque serveur doit croire qu'il porte l'adresse IP du service (ici on déclarera un alias de l'interface de loopback avec l'adresse IP 192.168.10.9) * l'adresse doit être connue du bloc virtual_ipaddress de votre instance LVS (certes on vous l'a déjà précisé dans le paragraphe précédent, mais on sait que vous allez l'oublier) ### Déclaration dans keepalived.conf ### ``` virtual_server 192.168.10.9 80 { delay_loop 6 lb_algo rr lb_kind DR protocol TCP real_server 192.168.10.98 80 { weight 1 TCP_CHECK { connect_port 80 connect_timeout 3 } } real_server 192.168.10.85 80 { weight 1 TCP_CHECK { connect_port 80 connect_timeout 3 } } } } ``` * **virtual_server** : doit être suivi de l'adresse IP virtuelle puis du port * **delay_loop** : délai entre deux tests de vie (n'oubliez pas que vous avez deux serveurs LVS, donc vos serveurs se prendront deux fois la charge correspondante) * **lb_algo** : l'algorithme utilisé par l'ordonnanceur ; les plus utilisés sont rr (round-robin) et lc (moins de connexions actives) avec leurs équivalents wrr et wlc prenant en compte les poids ; la liste complète des algorithmes est disponible dans http://www.linuxvirtualserver.org/docs/scheduling.html * **lb_kind** : méthode d'accès aux serveurs, pour du routage direct on indique '''DR''' * **real_server** : doit être suivi de l'adresse IP d'un serveur et du port du service. Il faut autant de blocs real_server qu'il y a de serveurs derrière l'adresse virtuelle * **weight** : poids, notamment utilisé pour les algorithmes wlc et wrr ; par défaut, le poids est 1 * **TCP_CHECK** : test de vie de type ouverture de connexion TCP ; dans cette exemple si une connexion au port 80 prend plus de 3 secondes, le serveur n'est plus considéré comme vivant ## On s'en fait une deuxième ? ## Vous avez probablement plus d'un service à répartir, donc il faudra créer une adresse IP virtuelle par service. ### Choix de l'adresse IP ### Pour votre deuxième service vous pouvez soit attribuer une nouvelle adresse IP, soit réutiliser celle d'une adresse de service existante, à condition évidemment que ce soit sur un port différent (et en plus comme ça elle est déjà dans le bloc virtual_servers, vous ne l'oublierez pas pour une fois). ### Ajout de quelques options ### ``` persistence_timeout 60 virtualhost supervision.fr.local quorum 30 hysteresis 2 quorum_up "/usr/local/bin/notify.pl qourum up" quorum_down "/usr/local/bin/start_spare_vm.pl" sorry_server 192.168.10.55 80 ``` * persistence_timeout : mettre un nombre de secondes si on veut activer la persistance de session ; pendant ce nombre de secondes, une même adresse IP source sera systématiquement envoyée au même serveur sans que l'ordonnanceur ne soit sollicité * quorum : poids total des serveurs actifs nécessaire pour considérer l'adresse virtuelle comme pleinement opérationnelle * quorum_down : commande à lancer quand le quorum n'est plus atteint, en général on met une commande qui envoie une alarme par sms ou dans l'outil de supervision, mais selon votre architecture vous pouvez aussi envisager de démarrer automatiquement des serveurs supplémentaires, d'activer une version allégée de vos services, etc. * quorum_up : commande à lancer une fois que le quorum est de nouveau atteint * hystérésis : différence de poids minimum entre deux appels de commande quorum_up/quorum_down ; par exemple dans notre cas si un quorum_down a été détecté à 29, le quorum_up ne sera pas appelé lors du passage à 30 mais seulement lors du passage à 31 ; cette fonctionnalité permet d'éviter d'appeler les commandes trop souvent lorsqu'on est proche des limites, c'est surtout utile si la commande appelée est particulièrement lourde * sorry_server : serveur auquel seront envoyées les requêtes si aucun des serveurs pointés par l'adresse virtuelle ne répond ; pour un service web ça pourrait être un mini serveut hébergeant une simple page html d'excuses * virtualhost : pour un service web, nom de domaine vers lequel seront envoyés les tests de vie HTTP ou HTTPS (cf. paragraphe suivant) ### Choix du test de vie ### Pour notre première adresse IP virtuelle nous avons choisi un test de vie TCP, mais keepalived permet d'autres tests de vie. #### GET d'une URL #### ``` HTTP_GET { url { path /test_vie.php digest 5f1a4b7e269b7f5ddf6bbce06856c1e8 status_code 200 } connect_port 80 connect_timeout 3 } ``` Si la page test_vie.php n'est pas dans le virtual host par défaut de votre serveur web, il faudra préciser le paramètre _virtualhost_ dans la configuration de l'adresse IP virtuelle. Le paramètre _digest_ correspond au hash MD5 de la réponse du serveur, on peut le récupérer avec la commande suivante : ``` # genhash -s 192.168.10.85 -p 80 -u /test_vie.php MD5SUM = 5f1a4b7e269b7f5ddf6bbce06856c1e8 ``` Veuillez noter que : * on peut ne mettre qu'une seule information entre _digest_ et _status_code_ (code retour HTTP, a priori ce sera 200) * on peut déclarer autant de blocs url{} que l'on veut dans un test, le serveur ne sera plus vu vivant si un seul d'entre eux échoue * si on veut faire un test en HTTPS, il faut nommer le bloc SSL_GET au lieu de HTTP_GET (et pour récupérer le digest ajouter l'option « -S » à la commande genhash) * le digest dépend du contenu de la page, n'ayez pas de contenu dynamique dedans ! Afficher l'heure ou la durée d'affichage par exemple ferait tomber systématiquement le test en erreur ; par contre c'est utile pour valider que tout va bien, par exemple on peut faire une page qui affiche « OK » quand elle arrive à accéder à la base de données, et « KO » sinon : le digest n'étant retrouvé que lorsque la page affiche OK, le répartiteur de charge n'enverra pas de trafic aux serveurs incapables d'accéder à la base de données #### test personnalisé #### Il est possible d'écrire un script qui sera utilisé pour les checks, par exemple pour tester qu'un serveur LDAP est opérationnel, on fera un script qui fait une requête LDAP : ``` MISC_CHECK { misc_path "/usr/local/bin/test_ldap.pl 192.168.10.72" misc_timeout 15 # misc_dynamic } ``` Le script doit simplement renvoyer 0 si le serveur est vivant, et une autre valeur si ce n'est pas le cas. Ici on n'a pas opté pour l'option misc_dynamic (elle est commentée), mais on peut l'activer si on utilise les algorithmes wrr ou wlc, dans ce cas le code retour du script sera interprété ainsi : * 0: le serveur est vivant, son poids doit rester celui configuré dans keepalived.conf * 1 : le serveur n'est pas vivant, plus aucune requête ne doit lui être envoyé * de 2 à 255 : le serveur est vivant, mais son poids doit être changé par la valeur renvoyée moins deux (par exemple si le script a un code retour de 10 le nouveau poids du serveur sera 8) # Étape 4 : Exploitons tout ça # Votre service est configuré, il n'y a plus qu'à le lancer ! ``` # service keepalived start ``` Keepalived permet seulement de gérer une configuration pour LVS, sans donner d'outils d'exploitation supplémentaires. Pour ensuite suivre la vie de votre service LVS, il faut utiliser la commande **ipvsadm**. ## Extraire des statistiques ## L'option **--list** (abréviations : -l ou -L) permet de lister toutes les adresses virtuelles portées par votre répartiteur de charge avec le nombre de connexions en cours pour chacun des serveurs qu'elles contiennent. En y ajoutant l'option **--stats**, vous aurez en plus des statistiques réseau : ``` # ipvsadm -ln -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 192.168.10.9:443 rr persistent 1 -> 192.168.10.70:443 Route 1 0 0 -> 192.168.10.85:443 Route 1 0 0 TCP 192.168.10.9:80 rr persistent 50 -> 192.168.10.70:80 Route 1 416 136 -> 192.168.10.85:80 Route 1 48 91 ``` La plupart des outils de monitoring savent interpréter ces chiffres pour sortir des graphes qui peuvent vous être utiles, par exemple voici ce que donne un suivi de nombre de connexions en cours avec [[munin]] :  ## Manipuler vos adresses virtuelles dynamiquement ## Si vous avez décidé d'utiliser le paramètre _quorum_down_ pour adapter votre architecture dynamiquement, vous pouvez vouloir ajouter des serveurs dans la liste de ceux portés par une adresse virtuelle dynamiquement. Pour cela, il faut utiliser l'option **--add-server** (abrégeable en -a), il y a bien évidemment une option **--delete-server** pour faire l'inverse : ```bash # ajout du serveur 192.168.10.44 # à l'adresse virtuelle 192.168.10.9:80 ipvsadm -a -t 192.168.10.9:80 -r 192.168.10.75 # retrait du serveur 192.168.10.44 # de l'adresse virtuelle 192.168.10.9:80 ipvsadm -d -t 192.168.10.9:80 -r 192.168.10.75 ``` [^1]: Source : Article [[Répartition de charge]] de Wikipédia en français - [Liste des auteurs](http://fr.wikipedia.org/w/index.php?title=R%C3%A9partition_de_charge&action=history)