7 min de lecture
Présentation de LinK, un gestionnaire d’IP virtuelle basé sur etcd
Nous venons de passer LinK, notre gestionnaire d’IP virtuelle, en open source.

LinK (LinK is not Keepalived) est un gestionnaire d’IP virtuelle permettant de mettre en place de la haute disponibilité. Son objectif est de simplifier le partage d’une même IP entre plusieurs machines. Nous open sourçons aujourd’hui cet outil sous licence MIT afin que chacun puisse l’utiliser et y contribuer.
Nous avons introduit des réseaux définis par logiciel (SDN) dans notre infrastructure grâce à LinK et SAND, dans le cadre du développement de notre service de clusters Elasticsearch hautement disponibles à la demande sur Scalingo (SAND sera présenté dans un prochain article).
LinK est un agent réseau qui permet à plusieurs hôtes de partager une IP virtuelle. Il détermine quel hôte doit associer cette IP virtuelle et informe les autres membres du réseau de l’hôte qui la possède. Un cas d’usage typique est celui où vous avez plusieurs proxies devant un cluster. L’un est le maître et l’autre est présent en cas de défaillance du maître. Ce proxy de secours associe l’IP virtuelle si le maître est détecté comme défaillant, afin que le cluster reste accessible.
Si vous souhaitez consulter directement le code source, celui de LinK est disponible sur ce dépôt GitHub.
Les objectifs
Nous avions plusieurs objectifs avant de commencer le développement de ce logiciel. Tout d’abord, aucun contrôleur central ne devait centraliser les informations. Dans un environnement hautement distribué, il est important de limiter autant que possible les communications. Disposer d’agents autonomes capables de réagir en cas de problème réseau est un avantage majeur. Ainsi, l’architecture de LinK doit être : un agent par hôte, et rien de plus. Aucun contrôleur central.
Un autre objectif important est de toujours avoir au moins un serveur associant l’IP virtuelle. En effet, cette IP est utilisée dans un contexte de haute disponibilité, elle doit donc toujours être accessible. À un instant donné, deux hôtes peuvent éventuellement associer l’IP virtuelle. Cela n’est pas problématique, car cela n’empêche pas cette IP d’être joignable.
Enfin, nous souhaitons respecter la philosophie UNIX : « faire une seule chose et bien la faire ». LinK est uniquement responsable de l’attribution des IP. Il ne gère pas l’équilibrage de charge ni d’autres aspects de plus haut niveau.
Pourquoi ne pas utiliser Keepalived ?
Nous utilisons déjà Keepalived pour certains de nos composants internes (DNS, load balancers, etc.) et nous avions initialement envisagé de l’utiliser pour ce mécanisme de bascule d’IP. Mais lors de la définition de cette solution, nous avons rencontré certaines limitations de Keepalived.
La limitation la plus importante concerne le nombre de planificateurs d’IP que Keepalived permet. Dans notre configuration, chaque base de données nécessite son propre planificateur d’IP virtuelle. Avec Keepalived, il faut spécifier un virtual_router_id différent dans la section vrrp_instance. Comme ce virtual_router_id est codé sur un seul octet dans le protocole VRRP, nous serions limités à 256 planificateurs d’IP virtuelle sur l’ensemble de notre infrastructure. Cela n’est pas acceptable, car cela nous limiterait à moins de 256 clusters. D’autres architectures ont été envisagées, mais chacune présentait des inconvénients significatifs.
En travaillant sur ce sujet, nous avons étudié le fonctionnement du partage d’IP dans Keepalived et constaté qu’il était relativement simple. La complexité de Keepalived vient du mécanisme de sélection de l’hôte (déterminer quel nœud doit posséder l’IP). Dans Keepalived, cela repose sur le protocole VRRP. Cependant, chez Scalingo, nous disposons déjà d’un composant distribué capable de gérer les élections et les leases : etcd. Enfin, en développant notre propre gestionnaire d’IP virtuelle, nous pouvons le piloter via une API REST, ce qui est bien plus simple que de modifier des fichiers de configuration sur disque.
Architecture de LinK
L’idée de l’architecture de LinK est de disposer d’un agent sur chaque hôte susceptible d’associer l’IP. Voici une vue d’ensemble d’une infrastructure utilisant LinK :

Chaque hôte possède une IP (dans la plage 192.168.0.0/16 dans cet exemple) et exécute un agent LinK. Tous les agents peuvent associer l’IP virtuelle (dans la plage 10.0.0.0/8). Etcd est accessible par tous les hôtes. Notez que seuls deux hôtes sont représentés ici, mais d’autres peuvent rejoindre ce réseau d’agents LinK.
Chaque agent exécute la machine à états suivante :

Elle comporte trois états différents :
ACTIVATED: cet agent associe l’IP virtuelleSTANDBY: cet agent ne possède pas l’IP virtuelle mais est disponible pour une électionFAILING: les vérifications de santé ont échoué, cet agent n’est pas disponible pour une élection
Et plusieurs événements peuvent survenir. Ces événements modifient l’état de l’agent :
fault: une erreur est survenue lors de la coordination avec les autres nœudselected: cet agent a été élu pour associer l’IP virtuelledemoted: cet agent a perdu la possession de l’IP virtuellehealth_check_fail: les vérifications de santé ont échouéhealth_check_success: les vérifications de santé ont réussi
Les vérifications de santé sont configurables. Elles permettent de détecter qu’un hôte est défaillant et ne doit pas associer l’IP. Actuellement, l’agent LinK utilise une connexion TCP vers l’hôte sur lequel il s’exécute pour détecter une défaillance.
Avec cette machine à états, chaque agent sait de manière autonome dans quel état il se trouve. Il est possible que deux agents soient simultanément dans l’état ACTIVATED. LinK est conçu pour gérer ce cas. Cela ne pose pas de problème, et les hôtes tentant de se connecter à l’IP virtuelle utiliseront l’un de ces hôtes.
Un élément reste à résoudre : comment synchroniser les agents LinK sans utiliser de contrôleur central ? Notre solution consiste à utiliser etcd, une base de données clé/valeur distribuée.
Synchronisation des agents
Les hôtes peuvent déterminer s’ils doivent associer l’IP grâce à etcd. Les agents LinK utilisent la fonctionnalité de lease d’etcd : un mécanisme de verrou avec expiration. Tous les agents tentent d’obtenir ce verrou. Celui qui y parvient le conserve pendant 6 secondes et associe l’IP virtuelle durant cette période. Toutes les 3 secondes, il tente de renouveler le lease (c’est-à-dire prolonger le verrou pour 6 secondes). S’il échoue, un autre agent obtient le lease et associe l’IP virtuelle.
Un peu de théorie sur ARP
ARP a été conçu à l’origine comme le lien entre les protocoles Ethernet et IP. Dans un réseau local, lorsqu’un hôte souhaite communiquer avec un autre hôte mais ne possède que son adresse IP, il doit découvrir son adresse MAC. Le mécanisme consiste à diffuser une requête ARP demandant l’adresse MAC correspondant à l’IP donnée. Afin d’accélérer ce processus, chaque hôte conserve un cache des associations IP / MAC. Ce cache ARP a une durée de vie courte.
Dans notre infrastructure d’exemple, si un hôte souhaite communiquer avec l’hôte 1 via son adresse 192.168.0.1, il envoie une requête ARP à tous les hôtes du réseau local demandant l’adresse MAC correspondant à 192.168.0.1. L’hôte 1 répond avec son adresse MAC, par exemple MAC 1.
Dans le cas de LinK, si l’hôte 1 associe l’IP virtuelle 10.0.0.1et qu’un autre hôte (hôte 3) tente de communiquer avec lui, l’hôte 1 répondra MAC 1 à la requête ARP. Un peu plus tard, l’hôte 2 obtient le lease etcd et associe l’IP virtuelle 10.0.0.1 L’hôte 3 possède alors une entrée dans son cache ARP pour l’adresse IP 10.0.0.1et envoie les messages à MAC 1, alors que l’hôte 2 associe désormais l’IP.
Ce problème est résolu en utilisant des requêtes ARP gratuites. Lorsqu’un agent associe l’IP, il diffuse une requête ARP gratuite où les adresses IP source et destination sont définies sur l’IP virtuelle et l’adresse Ethernet source correspond à celle de l’hôte de l’agent. Ainsi, tous les hôtes du réseau sont informés que cette adresse IP est associée à un agent spécifique, ce qui invalide leur cache.
Nous avons conçu LinK pour assurer le mécanisme de bascule entre deux proxies HAProxy en frontal des clusters de bases de données. LinK est désormais open source, car nous sommes convaincus qu’un gestionnaire d’IP virtuelle simple, propre, tolérant aux pannes et fortement distribué peut être utile à beaucoup d’entre vous. Nous continuerons à l’utiliser et à le faire évoluer en interne. Les contributions externes sont les bienvenues, nous acceptons les pull requests. N’hésitez pas à l’utiliser, le code source de LinK est disponible dans ce dépôt GitHub.
Photo par Fabio Ballasina sur Unsplash

Jonathan Hurter
Jonathan était l'un des premiers développeurs de Scalingo et il fait partie de l'entreprise depuis 2016. Autant vous dire qu'il connaît bien la plateforme Scalingo. En parallèle, il est également actif dans la scène associative strabourgeoise. Lorsqu'il a un peu de temps, il rédige des articles sur ce blog.
Restez informé
Recevez des articles et des mises à jour de la plateforme dans votre boîte de réception.
Prêt à déployer en toute confiance ?
Découvrez des déploiements sans temps d'arrêt, une mise à l'échelle automatique intelligente et une infrastructure entièrement gérée. Commencez à déployer vos applications sur Scalingo dès aujourd'hui.
Aucune carte de crédit requise • Déployez en quelques minutes • Annulez à tout moment





