RR DNS et VIP multiples :
répartir sans aucun composant central
C'est le seul niveau de répartition qui n'ajoute rien sur le chemin des requêtes — donc rien à redonder, rien à surveiller en plus. Grossier, mais gratuit en surface de panne.
Sommaire
1. Le montage : des priorités croisées
Deux ou trois nœuds, autant d'adresses flottantes, et un seul enregistrement DNS qui les publie toutes. Chaque nœud est maître de sa propre adresse et secours de celle des autres : c'est le croisement des priorités qui fait tout le travail.
| VIP A | VIP B | |
|---|---|---|
| Nœud 1 | priorité 150 — maître | priorité 100 — secours |
| Nœud 2 | priorité 100 — secours | priorité 150 — maître |
En fonctionnement nominal, chaque nœud porte une adresse et le trafic se partage. Si le nœud 1 tombe, le nœud 2 récupère la VIP A en plus de la sienne : le service reste entièrement joignable, sur les deux adresses, avec un déséquilibre de charge mais aucun trou.
2. La configuration, en pratique
C'est le même keepalived que pour une VIP unique, avec deux blocs au lieu d'un. Extrait du nœud 1 :
vrrp_instance VIP_A {
state MASTER
interface eth0
virtual_router_id 51
priority 150 # 100 sur le nœud 2
advert_int 1
virtual_ipaddress { 192.0.2.10/24 dev eth0 }
track_script { chk_service }
}
vrrp_instance VIP_B {
state BACKUP
interface eth0
virtual_router_id 52 # identifiant DIFFÉRENT du premier
priority 100 # 150 sur le nœud 2
advert_int 1
virtual_ipaddress { 192.0.2.11/24 dev eth0 }
track_script { chk_service }
}
Le piège du virtual_router_id
Chaque groupe VRRP doit avoir un identifiant différent, et cet identifiant doit être unique sur le domaine de diffusion — pas seulement dans votre configuration. Deux clusters distincts qui réutilisent le même numéro sur le même VLAN s'élisent mutuellement et se disputent des adresses qui ne les concernent pas. C'est une panne difficile à diagnostiquer parce qu'elle vient d'un voisin, pas de chez vous.
Côté DNS, on publie ensuite un seul enregistrement portant les deux adresses. Le
track_script reste indispensable : sans lui,
keepalived ne surveille que lui-même — c'est
détaillé au niveau 2 de la haute disponibilité.
3. Ce que le DNS ne fait pas
Il faut être clair sur ce qu'on achète, parce que ces quatre limites sont structurelles et qu'aucune configuration ne les contourne.
- • Aucun test de santé. Le DNS publie des adresses, il ne vérifie jamais qu'elles
répondent. C'est le
track_scriptde keepalived qui assure ce rôle, en retirant l'adresse du nœud défaillant — pas le DNS. - • Le cache et la durée de vie. Un résolveur qui a mis un enregistrement en cache le conserve jusqu'à expiration. Toute correction met donc au minimum un TTL à se propager, et certains clients ignorent cette durée.
- • Aucune pondération. Une grosse machine reçoit autant qu'une petite. Si vos nœuds sont hétérogènes, la répartition sera injuste et rien ne le corrigera.
- • Le DNS ne décide pas de la répartition. Il propose un ordre ; ce sont le cache du résolveur et le comportement du client qui décident du résultat, et l'écart entre deux clients est considérable — c'est l'objet de la section suivante.
4. Qui choisit réellement l'adresse
On lit souvent que « le client en prend une au hasard ». C'est faux aux trois étages — le serveur autoritatif, le résolveur, le client — et c'est le troisième qui décide si le montage vous apporte une redondance réelle ou rien du tout.
a. Le serveur autoritatif fait tourner l'ordre
BIND ne tire pas au sort : il fait tourner l'ordre du jeu d'enregistrements à chaque réponse. Avec trois adresses A, B et C :
| Requête | Ordre servi | Première adresse |
|---|---|---|
| 1re | A → B → C | A |
| 2e | B → C → A | B |
| 3e | C → A → B | C |
C'est une permutation circulaire, déterministe. Le point est tranché à la source : BIND 9.21.14
a supprimé l'ordre aléatoire, l'ISC notant qu'il « n'offrait pas une distribution uniforme
de toutes les permutations et n'était supérieur à l'ordre cyclique en aucune manière » — et que
désormais « random
ordering is now an alias for cyclic ordering[1] ».
b. Le résolveur récursif s'interpose
C'est l'étage qu'on oublie. La rotation a lieu chez l'autoritatif, mais vos clients ne lui parlent jamais : ils interrogent un résolveur récursif, qui garde le jeu d'adresses en cache pendant toute la durée de vie. La granularité réelle n'est donc pas « par client » mais « par résolveur ». Un site entier derrière un seul résolveur d'entreprise peut recevoir le même ordre pendant tout le TTL. C'est la vraie raison pour laquelle le round-robin DNS répartit mal sur de petits effectifs : ce n'est pas un défaut de hasard, c'est le cache.
c. Le client fait ce qu'il veut — et l'écart est énorme
Le DNS retourne plusieurs adresses, mais il ne définit pas comment elles seront utilisées. Certains clients essaient la première jusqu'au succès, d'autres les mettent en concurrence avec un délai, et quelques-uns les transforment réellement en groupe de cibles.
| Client | Ce qu'il fait des adresses reçues | Répartition |
|---|---|---|
| chrony directive pool |
Instancie plusieurs sources indépendantes. « La valeur par défaut est 4 et la valeur maximale est 16 » (chrony.conf[2]). | Réelle, et les sources votent |
| chrony directive server |
Une seule adresse active pour cette source, prise dans l'ordre du résolveur. | Aucune |
| Navigateur Happy Eyeballs, RFC 8305[3] |
Tentatives décalées, la première poignée de main gagne, les autres sont annulées — puis la connexion gagnante est réutilisée. | Des connexions, pas des requêtes |
| curl / libcurl | Tentatives échelonnées (200 ms par défaut[4]), première connexion réussie conservée. | Bascule correcte |
Gonet.Dialer |
Met IPv6 et IPv4 en concurrence après 300 ms[5], mais essaie séquentiellement les adresses d'une même famille. | Repli au délai d'attente |
| PostgreSQL libpq |
« Tous les hôtes et adresses seront essayés dans l'ordre, jusqu'à ce que l'un réussisse. » L'option load_balance_hosts[6] existe, mais sa valeur par défaut est disable. |
Aucune par défaut |
| nginx bloc upstream |
« Un nom de domaine qui se résout en plusieurs adresses IP définit plusieurs serveurs à la fois[7] », répartis en round-robin pondéré. | Réelle, faite par nginx |
Deux limites, sinon on vend du RR DNS pour de la haute disponibilité
1. Happy Eyeballs, ce sont les navigateurs.
Le décalage du RFC 8305 porte un nom, le Connection Attempt Delay : « une valeur recommandée par défaut est 250 millisecondes », le minimum recommandé est 100 ms, une tentative suivante « NE DOIT PAS démarrer dans les 10 millisecondes de la précédente », et le plafond conseillé est de 2 secondes. Concrètement : face à une adresse morte, un utilisateur paie 250 ms, pas un délai d'attente TCP. C'est ce qui donne l'impression d'une bascule instantanée dans un navigateur.
Mais les appels de machine à machine — supervision, API, intégration continue, sondes de santé — font pour la plupart un repli séquentiel, au délai d'attente de connexion, c'est-à-dire des dizaines de secondes… quand ils en font un. Le round-robin DNS donne donc une bonne bascule aux humains et une mauvaise aux machines. En infrastructure, c'est exactement la population qui compte.
2. La course s'arrête à la connexion.
Si le serveur termine la poignée de main puis renvoie des 500, ou reste pendu, plus personne ne court : le client a sa connexion et s'y tient. Le DNS n'a aucun contrôle de santé. C'est la frontière honnête entre répartition de charge et haute disponibilité — et c'est précisément ce qu'on va chercher un niveau plus haut, avec le test de santé que keepalived applique aux cibles IPVS, puis avec le test applicatif d'HAProxy.
Le contraste à retenir
En HTTP, le client court et n'en garde qu'une : la connexion gagnante est
ensuite réutilisée, et cent requêtes ne produisent pas cent choix d'adresse. En NTP avec
pool, le client en garde plusieurs et les
fait voter. Même enregistrement DNS, usages exactement inverses — c'est aussi
l'argument qui décide du mode
pool pour le NTP plutôt qu'une adresse unique.
Et un mot-clé suffit à tout annuler : server au
lieu de pool, ou un
load_balance_hosts laissé à sa valeur par défaut.
C'est pour cette raison que nous vérifions la configuration des clients, pas seulement
celle des serveurs.
5. Le comportement réel en panne
C'est là que le montage se distingue d'un simple round-robin DNS sans VIP, et c'est ce qui le rend défendable. Avec du round-robin nu sur des adresses fixes, la panne d'un nœud laisse son adresse publiée et morte : une requête sur deux échoue jusqu'à ce qu'un humain modifie la zone.
Ici, l'adresse survit à la machine
Parce que chaque adresse est flottante, elle migre chez un survivant en une à trois secondes. Les deux adresses publiées restent donc joignables, portées par une seule machine. Le DNS n'a rien à corriger, et il n'a d'ailleurs rien remarqué. Le déséquilibre de charge est le prix à payer, pas l'indisponibilité.
Corollaire à ne pas oublier au dimensionnement : chaque nœud doit pouvoir encaisser la charge de l'ensemble, sinon la bascule transforme une panne en saturation. C'est la même arithmétique que pour l'anycast, et elle se calcule avant, pas après.
6. Quand ça suffit, et quand ça ne suffit plus
C'est le bon choix si…
- • Deux ou trois nœuds, de capacité comparable
- • Un service sans état, ou dont l'état est partagé
- • Un trafic interne ou modéré
- • Vous ne voulez ajouter aucun composant au chemin
Il faut monter d'un cran si…
- • Les nœuds sont de tailles différentes (pondération)
- • Il faut retirer une cible en quelques secondes
- • L'application exige des sessions collantes
- • Le routage doit dépendre de l'URL
Le cran suivant est la couche 4 avec IPVS, qui apporte la pondération et un test de santé — au prix d'un composant à redonder.
Questions fréquentes
Combien de VIP faut-il déclarer ?
Autant que de nœuds, en général : chaque machine est maître d'une adresse et secours des autres. Au-delà de trois ou quatre, la configuration devient pénible à maintenir et le déséquilibre après panne devient difficile à raisonner — c'est le signe qu'il faut passer à un vrai répartiteur.
Que se passe-t-il si les deux nœuds tombent en même temps ?
Les deux adresses disparaissent du réseau et le service est indisponible : ce montage répartit la charge et survit à la perte d'un nœud, il ne fait pas de miracle au-delà. C'est aussi pour cela qu'on le combine avec de la haute disponibilité d'hyperviseur, qui relance les machines perdues et reconstruit la redondance.
Faut-il baisser la durée de vie DNS ?
Ce n'est pas nécessaire ici, et c'est même un contresens fréquent. Puisque les adresses sont flottantes et migrent d'elles-mêmes, le DNS n'a jamais besoin d'être corrigé en urgence : la durée de vie peut donc rester confortable. Baisser agressivement le TTL sert quand la bascule se fait par changement d'enregistrement, ce qui n'est pas le cas.
Ce montage fonctionne-t-il chez un hébergeur ?
Cela dépend entièrement de ce que le fournisseur permet en matière d'adresses déplaçables. Sur un segment de niveau 2 dont vous maîtrisez l'apprentissage des adresses MAC, oui. Sinon, il faut passer par le plan de contrôle du fournisseur, et la bascule se compte en dizaines de secondes plutôt qu'en secondes.
Sources
Les principales affirmations techniques de cette page sont étayées par les normes et documentations primaires suivantes. Liens consultés le 23 août 2026.
- [1] BIND 9.21.14 — suppression de l’ordre aléatoire : « random ordering is now an alias for cyclic ordering »
-
[2]
chrony.conf — directives
serveretpool,maxsources(défaut 4, maximum 16) - [3] RFC 8305 — Happy Eyeballs v2 : délai entre tentatives de connexion
- [4] libcurl — CURLOPT_HAPPY_EYEBALLS_TIMEOUT_MS, défaut 200 ms entre deux tentatives
-
[5]
Go —
net.Dialer.FallbackDelay: « If zero, a default delay of 300ms is used », entre familles d’adresses -
[6]
libpq —
load_balance_hosts, valeur par défautdisable - [7] ngx_http_upstream_module — un nom résolvant vers plusieurs adresses définit plusieurs serveurs
Votre répartition ajoute-t-elle un point de panne ?
Nous auditons l'existant et nous disons franchement si un répartiteur dédié se justifie, ou si un montage plus simple ferait le même travail.
Demander un devis