[Projet] NFS hautement disponible avec DRBD et Heartbeat

Un cluster infiniment disponible !

Un cluster infiniment disponible !

Si vous me suivez vous n’êtes pas sans savoir que je cherche à résoudre la problématique suivante pour mon projet de fin d’année : mettre en place un SAN hautement disponible afin d’y stocker les machines virtuelles gérées par un cluster de virtualisation.

Après avoir mise en place un premier SAN grâce à DRBD, iSCSI et Keepalived, j’ai moins fait le malin lorsqu’il a fallu l’ajouter dans Proxmox. Les jours passent et je n’ai pas su trouver pourquoi Proxmox ne voulait pas de mon SAN iSCSI… De plus, ayant récemment appris que NFS permettait la migration de machines virtuelles à chaud et que j’en aurai besoin, j’ai vite changé d’avis pour me tourner vers NFS.

Pour les noob, NFS (Network File System) est, comme son nom l’indique, un système de fichier réseau qui permet de partager des données principalement entre machines UNIX. L’intérêt étant, comme iSCSI, de pouvoir partager des données de manière totalement transparente, simple, efficace et fiable.

Je ne vous refais pas les jolis schémas de l’article précédent hormis le global, car j’ai ajouté quelques petites choses sympathiques essentiellement pour obtenir une configuration digne de porter le qualificatif de hautement-disponible.

J’ai donc doublé la première carte réseau (eth0 et eth1) afin de découvrir les joies du bonding et du load-balancing. J’ai aussi décidé de dédier un réseau à DRBD (10.10.1.0) auquel les serveurs accéderont via leur troisième interface (eth2). Enfin, j’ai séparé les métadonnées DRBD des données répliquées (allez faire un tour sur la documentation pour en savoir plus).

Voici les caractéristiques des machines :

Fonction Nom de machine Address IP IP DRBD
Nœud Primaire mnemosyne 192.168.100.10 10.10.1.10
Nœud Secondaire clio 192.168.100.11 10.10.1.11

L’addresse IP flottante (gérée par Heartbeat) sera 192.168.100.100 et le dossier partagé par NFS sera /srv/nfs.

Allons faire chauffer nos proc’ !

Création des interfaces réseau « liées »

Je pars d’une Debian 7 fraîchement installée et à jour. Je démarre avec un disque (/dev/sda1 sur lequel est installé le système) et deux cartes réseau (eth0 et eth1).

Nous allons commencer par mettre en place les interfaces réseau liées. A quoi ça sert ? A supprimer un point possible de panne. Notre SAN doit être accessible 99,9% du temps. Si une carte réseau grille, la seconde prend le relais et on n’a pas d’interruption de service. Petit bonus, utiliser deux cartes réseau permet aussi de faire de la répartition de charge (Round-robin).

Pour mettre en place cela, nous avons besoin du paquet ifenslave, que nous pouvons installer.

sudo apt-get install ifenslave

La configuration se fait ensuite via /etc/modprobe.d/aliases.conf :

alias bond0 bonding
options bonding mode=0 arp_interval=2000 arp_ip_target=192.168.100.10

Coupez le réseau :

# ifdown eth0 (à répéter sur toutes les interfaces liées)
# /etc/init.d/networking stop

Et reconfigurez-le via le fichier /etc/network/interfaces :

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).
 
# The loopback network interface
auto lo
iface lo inet loopback
 
# The primary network interface
auto bond0
iface bond0 inet static
        address 192.168.100.10
        netmask 255.255.255.0
        broadcast 192.168.100.255
        network 192.168.100.0
        gateway 192.168.100.2
        dns-nameservers 8.8.8.8
        slaves eth0 eth1
        bond_mode balance-rr
        bond_miimon 100
        bond_downdelay 200
        bond_updelay 200

Normalement, pas besoin d’ajouter eth0 et eth1 dans ce fichier. Elles sont prises en charge par le bonding.

Redémarrez le réseau :

sudo service networking start

Qu’est ce que c’est que ce charabia ?

  • bond_mode balance-rr place l’interface en mode « Round robin »
  • miimon=100 défini la fréquence (en ms) d’inspection des liens esclaves afin d’y détecter une panne. 100ms est la valeur recommandée.
  • downdelay=200 défini le temps minimum avant qu’une interface soir déclarée en panne
  • updelay=200 défini le temps minimum avant qu’une interface soir déclarée opérationnelle

Toutes ces opérations sont à réitérer (en les adaptant évidemment…) sur le deuxième nœud.

Si vous cherchez plus d’informations sur ifenslave ou si vous êtes curieux, vous pouvez trouver quelques informations intéressantes sur le wiki Debian.

Mise en place de DRBD

On peut passer à DRBD. J’éteins mes machines afin d’y ajouter deux disques (un pour les métadonnées DRBD et un pour les données répliquées) et la carte réseau dédié à DRBD.

Comment tu calcules la quantité d’espace nécessaire aux métadonnées ?

C’est simple, il y a une formule pour ça

formule approximative metadonnées drbd

Où MMo est la taille des métadonnées (en Mo) et CMo la taille de la partition DRBD répliquée (en Mo). Dans mon cas (400Go répliqués) :

formule approximative metadonnées drbd cas

Un disque de 1Go devrait largement faire l’affaire. Donc pour résumer on aura :

  • /dev/sdb1 qui contiendra les métadonnées DRBD, d’une taille de 1Go
  • /dev/sdc1 qui contiendra les données DRBD répliquées, soit 400 Go
  • L’interface eth2 en ip fixe avec, respectivement sur le nœud primaire puis le secondaire, les adresses 10.10.1.10 et 10.10.1.11 accessibles aux noms d’hôte san0 et san1

Je vous laisse le soin de créer la partition sur vos disques. Le fichier /etc/network/interfaces devrait quant à lui ressembler à ceci (sur le primaire) :

# The loopback network interface
auto lo
iface lo inet loopback
 
# The user-accessible network interface
auto bond0
iface bond0 inet static
        address 192.168.100.10
        netmask 255.255.255.0
        broadcast 192.168.100.255
        network 192.168.100.0
        gateway 192.168.100.2
        up /sbin/ifenslave bond0 eth0
        up /sbin/ifenslave bond0 eth1
 
# Members of the bonded network interface
auto eth0
iface eth0 inet manual
auto eth1
iface eth1 inet manual
 
# The isolated network interface
auto eth2
iface eth2 inet static
    address 10.10.1.10
    netmask 255.255.255.0
    broadcast 10.10.1.255
    network 10.10.1.0

Assurez-vous aussi que votre fichier host soit correctement complété :

127.0.0.1         localhost
192.168.100.10 mnemosyne.exmaple.net mnemosyne
192.168.100.11 clio.example.net clio
10.10.1.10 mnemosyne
10.10.1.11 clio

Vos deux machines doivent aussi être à l’heure sinon DRBD aura quelques soucis. Installez NTP si besoin ou utilisez les VMware Tools si vous travaillez avec VMware. Si tout est prêt, passons à l’installation de DRBD et de Heartbeat :

sudo apt-get install drbd8-utils heartbeat

On commence par la création de la ressource drbd. Je propose de la placer dans /etc/drbd.d/nfs.res, avec le contenu suivant :

resource nfs {
        protocol C;
 
        handlers {
                pri-on-incon-degr "echo o > /proc/sysrq-trigger ; halt -f";
                pri-lost-after-sb "echo o > /proc/sysrq-trigger ; halt -f";
                local-io-error "echo o > /proc/sysrq-trigger ; halt -f";
                outdate-peer "/usr/lib/heartbeat/drbd-peer-outdater -t 5";
        }
 
        startup {
                degr-wfc-timeout 120;
                become-primary-on mnemosyne;
        }
 
        disk {
                on-io-error detach;
        }
 
        net {
                cram-hmac-alg sha1;
                shared-secret "password";
                after-sb-0pri disconnect;
                after-sb-1pri disconnect;
                after-sb-2pri disconnect;
                rr-conflict disconnect;
        }
 
        syncer {
                rate 100M;
                verify-alg sha1;
                al-extents 257;
        }
 
        on mnemosyne {
                device /dev/drbd0;
                disk /dev/sdc1;
                address 10.10.1.10:7788;
                meta-disk /dev/sdb1[0];
        }
 
        on clio {
                device /dev/drbd0;
                disk /dev/sdc1;
                address 10.10.1.11:7788;
                meta-disk /dev/sdb1[0];
        }
}

Vous trouverez plein d’informations intéressantes sur ce fichier dans la documentation officielle DRBD qui est très claire.

Les étapes suivantes sont les mêmes que pour l’article précédentes : chaque commande A doit impérativement être exécutée sur les deux nœuds avant de passer à la commande B.

sudo drbdmdadm create-md nfs
 
  --==  Thank you for participating in the global usage survey  ==--
The server s response is:
 
you are the 438th user to install this version
Writing meta data...
initializing activity log
NOT initialized bitmap
New drbd meta data block successfully created.
success
 
sudo modprobe drbd
sudo drbdadm attach nfs
sudo drbdadm connect nfs

Après cela, nos deux serveurs DRBD doivent avoir conscience de l’un et l’autre, vous pouvez le vérifier avec la commande :

cat /proc/drbd
version: 8.3.11 (api:88/proto:86-96)
srcversion: 41C52C8CD882E47FB5AF767
 0: cs:Connected ro:Secondary/Secondary ds:Inconsistent/Inconsistent C r-----

On peut d’ailleurs voir que les deux parties sont définie en « Secondary ». Toutes les commandes qui suivent et qui concernent DRBD doivent être exécutée uniquement sur le Primary, que nous allons définir tout de suite :

sudo drbdadm -- --overwrite-data-of-peer primary nfs

La synchronisation démarre et vous pouvez en consulter l’avancement avec :

watch -n 1 cat /proc/drbd

Synchronisation DRBD

Vous remarquerez que c’est pas rapide rapide. Donnez un coup de boost avec la commande :

sudo drbdsetup /dev/drbd0 syncer -r 100M

Après deux heures (dans mon cas), j’obtiens :

cat /proc/drbd
version: 8.3.11 (api:88/proto:86-96)
srcversion: 41C52C8CD882E47FB5AF767
 0: cs:Connected ro:Primary/Secondary ds:UpToDate/UpToDate C r-----
    ns:419416540 nr:0 dw:0 dr:419417536 al:0 bm:25600 lo:0 pe:0 ua:0 ap:0 ep:1 wo:f oos:0

On peut donc revenir à un débit de synchronisation normal :

sudo drbdadm adjust nfs

Nous voilà maintenant avec un nouveau lecteur (/dev/drbd0) que nous pouvons utiliser comme bon nous semble. Pour nous il contiendra un dossier export/ partagé sur le réseau via NFS afin que le cluster de virtualisation puisse y stocker ses machines virtuelles. On termine donc par formater ce lecteur, j’ai choisi ext4 :

sudo mkfs.ext4 /dev/drbd0
sudo mkdir -p /srv/nfs
sudo mount /dev/drbd0 /srv/nfs

Le lecteur est monté sur /srv/nfs. Il nous reste donc NFS et Heartbeat.

Installation et configuration de NFS

On commence par installer NFS sur les deux machines :

sudo apt-get install nfs-kernel-server

La première étape consiste à supprimer le script de démarrage automatique de NFS. En effet, le lancement du service sera automatiquement géré par Heartbeat. Supprimez le liens dans /etc/rc02.D/ :

sudo rm /etc/rc02.d/SXXnfs-common
sudo rm /etc/rc02.d/SXXnfs-kernel-server

Maintenant, passons à la configuration, dans le fichier /etc/exports :

/srv/nfs/export 192.168.100.0/24(rw,no_subtree_check)

Cette ligne permet de partager /srv/nfs/export sur le réseau 192.168.100.0/24 avec les options rw (permet la lecture et l’écriture sur un partage pour l’hôte défini) et no_subtree_check (pour être plus souple sur ce qui va être copié sur le partage).

Attention cette configuration n’est pas du tout faite pour de la production car je ne mets aucune sécurité en place. N’importe quel hôte du réseau 192.168.100.0 aura en effet accès au partage. Je n’ai pas envie de perdre du temps avec ça en fait…

Copiez ce fichier de configuration sur le deuxième noeud :

sudo scp /etc/exports root@clio:/etc/

et passons à Heartbeat.

Configuration de Heartbeat

Normalement vous l’avez installé avec drbd. Il ne reste plus qu’à le configurer.

  • /etc/heartbeat/ha.cf
keepalive       2
deadtime        10
warntime        5
initdead        120
bcast           bond0 eth2
node            mnemosyne clio
  • /etc/heartbeat/authkeys
auth 3
3 md5 password

Protégez ce fichier avec un chmod 600.

  • /etc/heartbeat/haresources
mnemosyne IPaddr::192.168.100.100/24/bond0 drbddisk::nfs Filesystem::/dev/drbd0::/srv/nfs::ext4 nfs-kernel-server

Encore une fois c’est vraiment une configuration de base, la documentation de heartbeat saura mieux vous éclairer.

Copiez tout ça sur le deuxième noeud (sur lequel vous avez évidemment installé heartbeat) et redémarrez.

Normaement après le redémarrage :

  • Le cluster est accessible à l’adresse 192.168.100.100, que Heartbeat a créé sur l’interface virtuelle bond0:0
  • /dev/drbd0 a été monté sur /srv/nfs
  • Le service nfs-kernel-server a été correctement lancé et partage le dossier /srv/nfs/export

Si vous vous amusez à couper violemment le noeud primaire, le secondaire devrait prendre le rôle rapidement. Après avoir monté /dev/drbd0 sur /srv/nfs et relancé le service NFS. Pas mal non ? Le SAN est maintenant prêt à accueillir nos machines virtuelles. Mais avant, il va falloir créer notre cluster Proxmox.

ps : si jamais vous constatez des erreurs malgré mes relectures, dites-le moi 😉

Cet article vous a plu ? Partagez-le sur les réseaux sociaux !

Twitter Facebook Google Plus email