Conception et mise en oeuvre d'un Service d'Archivage
Mise en place d'une solution RAID logiciel (RAID de type 1)
Ce document se présente comme un petit guide (ou
mode d'emploi) montrant comment mettre en place une solution RAID-1 logiciel
sous Linux (Fedora Core 2) dans le cadre de la mise oeuvre du Service d'Archivage.
Le RAID va être mis en oeuvre directement à l'installation du système
(Linux FC2) grâce à DiskDruid puis administré
par la suite avec les outils raidtools et mdadm.
- Qu'est-ce que le RAID-1?
- Ressources matérielles et logicielles
- Gestion des périphériques RAID-1 :
- avec raidtools
- avec mdadm
- Conclusion - Bilan
1- Qu'est-ce que le RAID-1?
La technologie RAID (Redundant Array of Inexpensive
Disks ou Redundant Array of Independent Disks) permet de constituer
une unité de stockage à partir de plusieurs disques durs. L'objectif
est principalement d'assurer la redondance des informations en fournissant des
fonctionnalités de sécurité permettant d'assurer l'intégrité
et la disponibilité des données.
Le RAID-1 a pour but de dupliquer l'information à
stocker sur plusieurs disques, on parle de mirroring, ou shadowing.
Le RAID-1 s'emploie à partir de deux disques auxquels viennent
éventuellement se greffer des disques de secours. Ce mode duplique les
informations d'un disque (ou plusieurs) sur l(es) autre(s). En utilisant
ce procd, seulement la moiti de l'espace est disponible pour les donnes.
Avantages du RAID-1 :
- disponibilité des données,
- gain de performance en lecture (plusieurs disques et donc plusieurs contrôleurs
de disques).
Inconvnients du RAID-1 :
- perte d'espace disque,
- perte de temps CPU ,
- perte de vitesse en écriture (dû aux redondances).
Dans le cadre du Serveur d'Archivage, il est indispensable
de recourir à ce type de solution afin d'assurer la disponibilité
des données. Le RAID-1 peut être réalisé matériellement
(grâce à des cartes intégrant cette technologie) ou logiciellement.
C'est cette dernière solution que nous allons étudier.
2- Ressources matérielles et logicielles
a) Ressources matérielles
Voici la configuration matérielle utilisée
:
- PC DELL OptiPlex GX110 PIII 667 MHz,
- 512Mo de mémoire vive,
- 2 disques dur IDE de 40Go chacuns.
Cette configuration correspond au futur serveur d'archivage.
Il est tès important de n'utiliser qu'un disque IDE par nappe. Outre
la question des performances, la défaillance d'un disque provoque
généralement le blocage de l'interface. Un bus, un disque,
c'est la règle. Surtout que les contrôleurs PCI IDE ne manquent
pas (ou on peut s'en procurer à des prix abordables).
b) Ressources logicielles
Le système d'exploitation est Linux Fedora Core
2 (noyau 2.6.5-1.358). L'idée est de faire du RAID-1 logiciel sur les
données (/home) mais également sur le système
(c'est à dire /boot, /var, /...). Le but est
de simplifier la tâche de l'administrateur : si un disque venait à
"griller", son changement et sa synchronisation doivent se faire le
plus simplement possible.
A l'installation de Linux FC2, il est possible, avec l'outil
DiskDruid, de créer directement les périphériques
RAID. Nous allons donc mettre en oeuvre notre raid logiciel de cette façon.
DiskDruid est un logiciel de partitionnement, il prépare
le (ou les) disque(s) pour y installer le système Linux (ici Fedora Core
2). Cet outil détecte les deux disques IDE : hda et hdc
( s'ils avaient été sur la même nappe on aurait eu hdb
à la place de hdc). Initialement, ces 2 disques sont vierges.
On va donc réaliser le partitionnement.
Il n'y a aucune raison d'employer le RAID au dessus
du swap pour en améliorer les performances. Le noyau se charge lui-même
d'équilibrer le swap sur plusieurs périphériques
si toutes les partitions ont la même priorité dans la fstab.
Un fichier /etc/fstab correctement écrit ressemble à
ce qui suit :
/dev/hda2 swap swap defaults,pri=1 0 0
/dev/hdc2 swap swap defaults,pri=1 0 0
Les partitions de type swap seront donc les seules
partitions à ne pas être en RAID.
Nous allons créer les partitions les unes à
la suite des autres. En double-cliquant sur la partie <espace libre> de
chaque disque. On va créer de nouvelles partitions en indiquant le cylindre
de début, de fin et le type de partition. Nous allons commencer par créer
toutes les partitions de type "RAID logiciel" sur le premier disque.
En procédant ainsi, on va pouvoir utiliser une fonctionnalité
intéressante de DiskDruid qui permet de pouvoir cloner
toutes les partitions de type "RAID logiciel" sur le deuxième
disque (ce qui évite de refaire les même manipulations sur le deuxième
disque). Ensuite, on va créer une partition swap sur chaque
disque (que l'on place en début de chaque disque). Pour des raisons de
performances en terme de temps d'accès, les partitions sont disposées
dans l'ordre croissant en fonction de leur taille.
Procédure :
- Création de 4 partitions de type "RAID logiciel" sur hda,
- cylindre : début=2082, fin=2285 ( pour /boot soit environ
100Mo),
- cylindre : début=2286, fin=3301 (pour /varsoit environ
500Mo),
- cylindre : début =3302, fin=10413 (pour / soit environ
3500Mo),
- cylindre : début=10413, fin=79655 (pour /home soit environ
34080Mo),
- Clonage de ces partitions sur hdc en cliquant sur le bouton "RAID"
et en sélectionnant "Clonage...",
- Création de la partition de type swap sur hda du
cylindre 1 jusqu'au 2081 (1024Mo soit Mémoire vive x 2),
- Création de la partition de type swap sur hdc du
cylindre 1 jusqu'au 2081 (1024Mo soit Mémoire vive x 2),
L'illustration suivante montre un aperçu du partitionnement
réalisé :
Figure 1 : Informations sur le disque
Maintenant il ne reste plus qu'à associer les partitions
de type "RAID logiciel" pour en faire des périphériques
RAID. Pour cela, on clique sur "Créer un périphérique
de type RAID" (on peut le faire seulement après avoir créé
au moins deux partitions de type "RAID logiciel"). On va associer
les partitions "RAID logiciel" deux à deux, chosir le type
de RAID (le type 1 dans notre cas), indiquer le point de montage (/boot,
/var, / ou /home) et nommer le nouveau périphérique
(les noms vont de /dev/md0 jusqu'à /dev/md31).
On obtient ainsi 4 périphériques RAID-1
:
/dev/md0 associant hda1 et hdc1 (/boot),
taille : 100 Mo
/dev/md1 associant pour hda3 et hdc3 (/var),
taille : 500 Mo
/dev/md2 associant pour hda5 et hdc5 (/),
taille : 3,5 Go
/dev/md3 associant pour hda6 et hdc6 (/home),
taille : 34Go
Après avoir réalisé ce partitionnement,
on poursuit l'installation de Fedora Core 2 en faisant une installation minimale
(en installant tout de même un environnement graphique et quelques outils
pratiques). Puis nous installerons par la suite les dernières versions
des outils dont nous aurons besoin (samba 3.0.11, tomcat 5.5...).
A la fin de l'installation de Linux Fedora Core 2, le
RAID est normalement actif sur la machine. Une dernière manipulation
est indispensable pour écrire le MBR du disque hda sur hdc.
En effet, pour l'instant on ne peut "booter" que sur le disque hda.
Pour remédier à cela et pouvoir "booter" à partir
de n'importe quel disque : dd if=/dev/hda of=/dev/hdc bs=512 count=1.
Le fichier /etc/fstab a automatiquement été
écrit ainsi (on peut y voir nos 4 périphériques RAID) :
/dev/md2 / ext3 defaults 1 1
/dev/md0 /boot ext3 defaults 1 2
none /dev/pts devpts gid=5,mode=620 0 0
none /dev/shm tmpfs defaults 0 0
/dev/md3 /home ext3 defaults 12
none /proc proc defaults 0 0
none /sys sysfs defaults 0 0
/dev/md1 /var ext3 defaults 1 2
/dev/hda2 swap swap defaults 0 0
/dev/hdc2 swap swap defaults 0 0
/dev/cdrom /mnt/cdrom udf,iso9660 noauto,owner,kudzu,ro 0 0
/dev/fd0 /mnt/floppy auto noauto,owner,kudzu 0 0
On peut rajouter à ce fichier les priorités
décrites précédemment au niveau des partitions swap (c'est
à dire : pri=1).
Par défaut, le noyau est compilé avec le
support du RAID. Nous allons administrer nos périphérques RAID
de 2 façons :
- avec le paquetage raidtools (il fournit un ensemble d'outils permettant
de gérer les périphériques RAID),
- avec le paquetage mdadm (une seule commande : sbin/mdadm).
Nous allons utiliser ces 2 outils conjointement.
Nous nous contentons d'utiliser les paquetages intégrés
à Fedora Core 2(disponible sur les CDs d'installation). Aucun paquetage
supplémentaire n'est installé, même s'il en existe des versions
plus récentes, ceux-ci sont amplement suffisants :
[root@localhost root]# rpm -qa | grep raid
raidtools-1.00.3-8
[root@localhost root]# rpm -qa | grep mdadm
mdadm-1.5.0-3
3- Gestion des périphériques RAID
a) avec raidtools
Le fichier /proc/mdstat permet de voir l'état
du mirroring. Ce fichier permet, à tout moment, de voir si le
RAID est actif, inactif ou s'il est en resynchronisation (on parle également
de reconstruction), en bref, ce fichier est incontournable si l'on veut suivre
l'état des périphériques RAID.
[root@localhost root]# more /proc/mdstat
Personalities : [raid1]
md1 : active raid1 hda3[0] hdc3[1]
512000 blocks [2/2] [UU]
md2 : active raid1 hda5[0] hdc5[1]
3584256 blocks [2/2] [UU]
md3 : active raid1 hda6[0] hdc6[1]
34897664 blocks [2/2] [UU]
md0 : active raid1 hda1[0] hdc1[1]
102656 blocks [2/2] [UU]
unused devices: <none>
Ici, le fichier /proc/mdstat indique que les
4 périphériques sont bien actifs et les disques sont synchronisés.
Astuce:
Pour visualiser le fichier /proc/mdstat continuellement avec un
raffraichissement toutes les secondes :
[root@localhost root]# watch -n 1 more /proc/mdstat.
Le fichier /etc/raidtab correspond à la
configuration du RAID. Dans notre cas, il a été créé
automatiquement par les raidtools. Ce fichier n'est plus indispensable
car le système ne s'en servira plus pour gérer les périphériques
RAID. Néanmoins, il faut veiller à le conserver au cas ou l'on
voudrait faire des manipulations sur les périphériques RAID. Le
persistent-superblock permet d'écrire un superblock au début
de chaque partition participant au RAID. Cela permet au noyau de lire directement
la configuration du raid à partir des partitions impliquées, ce
qui fait que ce fichier n'est donc plus nécessaire au système
pour gérer le RAID.
Le fichier /etc/raidtab se présente ainsi : (les commentaires en italique
ont été rajoutés pour clarifier l'affichage) :
[root@localhost root]# more /etc/raidtab
# déclaration du raiddevice :
raiddev /dev/md2
# niveau de raid (ici 1 pour le mirroring) :
raid-level 1
# nombre de disques mirrorés :
nr-raid-disks 2
chunk-size 256
persistent-superblock 1
# nombre de disque de rechange :
nr-spare-disks 0
# partition physique à "mirrorer" :
device /dev/hda5
# Première partition déclarée (0) :
raid-disk 0
# partition physique à "mirrorer"
device /dev/hdc5
# Deuxième partition déclarée (1) :
raid-disk 1
raiddev /dev/md0
raid-level 1
nr-raid-disks 2
chunk-size 256
persistent-superblock 1
nr-spare-disks 0
device /dev/hda1
raid-disk 0
device /dev/hdc1
raid-disk 1
raiddev /dev/md3
raid-level 1
nr-raid-disks 2
chunk-size 256
persistent-superblock 1
nr-spare-disks 0
device /dev/hda6
raid-disk 0
device /dev/hdc6
raid-disk 1
raiddev /dev/md1
raid-level 1
nr-raid-disks 2
chunk-size 256
persistent-superblock 1
nr-spare-disks 0
device /dev/hda3
raid-disk 0
device /dev/hdc3
raid-disk 1
Le chunk-size est le nombre de bits lu sur un
disque avant de passer au suivant. Dans le cas du mirroring, le chunk-size
ne modifie pas la manière d'écrire les données sur les
différentes partitions. Cependant, pour la lecture, le système
va, dans notre cas, lire 256Ko sur une partition puis 256Ko sur l'autre ce qui
va améliorer les temps de lecture.
Tests de défaillances :
Pour tester le "crash" d'un disque, nous pouvons
utiliser l'utilitaire raidsetfaulty qui simule la défaillance
d'un disque. Nous allons par exemple considérer la défaillance
de hdc1 :
[root@localhost root]# raidsetfaulty /dev/md0 /dev/hdc1
[root@localhost root]# more /proc/mdstat
Personalities : [raid1]
md1 : active raid1 hda3[0] hdc3[1]
512000 blocks [2/2] [UU]
md2 : active raid1 hda5[0] hdc5[1]
3584256 blocks [2/2] [UU]
md3 : active raid1 hda6[0] hdc6[1]
34897664 blocks [2/2] [UU]
md0 : active raid1 hda1[0] hdc1[2] (F)
102656 blocks [2/1] [U_]
unused devices: <none>
La partition est marquée comme défaillante
(avec la lettre F) dans le fichier /proc/mdstat. Nous allons ensuite
la retirer du périphérique RAID avec raidhotremove :
[root@localhost root]# raidhotremove /dev/md0 /dev/hdc1
[root@localhost root]# more /proc/mdstat
Personalities : [raid1]
md1 : active raid1 hda3[0] hdc3[1]
512000 blocks [2/2] [UU]
md2 : active raid1 hda5[0] hdc5[1]
3584256 blocks [2/2] [UU]
md3 : active raid1 hda6[0] hdc6[1]
34897664 blocks [2/2] [UU]
md0 : active raid1 hda1[0]
102656 blocks [2/1] [U_]
unused devices: <none>
Ainsi, la partition n'apparaît plus dans le fichier
/proc/mdstat, elle est retirée du périphérique
RAID. Mais, pour simuler le crash d'un disque (physique), par exemple hdc,
il faudrait marquer de la même manière hdc3, hdc5
et hdc6 puis les retirer ensuite également avec raidhotremove.
Reintégrons hdc1 au périphérique
/dev/md0 avec la commande raidhotadd :
[root@localhost root]# raidhotadd /dev/md0 /dev/hdc1
[root@localhost root]# more /proc/mdstat
Personalities : [raid1]
md1 : active raid1 hda3[0] hdc3[1]
512000 blocks [2/2] [UU]
md2 : active raid1 hda5[0] hdc5[1]
3584256 blocks [2/2] [UU]
md3 : active raid1 hda6[0] hdc6[1]
34897664 blocks [2/2] [UU]
md0 : active raid1 hdc1[2] hda1[0]
102656 blocks [2/1] [U_]
[=====>...............] recovery = 27.0% (28032/102656) finish=0.0min speed=28032K/sec
unused devices: <none>
On voit clairement que le périphérique RAID
/dev/md0 est en reconstruction (à 27%...). On réaffiche
le fichier /proc/mdstat quelques secondes plus tard :
[root@localhost root]# more /proc/mdstat
Personalities : [raid1]
md1 : active raid1 hda3[0] hdc3[1]
512000 blocks [2/2] [UU]
md2 : active raid1 hda5[0] hdc5[1]
3584256 blocks [2/2] [UU]
md3 : active raid1 hda6[0] hdc6[1]
34897664 blocks [2/2] [UU]
md0 : active raid1 hdc1[1] hda1[0]
102656 blocks [2/2] [UU]
unused devices: <none>
Le périphérique /dev/md0 est à ce
stade totalement resynchronisé.
Considérons maintenant que l'on a marqué
toutes les partitions de type "RAID logiciel" du disque hdc
comme défaillantes (avec raidsetfaulty) puis nous les avons
retirées avec raidhotadd : nous avons simulé le crash
du disque entier.
Nous sommes ainsi dans cette situation :
[root@localhost root]# more /proc/mdstat
Personalities : [raid1]
md1 : active raid1 hda3[0]
512000 blocks [2/1] [U_]
md2 : active raid1 hda5[0]
3584256 blocks [2/1] [U_]
md3 : active raid1 hda6[0]
34897664 blocks [2/1] [U_]
md0 : active raid1 hda1[0]
102656 blocks [2/1] [U_]
unused devices: <none>
Procédons au rajout d'un nouveau disque (le même
puisque nous avons seulement "simulé" le crash du disque!).
Nous allons d'abord rajouter la partition hdc5 (au périphérique
/dev/md2) puis ensuite hdc6 (à /dev/md3) pour
voir ce qui se passe au niveau de la resynchronisation :
[root@localhost root]# raidhotadd /dev/md2 /dev/hdc5
[root@localhost root]# raidhotadd /dev/md3 /dev/hdc6
[root@localhost root]# more /proc/mdstat
Personalities : [raid1]
md1 : active raid1 hda3[0]
512000 blocks [2/1] [U_]
md2 : active raid1 hdc5[2] hda5[0]
3584256 blocks [2/1] [U_]
[>....................] recovery = 3.1% (80768/3584256) finish=4.0min speed=10096K/sec
md3 : active raid1 hdc6[2] hda6[0]
34897664 blocks [2/1] [U_]
resync=DELAYED
md0 : active raid1 hda1[0]
102656 blocks [2/1] [U_]
unused devices: <none>
La reconstruction des disques se fait séquentiellement.
Une fois que /dev/md2 sera complètement resynchronisé,
alors ce sera au tour de /dev/md3 (pour l'instant ce dernier est en
attente de synchronisation : resync=DELAYED). Quelques instants plus
tard on peut afficher l'état général :
[root@localhost root]# more /proc/mdstat
Personalities : [raid1]
md1 : active raid1 hda3[0]
512000 blocks [2/1] [U_]
md2 : active raid1 hdc5[1] hda5[0]
3584256 blocks [2/2] [U_]
md3 : active raid1 hdc6[1] hda6[0]
34897664 blocks [2/2] [UU]
md0 : active raid1 hda1[0]
102656 blocks [2/1] [U_]
unused devices: <none>
/dev/md2 et /dev/md3 sont synchronisés.
2) avec mdadm
Cet outil offre plus ou moins les mêmes fonctionnalités
que les raidtools. Il se présente comme un binaire (sbin/mdadm)
et se lance avec de nombreux paramètres.
mdadm offre la possibilité visualiser
le détail d'un périphérique RAID (/dev/md0 par
exemple) de la façon suivante :
[root@localhost root]# mdadm --detail /dev/md0
/dev/md0:
Version : 00.90.01
Creation Time : Fri Mar 18 11:19:29 2005
Raid Level : raid1
Array Size : 102656 (100.25 MiB 105.12 MB)
Device Size : 102656 (100.25 MiB 105.12 MB)
Raid Devices : 2
Total Devices : 2
Preferred Minor : 0
Persistence : Superblock is persistent
Update Time : Fri Mar 25 18:17:18 2005
State : clean, no-errors
Active Devices : 2
Working Devices : 2
Failed Devices : 0
Spare Devices : 0
Number Major Minor RaidDevice State
0 3 1 0 active sync /dev/hda1
1 22 1 1 active sync /dev/hdc1
UUID : ec58728f:eacbb483:cd470a58:ffc83b88
Events : 0.627
Tests de défaillances :
De la mme manire qu'avec les raidtools, il
est possible de raliser des tests de dfaillance par simulation.
Marquage de hdc3 comme défaillant ( même
fonction que raidsetfaulty):
[root@localhost root]# mdadm /dev/md1 --fail /dev/hdc3
mdadm: set /dev/hdc3 faulty in /dev/md1
Retrait de hdc3 du périphérique
RAID /dev/md1 (même fonction que raidhotadd) :
[root@localhost root]# mdadm /dev/md1 --remove /dev/hdc3
mdadm: hot removed /dev/hdc3
Visualisation du priphrique /dev/md1 :
[root@localhost root]# mdadm --detail /dev/md1
/dev/md1:
Version : 00.90.01
Creation Time : Fri Mar 18 11:20:16 2005
Raid Level : raid1
Array Size : 512000 (500.00 MiB 524.29 MB)
Device Size : 512000 (500.00 MiB 524.29 MB)
Raid Devices : 2
Total Devices : 1
Preferred Minor : 1
Persistence : Superblock is persistent
Update Time : Fri Mar 25 18:17:42 2005
State : clean, no-errors
Active Devices : 1
Working Devices : 1
Failed Devices : 0
Spare Devices : 0
Number Major Minor RaidDevice State
0 3 3 0 active sync /dev/hda3
1 0 0 -1 removed
UUID : 92176514:3efa7fd1:391fcf73:76dbc1a9
Events : 0.38488
Rintgration de hdc3 (mme fonction que raidhotadd)
:
[root@localhost root]# mdadm /dev/md1 --add /dev/hdc3
mdadm: hot removed /dev/hdc3
La commande suivante permet l'envoi automatique d'emails
en cas de dfaillance au niveau de n'importe quel priphrique RAID :
[root@localhost root]# mdadm --monitor --mail=service.archivage@enst-bretagne.fr
--delay=10 --daemonise /dev/md*
Après avoir mis défaillant hdc3 sur
/dev/md1, par défaut l'email suivant est envoyé (à
l'adresse précisée par la commande citée au dessus) :
Date: Tue, 29 Mar 2005 8:55:47 +0200
De: mdadm monitoring <root@localhost.localdomain>
à: service.archivage@enst-bretagne.fr
Objet: Fail event on /dev/md1:localhost.localdomain
This is an automatically generated mail message from mdadm
running on localhost.localdomain
A Fail event had been detected on md device /dev/md1.
Faithfully yours, etc.
Ainsi, l'administrateur peut agir au plus vite en cas
de défaillance de l'un des disques.
4- Conclusion - Bilan
Le RAID logiciel sous Linux apparaît donc comme
assez simple à mettre en oeuvre. L'idée est de simplifier au maximum
la tâche de l'administrateur système. Dans cette solution de RAID
logiciel, si un disque venait à "griller", l'administrateur
va devoir :
- Trouver un nouveau disque de taille supérieure ou égale à
celui qui a "grillé",
- Le partitionner de la même manière,
- Reconstruire (ou synchroniser) les périphériques RAID à
l'aide des commandes ci-dessus (raidtools ou mdadm),
On peut noter, par évidence, que les actions 1
et 3 ne posent biensûr aucun problème. La première action
(qui est incontournable!) permettra à l'admministrateur de bricoler un
peu... Le RAID-1 est résistant à la défaillance d'un disque.
En effet, le système peu continuer de s'exécuter malgré
un disque HS. Mais, la défaillance d'un disque va obligatoirement engendrer
l'arrêt du système (c'est à dire du serveur d'archivage)
afin de remplacer le disque endommagé. Ce nouveau disque (vierge) devra
être partitionné de la même manière que le disque
"grillé". La solution la plus adaptée est de "booter"
avec un liveCD ou un disque de recupération et d'exécuter
la commande suivante : dd if=/dev/hda of=/dev/hdc afin de recopier
le disque "valide" sur le nouveau disque, et ce, bits à bits.
Il faut également s'assurer de l'emplacement des disques sur les nappes
IDE (hda est en Primary Master et hdc en Secondary Master).
Ensuite on peut "rebooter" normalement, et, par un script, procéder
à la resynchronisation (même si les disques sont normalement déjà
synchronisés puisque "identiques").
Une solution en RAID "matériel" serait
plus intéressante dans notre cas, car plus simple d'administration. En
effet dans la plupart des cas, l'administrateur n'aurait pour tâche uniquement
que de remplacer le disque qui crashé! Les cartes mères gérant
le RAID "matériel" sont assez onnéreuses, mais n'aillant
pas ce type de matériel à disposition nous utiliserons le RAID
logiciel. D'autant que, une fois le serveur d'archivage terminé, il pourra
s'installer sur n'importe quelle machine standard, sans avoir recours à
des cartes spécialisées.
Maj le 29-03-2005