Mirroring du disque système avec mdadm et grub
Posted by Daniel on 06 Mar 2008 at 05:35 | Tagged as: linux
Cette procédure décrit le passage d'une Ubuntu Breezy (5.10) avec un seul disque système à une plate-forme avec deux disques systèmes en miroir (raid1), en utilisant mdadm pour la gestion des metadevices et grub comme bootloader.
La procédure est décrite pour un environnement de type Debian/Ubuntu, mais devrait s'appliquer sans soucis sur une autre distribution.
Attention : ce document n'est qu'une synthèse de mon expérience personnelle sur le sujet. Je ne peux aucunement être tenu responsable des conséquences de l'utilisation, correcte ou non, des informations exposées ici. Je ne répondrai pas non plus aux demandes directes d'assistance!
Aperçu des opérations
- Vérification de la présence des modules nécessaires
- Ajout physique du nouveau (second) disque
- Copie de la table des partitions de l'ancien vers le nouveau disque
- Changement des flags partitions sur le nouveau disque
- Création des métadevices sur le nouveau disque
- Création des filesystems sur les métadevices
- Copie des données de l'ancien disque sur les nouveaux filesystems
- Modification de la fstab sur le nouveau filesystem root
- Création de l'initrd
- Modification du menu.lst de grub et installation sur les deux disques
- Rebooter sur le nouveau disque seul pour valider
- Attacher l'ancien disque au miroir
- Mieux dormir la nuit en sachant que son serveur préféré ne mourra pas au premier crash disque!
Vérification de la présence des modules nécessaires
Vérifier la présence des modules md et raid1 :
# lsmod | egrep "md|raid1"
S'ils manquent, vérifier leur présence en les chargeant :
# modprobe md # modprobe raid1
Vérifier que les modules sont bien reconnus :
# cat /proc/mdstat Personalities : [raid1] read_ahead not set unused devices:
Vérifier également la présence du binaire mdadm. S'il manque, l'installer avec synaptic ou apt-get :
# apt-get install mdadm
Ajout du nouveau disque
L'idéal est d'ajouter un disque de même modèle que le disque existant, mais ce n'est pas strictement nécessaire. L'essentiel est d'avoir la place de reproduire les partitions existantes sur le nouveau disque!
Chez moi, le disque d'origine était /dev/hda, et le nouveau est /dev/hdd, ce sont donc les devices que j'utiliserai dans les exemples de ce mini-guide.
Copie de la table des partitions
Puisqu'on souhaite garder la configuration existante de la machine, on va conserver le partitionnement existant pour servir de base aux métadevices. On va donc copier la table des partitions de l'ancien disque sur le nouveau, par exemple avec sfdisk :
# sfdisk -d /dev/hda | sfdisk /dev/hdd
Chez moi, les partitions d'origines sont les suivantes, encore une fois, je les utiliserai comme exemples :
- /dev/hda1 = /
- /dev/hda2 = swap
- /dev/hda3 = /home
Modification des flags des partitions
Pour que l'ensemble fonctionne correctement, il faut annoncer au système que les types de partitions ont changé. On va donc éditer la table des partitions du nouveau disque et déclarer chaque partition comme étant de type raid autodetect. Le code hexadécimal correspondant est fd.
# sfdisk -c /dev/hdd 1 fd # sfdisk -c /dev/hdd 2 fd # sfdisk -c /dev/hdd 3 fd
Cela peut bien entendu aussi se faire avec fdisk (option t pour changer les flags des partitions).
Création des métadevices
Il est maintenant temps de créer les métadevices, c'est-à-dire les devices raid qui s'appuient sur des devices physiques. Pour cette création, on va s'appuyer sur le second disque, /dev/hdd, et annoncer à mdadm que l'autre pan du miroir est manquant, ce qui nous permet de conserver les données du premier disque /dev/hda.
# mdadm -C /dev/md0 --level=1 --raid-devices=2 /dev/hdd1 missing # mdadm -C /dev/md1 --level=1 --raid-devices=2 /dev/hdd2 missing # mdadm -C /dev/md2 --level=1 --raid-devices=2 /dev/hdd3 missing
Création des filesystems
On peut maintenant recréer les filesystems sur les nouveaux volumes.
# mkfs -t ext3 /dev/md0 # mkfs -t ext3 /dev/md2 # mkswap /dev/md1
Recopie du système existant
A ce stade-là, nous sommes toujours sur le système d'origine, avec en particulier un root filesystem sur /dev/hda1. Nous allons donc monter les nouveaux filesystems et y recopier les données actuelles.
# mkdir /newroot # mount /dev/md0 /newroot # cd / ; find . -xdev | cpio -pmd /newroot/ # mount /dev/md2 /newroot/home # cd /home ; find . -xdev | cpio -pmd /newroot/home/
Vous pouvez bien sûr utiliser un autre moyen de copie, cp et tar fonctionnent parfaitement aussi.
Note : si vous vous demandez pourquoi il faut créer un nouveau filesystem et y recopier les données existantes au lieu de simplement créer un métadevice "autour" de la partition existante, c'est parce que mdadm utilise le début de la partition physique pour stocker ses propres métadonnées, et il a donc besoin de se réserver cet espace, ce qu'il fait à la création. Sur la partition existante, cet espace était déjà occupé par des données.
Modification de la nouvelle fstab
Sur notre tout nouveau (futur) filesystem root, on va modifier la fstab pour utiliser les métadevices.
# vi /newroot/etc/fstab
-
- /dev/hda1 devient /dev/md0
- /dev/hda2 devient /dev/md1
- /dev/hda3 devient /dev/md2
Création d'un initrd
Attention : cette section ne décrit pas le téléchargement et la recompilation d'un noyau. Il vous faudra donc un noyau raisonnablement récent. J'ai fait l'opération avec un 2.6.12, mais tant que vous avez le support du module md et du module raid1, ça devrait pouvoir fonctionner.
L'initrd (INIT RamDisk) est lu et chargé en mémoire par le noyau au début du processus de boot, avant que le filesystem root définitif ne soit accessible. Il permet de fournir un certain nombre de fonctionnalités supplémentaires non présentes dans le noyau, typiquement sous forme de modules. Puisqu'il est spécifique à un noyau donné, il est généralement recréé à chaque upgrade de vos paquets kernel, attention donc à regénérer un initrd lorsque vous mettez à jour le noyau!
Nous allons donc recréer un initrd en forçant le chargement du module raid1, et surtout en lui spécifiant explicitement le root filesystem à utiliser. En effet, le mkinitrd Debian va par défaut utiliser le root filesystem déclaré dans la fstab courante, soit /dev/hda1, ce qui nous provoquerait un beau panic lors du reboot si le filesystem en question n'existait plus!
# vi /etc/mkinitrd/modules
- ajouter une ligne raid1
# vi /etc/mkinitrd/mkinitrd.conf
- remplacer ROOT=probe par ROOT=/dev/md0
# mkinitrd -o /boot/initrd.img-.raid
La version du noyau est tout simplement celle du package kernel utilisé. Donc chez moi, avec un noyau 2.6.12-10 pour i386 :
# mkinitrd -o /boot/initrd.img-2.6.12-10-i386.raid
Notons que ces manipulations viennent d'être effectuées sur /dev/hda1, il faut donc les copier sur notre nouveau filesystem.
# cp -r /etc/mkinitrd /newroot/etc # cp /boot/initrd.img-.raid /newroot/boot
Mise à jour de grub
Il est temps de déclarer notre nouveau filesystem dans le bootloader.
# vi /boot/grub/menu.lst
Ajoutons une entrée :
title Ubuntu, kernel 2.6.12 sur /dev/md0 root (hd0,0) kernel /boot/vmlinuz-2.6.12-10-386 root=/dev/md0 md=0,/dev/hda1,/dev/hdd1 ro quiet initrd /boot/initrd.img-2.6.12-10-386.raid boot
Encore une fois, la modification étant faite sur l'ancien filesystem, on la recopie sur le nouveau (on aurait aussi pu se contenter de la faire sur le nouveau et passer le /newroot/boot/grub/menu.lst en paramètre à grub-install, mais je préfère avoir la même version du fichier des deux côtés de toute façon)
# cp /boot/grub/menu.lst /newroot/boot/grub/menu.lst
Notre configuration étant maintenant au point, il est temps de l'installer.
# grub-install /dev/hda1
Pour ce qui est du second disque, on va utiliser une petite astuce : nous voulons être capables de booter dessus si par hasard le premier est mort. Or, le premier disque détecté par le BIOS se voit affecter par grub l'identifiant hd0, le suivant hd1, etc. Il faut donc que le second disque (/dev/hdd) croie être hd0, pour pouvoir booter en l'absence du vrai hd0 (/dev/hda). Grub permet de faire ça très simplement :
# grub grub> device (hd0) /dev/hdd grub> root (hd0,0) grub> setup (hd0) grub> quit
Test de la configuration
Voilà, nous avons maintenant en plus de notre disque /dev/hda un disque /dev/hdd sur lequel nous avons construit des métadevices, recopié notre système, et que grub sait maintenant booter. Avant d'intégrer notre ancien disque au miroir (et donc d'écraser ses données), validons quand même la configuration.
Pour ce faire, rien de plus simple : on arrête le PC, et on débranche l'ancien disque. Le nouveau disque se retrouve donc seul, s'il boote correctement c'est que tout va bien.
S'il ne boote pas, remettre l'ancien pour rebooter sur la conf existante, et vérifier qu'on n'a pas oublié d'étape.
Incorporation de l'ancien disque
Puisque tout va bien, il est temps d'intégrer l'ancien disque, pour avoir réellement un miroir capable de supporter la perte d'un disque!
Rien de plus simple :
# mdadm -a /dev/md0 /dev/hda1 # mdadm -a /dev/md1 /dev/hda2 # mdadm -a /dev/md2 /dev/hda3
Le système va maintenant resynchroniser les données sur /dev/hda (comprendre, écraser tout ce qui s'y trouve à partir des données des métadevices).
Pour suivre l'avancement de la resynchronisation :
# cat /proc/mdstat
Une fois la resynchronisation terminée, ca y est, votre système est prêt!
Note : certaines personnes recommandent de refaire l'initrd à ce stade, mais je ne suis pas certain de l'utilité de cette démarche, et je n'ai pas fait de tests poussés sur le sujet. Mais étant donné que ça ne prend que quelques secondes, il n'y pas vraiment de raisons de s'en priver!