
Un retour aux premiers amours de ce blog, avec, pour changer, une suite de billets système et réseau.
Cette série est issue d’une petite discussion que j’ai eu avec mon ami Horacio, du blog LostinBrittany, durant un projet technique professionnel commun.
Plutôt que de garder pour moi mes réflexions, autant vous les faire partager
Cette discussion concerne surtout le prochain billet de ce blog, mais avant de l’aborder, il fallait poser les bases d’une certaine architecture et c’est ce que nous allons tout d’abord voir aujourd’hui.
Je vais vous parler d’une technique qui paraît bien triviale mais étonnamment efficace et largement employée dans les architectures disposant de 2 branches d’accès Internet.
Après tout, dans votre soucis constant de disposer d’une architecture hautement disponible et partant du sacro-saint adage “on ne met pas les oeufs dans le même panier”, vous avez décidé de confier l’accès internet de votre infrastructure à deux opérateurs différents (par exemple, si > 2, cela marche aussi…)
Bien évidemment, cela peut aussi être l’hébergement de vos serveurs dédiés chez deux entités différentes, ou encore, plus simplement, des serveurs dédiés dans 2 datacenters différents, ou tout bêtement, de 2 serveurs dédiés devant lesquelles vous n’avez pas de load-balancer…
Quoi qu’il en soit, la multiplication des points d’entrées “Internet” de votre service sur plusieurs chemins différents, vous donne, déjà, une meilleure sérénité de sa disponibilité envers le “monde”.
L’inconvénient de ce choix est qu’il est difficile de positionner un Load-Balancer devant vos serveurs pour répartir la charge ou tout simplement de renvoyer tout le trafic sur le serveur “vivant” quand l’autre est tombé.
On ramenant le concept à deux serveurs web (que je vais utiliser pour un exemple plus “accessible” ), nous allons voir comment utiliser le service DNS pour aller sur l’un ou l’autre des serveurs et pouvoir basculer le trafic sur l’un des deux en cas de panne d’un accès (ou du décès de l’un des serveurs Web).
Dans un vision très habituelle des choses, que l’on rencontre fréquemment sur les architectures exposées par les sysadmins, la technique souvent utilisée est le “Round Robin DNS“.
Je vous rassure tout de suite, rien à voir avec des problèmes d’obésité d’un quelconque défenseur de la fôret de Sherwood, mais d’une bidouille d’un enregistrement dns.
En effet, pour un enregistrement de type A (un enregistrement DNS spécifiant un nom = une adresse IP pour faire simple), on peut donner 2 entrées pour le même nom.
Exemple :
blog.guiguiabloc.fr IN A 10.10.10.10
blog.guiguiabloc.fr IN A 10.20.20.20
Les plus pointus allant même jusqu’à modifier l’entrée TTL pour peaufiner.
Résultat, alternativement, les requêtes sont envoyées sur 10.10.10.10 ou sur 10.20.20.20.
Le gros inconvénient de cette technique est que les requêtes iront toujours sur l’un ou l’autre, même si l’un des deux est mort… Un accès sur 2 n’aura donc pas de réponse… Gênant.
C’est donc une technique “a pas cher” de load-balancing, mais nullement une solution de haute-disponibilité (ou de Fail-Over).
Alors comment utiliser les DNS pour faire et du load-balancing et du fail-over ?
La réponse s’appelle du “Cascading NS” (ou cascade de serveurs NS).
Si une entrée DNS de type A fait la correspondance entre un nom d’hôte et une adresse IP, un enregistrement de type NS vous donne le serveur DNS ayant autorité sur le domaine (et qui donc sera à même de vous donner l’adresse IP (ou type A) du nom d’hôte que vous recherchez ou de vous indiquez à qui le demander).
Un dessin valant un long discours, regardons un peu le fonctionnement du cascading NS :

Que se passe t-il quand le client demande “blog.guiguiabloc.fr” ?
- Les autorités TLD répondent que le domaine “guiguiabloc.fr” est géré par les NS de tel registrar (OVH, GANDI, etc…) (je simplifie hein :p)
- Les serveurs DNS du Registrar répondent qu’il faut interroger deux autres NS, NS1.mondns.fr et NS2.mondns.fr qui sont autorité de zone pour le domaine “guiguiabloc.fr” (on arrive la sur VOS serveurs DNS) (1)
- Les serveurs DNS, ns1.mondns.fr et ns2.mondns.fr répondent qu’ils gèrent bien le domaine “guiguiabloc.fr” mais le sous-domaine “blog.guiguiabloc.fr” est géré par deux autres DNS, web-1.mondns.fr et web-2.mondns.fr (qui sont vos serveurs Web sur lesquelles tournent un serveur DNS ne s’occupant que de cette zone) (2)
- Le client interroge alors l’un des NS (web-1.mondns.fr ou web-2.mondns.fr) pour connaitre l’entrée A de blog.guiguiabloc.fr (3)
- Si c’est web-1.mondns.fr qui est interrogé, il répondra 10.10.10.10, si c’est web-2.mondns.fr, il répondra 10.20.20.20, avec une durée de vie d’1 minute de la correspondance (60 secondes plus tard, si le client doit demander de nouveau blog.guiguiabloc.fr, il devra demander de nouveau l’adresse IP (lors d’une nouvelle session par exemple).
Voila ce que donnera une demande de résolution :
guigui@Clara:~$ dig blog.guiguiabloc.fr
; <<>> DiG 9.7.3 <<>> blog.guiguiabloc.fr
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 41551
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 1, ADDITIONAL: 1
;; QUESTION SECTION:
;blog.guiguiabloc.fr. IN A
;; ANSWER SECTION:
blog.guiguiabloc.fr. 49 IN A 10.10.10.10
;; AUTHORITY SECTION:
blog.guiguiabloc.fr. 49 IN NS web-1.mondns.fr.
;; ADDITIONAL SECTION:
web-1.mondns.fr. 3922 IN A 10.10.10.10
Et 60 secondes plus tard :
...
;; ANSWER SECTION:
blog.guiguiabloc.fr. 60 IN A 10.20.20.20
;; AUTHORITY SECTION:
blog.guiguiabloc.fr. 60 IN NS web-2.mondns.fr.
;; ADDITIONAL SECTION:
web-2.mondns.fr. 5006 IN A 10.20.20.20
Vous avez compris que le site web blog.guiguiabloc.fr tourne sur les deux serveurs web avec chacun une IP différente.
A l’inverse du Round-Robin DNS, le client interroge les NS aléatoirement et prend la réponse du plus rapide (et donc également du plus proche géographiquement).
Rassurez vous, toute cette séquence ne prend que quelques millisecondes.
Mais que se passe-t-il quand web-1.mondns.fr tombe (et donc ne peut plus répondre).

Le début est identique mais quand le client demande “blog.guiguiabloc.fr” aux serveurs NS de la sous-zone, seul le “NS” 2 répondra.
Vous avez la un fail-over immédiat (tout au moins a 60 secondes après le crash) puisque NS1 ne répondra jamais.
La technique est aussi très efficace quand vous souhaitez retirer un des serveurs web de votre pool, il vous suffit d’arreter le serveur DNS dessus. Il ne répondra plus aux requètes NS et donc ne prendra pas de trafic
La configuration des DNS est des plus basiques pour cela, il faut bien évidemment que les serveurs DNS de web-1.mondns.fr et web-2.mondns.fr soit chacun master (maître) (puisqu’ils donnent une entrée de type A différente).
Pré-requis, vous avez bien entendu défini une entrée de type A pour web-1 et web-2 dans la zone “mondns.fr”.
Sur vos serveurs DNS principaux (ns1.mondns.fr et ns2.mondns.fr), pour la zone “guiguiabloc.fr” (bien sûr remplacez tout cela par vos domaines/IP
)
$TTL 600
@ IN SOA ns1.mondns.fr. noc.mondns.fr. (
2013020400 ; serial
3600 ; refresh
3600 ; retry
3600000 ; expire
3600 ; minimum
)
IN NS ns1.mondns.fr.
IN NS ns2.mondns.fr.
blog IN NS web-1.mondns.fr.
IN NS web-2.mondns.fr.
Sur web-1, pour la zone “blog.guiguiabloc.fr” :
$ORIGIN .
$TTL 60
blog.guiguiabloc.fr IN SOA ns1.mondns.fr. noc.mondns.fr. (
2013020400 ; serial
3600 ; refresh
3600 ; retry
3600000 ; expire
3600 ; minimum
)
IN NS web-1.mondns.fr.
IN A 10.10.10.10
Sur web-2, pour la zone “blog.guiguiabloc.fr”
$ORIGIN .
$TTL 60
blog.guiguiabloc.fr IN SOA ns1.mondns.fr. noc.mondns.fr. (
2013020400 ; serial
3600 ; refresh
3600 ; retry
3600000 ; expire
3600 ; minimum
)
IN NS web-2.mondns.fr.
IN A 10.20.20.20
Bien entendu, je vous laisse adapter à votre configuration, c’est juste un exemple
Alors, elle n’est pas sympa cette technique ?
“oui,oui. Très sympa oh Grand Guiguiabloc, mais y’a quand même un problème !”
“Ah ? Je t’écoute jeune Padawan”
“si le service web de web-1 plante par exemple, mais pas le serveur, mon DNS il répond toujours !!! et les visiteurs ils arrivent toujours sur mon serveur !! Ca craint !”
“Je m’attendais à cette remarque, jeune youglin, et comme je suis dans une année de grande bonté, je vais te donner une solution pour cela”
“oh merci Grand Guiguiabloc !!!” (flap-flap-flap)
La solution pour couper votre DNS local sur votre serveur web (ou votre reverse-proxy hein) en cas de crash du service http s’appelle :
MONIT.
MONIT est un utilitaire qui surveille vos process (mais également vos répertoires, fichiers, programmes etc..) et execute des actions en cas de soucis.
L’action la plus courante est d’avertir l’admin (forcément :p) mais également par exemple, de tenter de relancer le programme.
Exemple pour surveiller le process Nginx
check process nginx with pidfile /var/run/nginx.pid
start program = "/etc/init.d/nginx start"
stop program = "/etc/init.d/nginx stop"
group www-data
Vous trouverez des exemples sur la page wiki du projet :
http://mmonit.com/wiki/Monit/ConfigurationExamples
En cas de non réponse du process, vous pouvez appeler un script par “exec” ‘de type “/etc/init.d/bind9 stop”
Plus simple encore, un simple script bash appeler en crontab :
#!/bin/bash
#pre-requis blog.guiguiabloc.fr a une entrée dans
#le fichier /etc/hosts avec son ip locale
#pour éviter d'interroger les DNS
TESTING=`curl -sL -w "%{http_code} %{url_effective}\\n" "blog.guiguiabloc.fr" -o /dev/null`
if test "$TESTING" != "200 http://blog.guiguiabloc.fr"
then
echo "CA CHIE"
else
echo "ok"
fi
Et donc arreter le service DNS si “CA CA CHIE”
En espérant que cela vous donne des idées
Amusez-vous bien