Mise en oeuvre d’un système de fichier distribué et accès concurrents en SAN avec DRBD, ISCSI ,OCFS2 et DM-Multipath

Difficile de faire plus court en titre…

Je vous préviens tout de suite, ce billet risque d’être un peu long car après tout, j’ai passé du temps dessus, autant que vous en passiez, vous aussi, a me lire 🙂

Tous ceux qui ont déjà eu à mettre en oeuvre une quelconque solution de Haute-Disponibilité, se sont retrouvés un jour devant une problématique assez angoissante :

L’accès simultané (ou concurrent) à une ressource de données.

Si en lecture cela pose rarement des problèmes, en écriture, cela comment à devenir « légèrement » complexe.

Petit exemple.

Vous avez deux serveurs load-balancés (web ou autre), si vous écrivez une information sur le premier serveur, comment être sur qu’elle soit disponible sur le deuxième, et vice-versa.

Après tout, je peux aussi bien écrire sur le serveur A que sur le serveur B.

Retour en arrière donc pour vous expliquer la progression de mon raisonnement et la solution que j’ai mise en oeuvre.

Lorsque l’on désire avoir une synchronisation parfaite des données entre deux serveurs, la première méthode est d’utiliser un mode Actif/Passif (ou maître/esclave).
Le moyen le plus simple est de se baser sur DRBD dont j’avais déjà abordé le sujet ICI qui est une sorte de RAID Over IP.

La mise en place de drbd vous donne un nouveau périphérique de stockage (ou nouveau disque pour simplifier) de type /dev/drbdX.

Exemple DRBD

En cas de panne du Maître, le service est basculé sur l’Esclave et les données accessibles par celui ci.

Bascule DRBD

Bascule DRBD

Le volume DRBD, appelé par exemple /dev/drbd0 est alors « monté » en système de fichier sur la machine passive qui devient alors, active.

Je parle bien entendu de synchronisation en mode « bloc », pas d’une synchronisation de fichiers comme le fait rsync ou autre.

Dans cet exemple, le système de fichier reste standard (ext2, ext3, reiser etc…).

Si maintenant vous avez décidé de mettre en oeuvre un loadbalancing suite à la lecture de cet excellent billet 😉 , les choses se compliquent.

En effet, nous nous trouvons dans un cas de figure où les deux serveurs sont Maîtres, donc Actif.

Heureusement, depuis la version 0.8 de DRBD, les deux noeuds peuvent être « Primary ».

(nb. : la version 0.9 devrait apporter le support de plus de 2 noeuds)

Par contre, pour pouvoir utiliser ses deux noeuds en mode Primaire, il faut un système de fichier « distribué » (vous trouverez souvent le terme « shared disk file system »).

Il en existe peu et les principaux sont GFS et OCFS2.

Le premier est issu de RedHat et le second d’Oracle. Sachez que le support de ses deux systèmes de fichiers est inclus dans les noyaux Linux récents.

J’ai testé les deux quelques temps et suite à mon retour personnel d’expérience et les discussions avec d’autres « geeks » ayant joué avec les deux, j’ai une nette préférence pour OCFS2. La suite de ce billet se basera donc sur ce système de fichier.

(je vous laisse bien sûr à vos propres expériences et recherches, si vous préférez GFS ou Lustre, je ne vous jetterai pas de pierres 😀 )

Une fois mise en place, nous nous retrouvons donc avec ce type d’architecture :

OCFS2

OCFS2

La, on commence à être « poilu » non ?

Oui, MAIS, cette architecture est valable uniquement si on utilise les ressources locales des 2 serveurs (i.e. leurs disques durs).

Si je ne veux pas utiliser les disques durs de mes serveurs mais les disques d’un autre groupe de serveurs dédiés a cela ? Comment je fais ? HEIN ! Comment ???

Du calme, jeune Padawan, tu sais bien que Guiguiabloc est… à bloc…

Nous allons utiliser un SAN pour connecter nos disques distants à nos serveurs.

Un SAN !?! Mais j’ai pas de sous moi !!!

Allons, jeune Youngling, tu n’auras nul besoin de casser ton petit cochon qui te sert de tirelire, nous allons utiliser le protocole Iscsi.

L’ISCSI est du SCSI sur TCP/IP, nous allons connecter via ce protocole nos disques distants sur nos serveurs qui les verront comme s’il s’agissait de disques locaux.

(j’avais déjà abordé le sujet dans ce billet)

De plus en plus « poilu »… Mais pas encore assez. Poussons le bouchon un peu plus loin (hein Maurice ?) , je veux bien sûr de la redondance sur mes connexions Iscsi.

Et comment je fais de la haute disponibilité sur des iniatiators Iscsi ???

En utilisant un Device Mapper Multipath.

Bien sûr là vous vous dites : Guiguiabloc est fou/malade/a bloc/allumé (rayez les mentions inutiles) , et je vous répondrais… oui.

Schématisons le bouzin :

Schéma FS distribué

Schéma FS distribué

C’est beau hein ? 🙂

Après la théorie, passons à la phase la plus dure, la pratique.

  • DRBD

Récuperer les souces :

http://oss.linbit.com/drbd/8.3/drbd-8.3.0.tar.gz

tar xzvf drbd-8.3.0.tar.gz
cd drbd-8.3.0
cd drbd
make
cd ..
make tools
make install
make install-tools

Edition du fichier /etc/drbd.conf (bien sur, remplacer les valeurs par les votres)

#/etc/drbd.conf
 
global {
usage-count yes;
}
 
resource r0 {
protocol C;
startup {
become-primary-on both;
}
disk {
on-io-error   detach;
}
 
net {
allow-two-primaries;
after-sb-0pri discard-least-changes;
after-sb-1pri violently-as0p;
after-sb-2pri violently-as0p;
rr-conflict violently;
}
syncer {
rate 44M;
}
 
on DISK-GUIGUIABLOC-A { # nom du serveur 1
device     /dev/drbd0;
disk       /dev/sda4; # partition a prendre en compte
address    192.168.30.1:7788; # adresse ip et port d'écoute
meta-disk  internal;
}
on DISK-GUIGUIABLOC-B { # nom du serveur 2
device    /dev/drbd0;
disk      /dev/sda3; # partition a prendre en compte
address   192.168.30.2:7788; # adresse ip et port d'écoute
meta-disk internal;
}
}

Sur chacun des noeuds :

drbdadm create-md r0
modprobe drbd
drbdadm attach r0
drbdadm connect r0
 
Puis sur le noeud1 par exemple
drbdadm -- --overwrite-data-of-peer primary r0
 
/etc/init.d/drbd start

Vous suivez la synchro via un cat /proc/drbd

Je ne m’étends pas la dessus, j’en avais déjà parlé dans un autre billet.

  • ISCSI Target Entreprise

Sur les deux « serveurs disques », on va installer un Target ISCSI.

(en terminologie ISCSI, on parle de Target pour la cible (soit la machine qui « offre » son disque) et d’Initiator pour la machine qui va se connecter au Target).

Je vous invite cet excellent article :

http://www.unixgarden.com/index.php/administration-reseau/le-support-du-protocole-iscsi-dans-linux

Nous allons utiliser les sources du projet iSCSI Entreprise Target , ici en version 0.4.17.

wget http://kent.dl.sourceforge.net/sourceforge/iscsitarget/iscsitarget-0.4.17.tar.gz
tar xzvf iscsitarget-0.4.17.tar.gz
cd iscsitarget-0.4.17
make
make install

On prépare son /etc/ietd.conf (volontairement simplifié a l’extrème).

Vous remarquerez que j’exporte via ISCSI le volume DRBD0.

Target iqn.2009-02.fr.guiguiabloc:disk-a.disk
        Lun 0 Path=/dev/drbd0,Type=blockio
        Alias disk

On configure le fichier d’autorisation d’accès (comme les hosts.allow des wrappers tcp)

DISK-GUIGUIABLOC-a# cat /etc/initiators.allow
 
iqn.2009-02.fr.guiguiabloc:disk-a.disk ALL

Même chose sur le deuxième serveur (changer juste le nom du target).

on démarre /etc/init.d/iscsi-target start, et on vérifie

DISK-GUIGUIABLOC-a:/etc/iscsi/ifaces# /etc/init.d/iscsi-target status
iSCSI enterprise target is running at pid 7715
DISK-GUIGUIABLOC-a:/etc/iscsi/ifaces# cat /proc/net/iet/volume
tid:2 name:iqn.2009-02.fr.guiguiabloc:disk-a.disk
        lun:0 state:0 iotype:blockio iomode:wt path:/dev/drbd0
  • Open-ISCSI

Sur nos deux serveurs srv-guiguiabloc-a et srv-guiguiabloc-b, nous allons installer l’Initiator (le client ISCSI si vous préférez).

Récupérons des sources sur le site http://www.open-iscsi.org/

wget http://www.open-iscsi.org/bits/open-iscsi-2.0-870.2.tar.gz
 
tar xzvf open-iscsi-2.0-870.2.tar.gz
 
make
 
make install

On donne un nom explicite à notre Initiator, puis on démarre le service.

srv-guiguiabloc-a:/etc/iscsi# cat initiatorname.iscsi
InitiatorName=iqn.2009-02.fr.guiguiabloc:srvA
 
srv-guiguiabloc-a:/etc/iscsi# /etc/init.d/open-iscsi start
Starting iSCSI initiator service: iscsid.
Setting up iSCSI targets:iscsiadm: No records found!

Lançons une découverte du service

srv-guiguiabloc-a:/etc/iscsi# iscsiadm -m discovery -t sendtargets -p 192.168.30.1:3260
192.168.30.1:3260,1 iqn.2009-02.fr.guiguiabloc:disk-a.disk
 
srv-guiguiabloc-a:/etc/iscsi# iscsiadm -m discovery -t sendtargets -p 192.168.30.2:3260
192.168.30.2:3260,1 iqn.2009-02.fr.guiguiabloc:disk-b.disk

Un succès 😀

(Bien sûr vous reproduisez tout cela sur srv-guiguiabloc-b)

Maintenant, montons les sessions ISCSI sur nos deux Targets, sur nos deux serveurs

srv-guiguiabloc-a:~# iscsiadm -m node -T iqn.2009-02.fr.guiguiabloc:disk-a.disk -p 192.168.30.1 -l
Login session [iface: default, target: iqn.2009-02.fr.guiguiabloc:disk-a.disk, portal: 192.168.30.1,3260]
srv-guiguiabloc-a:~# iscsiadm -m node -T iqn.2009-02.fr.guiguiabloc:disk-b.disk -p 192.168.30.2 -l
Login session [iface: default, target: iqn.2009-02.fr.guiguiabloc:disk-b.disk, portal: 192.168.30.2,3260]
 
srv-guiguiabloc-b:~# iscsiadm -m node -T iqn.2009-02.fr.guiguiabloc:disk-a.disk -p 192.168.30.1 -l
Login session [iface: default, target: iqn.2009-02.fr.guiguiabloc:disk-a.disk, portal: 192.168.30.1,3260]
srv-guiguiabloc-b:~# iscsiadm -m node -T iiqn.2009-02.fr.guiguiabloc:disk-b.disk -p 192.168.30.2 -l
Login session [iface: default, target: iiqn.2009-02.fr.guiguiabloc:disk-b.disk, portal: 192.168.30.2,3260]
 
Vous devriez voir vos disques en local désormais :
 
srv-guiguiabloc-a:~# cat /proc/scsi/scsi
Attached devices:
Host: scsi1 Channel: 00 Id: 00 Lun: 00
  Vendor: IET      Model: VIRTUAL-DISK     Rev: 0
  Type:   Direct-Access                    ANSI SCSI revision: 04
Host: scsi2 Channel: 00 Id: 00 Lun: 00
  Vendor: IET      Model: VIRTUAL-DISK     Rev: 0
  Type:   Direct-Access                    ANSI SCSI revision: 04

Pour l’inclure en démarrage automatique :

iscsiadm -m node -T iqn.2009-02.fr.guiguiabloc:disk-a.disk -p 192.168.30.1 -o update -n « node.conn[0].startup » -v automatic

(je vous laisse lire la documentation et/ou l’article sur Unix Garden.)

  • Device Mapper MULTIPATH I/O

Nous allons utiliser une des couches du système Linux, le Device Mapper.

Son rôle est tout simplement de mapper un ou plusieurs périphériques de blocs sur un autre périphérique.
En fait, vous l’utilisez souvent sans peut-être le savoir avec LVM.

Vous trouverez un excellent billet la dessus sur : http://linux-attitude.fr/post/La-carte-du-peripherique

Et l’une des fonctions offertes par DM et le ISCSI, c’est le Multipath.

C’est à dire accéder à un périphérique par plusieurs chemins différents 🙂

Vous voyez ou je veux en venir ?….

Si notre Target A tombe, pas de soucis, srv-guiguiabloc-x passera par l’autre chemin, en l’occurrence le Target B, tout cela grâce au Multipath (pas celui LA hein 😉 )

(hi hi hi, désolé, il fallait que je la fasse)

Sur Debian : apt-get install multipath-tools

Editer votre fichier /etc/multipath.conf

blacklist {
devnode "sda"   # ici le disque local que j'exclue
}
defaults {
user_friendly_names yes
}
 
srv-guiguiabloc-a:# /etc/init.d/multipath-tools restart
 
srv-guiguiabloc-a:/dev/mapper# ll
total 0
crw-rw---- 1 root root  10, 63 2009-02-14 19:57 control
brw-rw---- 1 root disk 254,  0 2009-02-16 15:16 mpath0
brw-rw---- 1 root disk 254,  1 2009-02-16 15:16 mpath1

Vous voyez vos périphériques de blocs que vous pouvez utiliser comme n’importe quel autre.
En cas de déconnexion d’un Target, Multipath retirera le périphérique de la liste automatiquement.

(bien sûr, même punition pour srv-guiguiabloc-b).

  • OCFS2

On arrive « enfin » au système de fichier proprement dit.

Sur les 2 srv-guiguiabloc :

apt-get install ocfs2-tools

On créer le répertoire /etc/ocfs2

On édite un fichier cluster.conf (identique sur les deux noeuds)

node:
        ip_port = 7777
        ip_address = 192.168.30.1
        number = 0
        name = srv-guiguiabloc-a
        cluster = ocfs2
 
node:
        ip_port = 7777
        ip_address = 192.168.30.2
        number = 1
        name = srv-guiguiabloc-b
        cluster = ocfs2
 
cluster:
        node_count = 2
        name = ocfs2

Changer la valeur « O2CB_ENABLED=false » en « O2CB_ENABLED=true » dans /etc/default/o2cb

Démarrer le cluster :

srv-guiguiabloc-a:/etc/ocfs2# /etc/init.d/o2cb start
Loading module "configfs": OK
Mounting configfs filesystem at /sys/kernel/config: OK
Loading module "ocfs2_nodemanager": OK
Loading module "ocfs2_dlm": OK
Loading module "ocfs2_dlmfs": OK
Creating directory '/dlm': OK
Mounting ocfs2_dlmfs filesystem at /dlm: OK
Starting Oracle cluster ocfs2: OK

Et on formate 😀

srv-guiguiabloc-a:/etc/ocfs2# mkdir /data
srv-guiguiabloc-a:/etc/ocfs2# mkfs -t  ocfs2 -L GUIGUIABLOCFS /dev/mapper/mpath0
mkfs.ocfs2 1.2.1
Filesystem label=GUIGUIABLOCFS
Block size=4096 (bits=12)
Cluster size=4096 (bits=12)
Volume size=1439338496 (351401 clusters) (351401 blocks)
11 cluster groups (tail covers 28841 clusters, rest cover 32256 clusters)
Journal size=67108864
Initial number of node slots: 4
Creating bitmaps: done
Initializing superblock: done
Writing system files: done
Writing superblock: done
Formatting Journals: done
Writing lost+found: done
mkfs.ocfs2 successful

Et c’est tout !

N’essayer pas de formater /dev/mapper/mpath1, ou /dev/mapper/mpath0 sur srv-guiguiabloc-b, vous aurez ce message :

srv-guiguiabloc-a:/etc/ocfs2#  mkfs -t  ocfs2 -L GUIGUIABLOCFS /dev/mapper/mpath1
mkfs.ocfs2 1.2.1
Overwriting existing ocfs2 partition.
Proceed (y/N): n
Aborting operation.
 
srv-guiguiabloc-b:/etc/ocfs2#  mkfs -t  ocfs2 -L GUIGUIABLOCFS /dev/mapper/mpath0
mkfs.ocfs2 1.2.1
Overwriting existing ocfs2 partition.
Proceed (y/N): n
Aborting operation.

Ce qui prouve bien que notre volume est bien vu de srv-guiguiabloc-b, par le chemin /dev/mapper/mpath0 ou /dev/mapper/mpath1 😀

C’est pas magnifique tout cela ?

Et maintenant, le test final :

srv-guiguiabloc-a:/etc/ocfs2# mount /dev/mapper/mpath1 /data
srv-guiguiabloc-a:/etc/ocfs2# mount
/dev/sda1 on / type ext3 (rw,errors=remount-ro)
tmpfs on /lib/init/rw type tmpfs (rw,nosuid,mode=0755)
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
udev on /dev type tmpfs (rw,mode=0755)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=620)
configfs on /sys/kernel/config type configfs (rw)
ocfs2_dlmfs on /dlm type ocfs2_dlmfs (rw)
/dev/mapper/mpath1 on /data type ocfs2 (rw,_netdev,heartbeat=local)
 
srv-guiguiabloc-b:/etc/ocfs2# mount /dev/mapper/mpath0 /data
srv-guiguiabloc-b:/etc/ocfs2# mount
/dev/sda1 on / type ext3 (rw,errors=remount-ro)
tmpfs on /lib/init/rw type tmpfs (rw,nosuid,mode=0755)
proc on /proc type proc (rw,noexec,nosuid,nodev)
sysfs on /sys type sysfs (rw,noexec,nosuid,nodev)
udev on /dev type tmpfs (rw,mode=0755)
tmpfs on /dev/shm type tmpfs (rw,nosuid,nodev)
devpts on /dev/pts type devpts (rw,noexec,nosuid,gid=5,mode=620)
configfs on /sys/kernel/config type configfs (rw)
ocfs2_dlmfs on /dlm type ocfs2_dlmfs (rw)
/dev/mapper/mpath0 on /data type ocfs2 (rw,_netdev,heartbeat=local)
 
srv-guiguiabloc-a:/data# touch test
 
srv-guiguiabloc-b:/data# ls
test  lost+found

Vous pouvez vous amuser à écrire des deux côtés, couper un Target, vautrer un disque etc…

Après plusieurs essais intensifs, je vous avoue que j’ai été bluffé par le fonctionnement, que, je l’avoue, j’ai poussé à l’extrême.

Ne reste qu’à le greffer sur votre architecture « Altéonisée » que vous avez montée après la lecture de :

Switch applicatif avec OpenBSD, un Altéon à la maison ?…

Ce qui nous donne un joli résultat au final :

La Haute Dispo vue par Guiguiabloc

La Haute Dispo vue par Guiguiabloc

Très « poilu », non ? 😀

Comme dirais mon pote `g0rt :

[17:53] <`g0rt> ca c’est de la redondance vindiousse

Bon courage dans le peaufinage de votre cluster 😉

Ce billet a été posté dans architecture, linux et taggé , , , , , , . Bookmark ce permalink.

61 commentaires sur “Mise en oeuvre d’un système de fichier distribué et accès concurrents en SAN avec DRBD, ISCSI ,OCFS2 et DM-Multipath

  1. Excellente idée d’assemblage de tous ces éléments.
    Niveau perf l’iscsi par dessus ton drbd ca t’a fait perdre beaucoup?

    Le coup du double attachement iscsi c’est tout simplement génial!

  2. Merci 😀

    Je n’ai pas trouver une perte de performance si importante que cela, bien évidemment il vaut mieux dédier une interface réseau à chaque élément de la chaîne mais l’iscsi est connu pour être gourmand en ressources CPU. Je te conseille fortement une carte réseau TOE dont les prix commence à chuter (oublie les cartes dédiées ISCSI dont le prix fait frémir).

    Si j’ai un peu de temps, je pousserais un benchmark plus élaboré pour comparer.

  3. Bonjour,

    C’est exactement ce que je cherche ;> j’ai un petit soucis lors de la compilation de iscsitarget ( suis debian5 et kernel 2.6.28.7-default1

    CC [M] /usr/src/iscsitarget-0.4.17/kernel/block-io.o
    /usr/src/iscsitarget-0.4.17/kernel/block-io.c: In function ‘blockio_open_path’:
    /usr/src/iscsitarget-0.4.17/kernel/block-io.c:164: error: implicit declaration of function ‘open_bdev_excl’
    /usr/src/iscsitarget-0.4.17/kernel/block-io.c:164: warning: assignment makes pointer from integer without a cast
    /usr/src/iscsitarget-0.4.17/kernel/block-io.c: In function ‘blockio_detach’:
    /usr/src/iscsitarget-0.4.17/kernel/block-io.c:328: error: implicit declaration of function ‘close_bdev_excl’
    make[2]: *** [/usr/src/iscsitarget-0.4.17/kernel/block-io.o] Error 1
    make[1]: *** [_module_/usr/src/iscsitarget-0.4.17/kernel] Error 2

    Pour Drbd no soucis pour le reste bien suis bloqué pour le mom.

    Un grand merci si tu as une idée.

    Phil

  4. Bonjour,
    il manque peut-être quelque chose dans ton kernel, vu la version, tu l’as compilé toi même ?

    Rien ne dit non plus que la version 0.4.17 de iscsitarget soit compatible avec ton kernel assez récent et/ou qu’il faille le patcher.

  5. Bonjour,

    Bien finalement j’ai trouvé, j’ai laissé le kernel par default et installé linux-headers-2.6.26-1-amd64 depuis plus de soucis.
    Mais bon en ce moment drbd sync 950gig et il faut 20h sniff
    Merci à toi

  6. Hum j’ai quand même un soucis, enfait j’ai un seul serveur qui va connecter le cluster via iscsi mais il est sous FreeBSD6.1 et je ne peux pas le changer.
    Cela va surement être hard.

  7. J’ai compris je vais devoir me passer de iscsi-target sur le cluster et installer un heartbeat avec NFS

    ne pas installer dm-multipath sur le client.

    mais alors est-ce utile d’installer OCFS2 sur le cluster ? pour drbd primary/primary ??

    je pense que je suis reduit a faire un simple primary/secondary

    Sous freebsd il manque pas mal de chose mais j’ai pas le choix, je ne peux absolument pas toucher a la config.

  8. Cela sort complètement du sujet de ce billet. Forcément qu’OCFS2 est un filesystem cluster fonctionnement sur un DRBD primary/primary. Nous sommmes en mode maitre/maitre, la tu pars sur une solution active/passive qui n’est pas le but de l’article.
    Tu trouveras un autre billet plus ancien sur ce blog sur ce genre de solution. (DRBD/heartbeat).

  9. Alors là, je dis chapeau bas ….. super article, bien illustré, bien documenté.
    Je viens de découvrir ton blog, et j’avoue que je suis épaté par la qualité de tes articles.
    Bonne continuation.

  10. Salut,

    Je reviens sur cette article, savoir si tu as regardé pour aller plus loin les utilisations de filesystèmes distribués genre GlusterFS qui me parait très intéressant, essayé vite fait de mon côté avec des vm.

    Je me pose la question de savoir si ce n’est pas mieux de partir sur un glusterfs plutôt qu’un master/master. Lorsque l’on fait du HA, soit on veut un backup dans ce cas un bête master/slave suffit. Soit l’activité généré sur le seul master risque de crouler la machine sous la charge (réseau, cpu, IO, …) et on se doit de proposer mieux. Le master/master c’est très bien surtout avec l’arrivé de plus de 2 master dans le prochain drbd mais je trouve cela peu pérenne dans le temps en cas de changement de saturation espace disque par exemple, il faut alors entamer une migration des données. Pour avoir testé cette manip sur 400Go de données je ne sais pas ce que cela donnerait sur 1 ou 2 tera par exemple.

    J’aurais juste aimer avoir ton avis sur ces filesystems distribués, si tu en as testé, si tu as l’argument qui fait que ce n’est pas bien, …

    A bientôt

    PS tu peux aussi me répondre sur mon mail si tu ne veux pas polluer ce billet

  11. salut,
    Pas de soucis pour répondre ici, autant que tout le monde en profite 🙂 Si cela devient plus ardu, on continuera par mail.

    J’ai un peu testé GlusterFS et j’ai été très désagréablement surpris par ses performances. Perso, j’ai eu de gros soucis dès que l’on enchaîne les lectures/écritures (CPU au taquet) (mais cela n’engage que moi et les quelques tests réalisés), par contre je ne semble pas être tout seul a avoir eu des soucis.

    Le but du billet était un master/master, si l’on part sur du master/slave, il y a déjà beaucoup plus de solutions existantes, déjà éprouvées.

    Tu parles de volumes en Tera, a ce niveau là, on oublie complètement ce genre de solutions et on part sur de la fibre. Les baies de disques SAN avec disque FC et tout le toutim sont là pour cela, personnellement, quand j’arrive à une capacité de stockage supérieure au Tera (même au dessus de plusieurs centaines de Go), je suis depuis longtemps passé en FO.

    Que l’on soit d’accord, ce genre de solution (iscsi, ocfs2 etc..) c’est très bien pour du HA de faibles volumétries, cela ne sera jamais un concurrent de baie de disque SAN.

    Dans l’attente de ton avis

    Amicalement

  12. Effectivement le SAN en FO c’est bien meilleur.
    Mais bon rare sont les clients qui acceptent de tels investissement, des boites moyennes ou grosses industrie oui mais les petites pme qui doivent pousser pas mal de données sur le net n’investissent jamais.

    Ils préféreront faire plusieurs cluster drbd plutôt que d’investir dans un SAN. Outre l’argumentation que l’on essaye tous de mettre en place vis à vis des clients, mon idées serait de tendre vers des filesystems distribués.
    Avantage pour le client il n’achete que des machines simples et peut faire donc évoluer son archi au fur et à mesure plutôt que d’acheter son SAN directement.

    Il faut aussi voir qu’un SAN n’offre en plus pas de redondance si il est acheté tout seul, à part le raid, si le châssis crame le client perd tout.

    Dans les autres filesystems distribués tu as eu l’occasion de jouer avec lesquels?

    Il parait que Yahoo utilise HDFS connu aussi sous le nom Hadoop mais comme c’est du JAVA perso ca me refroidie de confier un filesysteme à ce langage…

  13. D’accord avec toi.
    En système de fichier distribué, je reste sur OCFS2 qui a largement fait ses preuves en production. Sinon, on retrouve souvent le cluster Redhat et son GFS (testé et approuvé aussi :-p)
    Je ne m’amuserais pas à jouer avec des FS non éprouvés en Prod. Ses deux choix, on les retrouve souvent comme solution lowcost et les retours généraux sont plus que favorable.
    Lustre aussi me plaît bien, mais je n’ai pas eu le temps de jouer avec.

  14. Bonjour,

    Merci ce tuto très interessant, j’en profite pour poser ma question !!!
    Acutellement j’utilise des machines A et B avec xen et des machines virtuelles en local, je voudrais utiliser ISCSI car j’ai une baie nas pour stocker toutes mes machines. Etant donné que sur le même partage ICSI je vais faire tourner des machines virtuelles pour le noeud A et des machines virtuelles différentes pour le noeud B(pour pouvoir faire livemigration de XEN, bascule d’un noeud à l’autre à chaud de machine virtuelle). Si je comprends bien il faut que j’utilise GFS ou OCF2 (autrement dit un systeme de fichier distribué) pour le partage en ISCSI. Ainsi, l’accès concurrent à une machine virtuelle (ou bien des quelconques données) sur le même partage (que theoriquement il ne devrait pas y avoir) ne devrait pas poser de problèmes sur l’intégrité des données. Etes vous d’accord avec moi ou bien tout simplement utiliser ext3 ?

    Merci d’avance pour vos réponses

  15. Bonjour, félicitation pour la qualité de tes tickets.
    J’ai une petite question, je cherche à mettre en place une architecture plus simple.

    2 serveurs type dedibox.
    2 drbd configuré sur chaque serveur.

    drbd0 monté sur /var/www
    drbd1 monté sur /var/lib/mysql

    les 2 drbd formaté en ocfs2

    le but: avoir un forum phpbb redondant, ( redirection par round robin sur l’un ou l’autre)
    on peut tomber aléatoirement sur serv1 ou serv2 et alimenter le forum puisque clusterisé drbd+ocfs2

    pas de problème pour la mise en place de l’architecture.

    Par contre je n’ai jamais réussi à faire démarré la base mysql de chaque coté… quand il démarre d’un coté il fail de l’autre…
    j’ai pourtant déplacé les ibdata dans un dossier non répliqué mais sans succès.

    Si tu as une idée ou quelques minutes pour tenter de faire démarrer un mysql-server sur 2 noeuds répliqué par drbd/ocfs2 je suis preneur…

  16. Bonjour, et encore merci pour ces beaux articles.

    Une question se pose chez moi, quand on crée un document sur le premier serveur (genre office), on peut l’ouvrir sur les deux serveurs en même temps pour les modifier, il n’y a pas de verrouillage et ce sera le dernier à avoir enregistré le document qui aura sa version de sauvegardée. Est ce que OCFS2 n’est pas là pour cela justement ? gérer le verrouillage des fichiers ? De plus, à aucun endroit vous parler de heartbeat et pourtant, à l’installation de OCFS2 il est demandé. N’est il pas nécessaire ? on peut s’en passer ?

    Merci pour ces petites précisions.

  17. exact, la synchro la plus récente gagne à l’écriture.
    OCFS2 gère la cohérence d’écriture des blocs et son ordre (I/O).

    Heartbeat sert effectivement par défaut pour une installation OCFS2 de base. OSCFS2 s’en sert pour monter son système de fichier. Je n’en parle pas car c’est du secondaire, il n’y a qu’une petite partie sur laquelle OCFS2 se base et il n’est pas obligatoire. On peut très bien utiliser OCFS2 sans la couche heartbeat (o2cb configure)

  18. Bonjour guigui et tous le monde,

    Voila j’ai quasiment la même architecture mais sans drdb car fas netapp avec du ISCSI monté sur mes trois machines du cluster et bonding à la place du multipah?
    Tous fonctionne très bien, le live migration aussi. Mais machines sont stockées sur un seul partage et les voit sur mes trois noeuds. Sauf que quand je fais une copie de la machine virtuelle tout bete (cp vm1 vm2), la charge du serveur qui fait la copie ne cesse d’augmenter et le serveur REBOOT. J’ai augmenté le timout oc2fs mais rien n’y fait qu’en pense tu ?

  19. quel process montent en fleche ? c’est tes i/o wait qui flambent ?
    Je ne pensent pas que ce soit oc2fs qui déconnent, probablement la couche en dessous. quels sont les débits constatés en écriture sur les noeuds via ton netapp ?

  20. c’est la charge cpu qui monte en flèche :
    machine:~# dd if=/dev/zero of=/domains/test bs=1024 count=100000
    100000+0 records in
    100000+0 records out
    102400000 bytes (102 MB) copied, 4.40641 s, 23.2 MB/s
    Le waiting acces de la commande top tourne à environ 20% mais n’augemente pas :
    load average: 1.44, 0.62, 0.26
    Tasks: 140 total, 3 running, 136 sleeping, 0 stopped, 1 zombie
    Cpu(s): 0.1%us, 3.3%sy, 0.0%ni, 76.5%id, 20.0%wa, 0.0%hi, 0.0%si, 0.1%st

    et mpstat me donne 2% i/o wait pour le CPU0 et rien pour les autres.

    Ce que je comprends pas c’est pourquoi il reboot.

  21. 🙁 ouep étrange, y’a rien de bien inquiétant entre le taux de transfert, la charge qui reste basse et le mpstat.
    Le reboot m’inquiète plus, c’est pas un comportement normal (même avec un loadaverage a 100 j’ai vu des serveurs tenir…)
    Tu n’as rien dans le syslog ?

  22. dans le syslog , il dit qu’il a des problèmes o2cfs (kernel oups) :
    Oct 22 17:21:15 machine kernel: [260604.658946] BUG: soft lockup – CPU#0 stuck for 61s! [cp:19768]

    C’est donc la commande cp qui est incriminée car il n’accède plus au lecteur iscsi.

  23. tu as quelle version du kernel ?
    J’ai vu ce genre d’erreur sur des kernels < 2.6.25 quelle version d'ocfs2 ?

  24. kernel : 2.6.26-2-xen-amd64 (debian package) , moi aussi j’ai ces erreurs soit disant corrigés et :
    ocfs2-tools1.4.1-1

  25. pourquoi t’as un kernel xenifié ? (rien a voir sûrement).

    Déja met a jour ton module ocfs, la 1.4.1-1 date d’aout 2008, y’a eu de sacré patchs depuis.

  26. Pour completer, quand je fais cat /proc/scsi/scsi, je vois mes deux chemins…
    Mais le multipath ne veut pas entendre raison;

    J’ai tenté de faire un multipath -F, puis de redémarrer multipath, mais que dalle…

    J’ai tenté de changer le nom des LUN pour qu’ils soient identiques, pas mieux…

  27. nope, c’est bon 1 chemin (1 multipath pour 2 initiators)

    J’ai deux chemins multipaths parce que j’avais monter 8 initiators sur 4 targets lors des tests…

    Faut que je corrige ça d’ailleurs 🙂 (en même temps ca pousse à la reflexion :-p)

  28. Salut,

    J’insiste, je ne vois qu’un seul chemin 😀

    multipathd> list multipaths topology
    mpath0 (1494554000000000000000000010000000000000002000000) dm-0 IET ,VIRTUAL-DISK
    [size=1024M][features=0 ][hwhandler=0 ]
    \_ round-robin 0 [prio=0][active]
    \_ 1:0:0:0 sdb 8:16 [active][ready]
    multipathd>

    Quand je shoote l’un de mes Target, l’initiator connecté dessus se vautre lamentablement (et reboote, d’ailleurs !)

    (actuellement, mes LUN ont le même nom. J’avais le même mécanisme sans qu’ils aient le même nom)

  29. J’ai (enfin) trouvé !!!

    Multipath est configuré pour créer des devices /dev/sdX…

    Jusque là, tout va bien !
    Sauf que dans mon environnement de tests, j’utilise des VM Xen… Où je n’ai que /dev/sda1 et /dev/sda2… mais pas de /dev/sda.

    Résultat, multipath me crée bien deux devices… /dev/sda et /dev/sdb… /dev/sda étant blacklisté par la configuration… Je ne le voyais pas !

    J’ai viré les blacklists, et je vois enfin mes deux chemins !

    Avec la blacklist :

    vm-mysql-sql1:/dev/mapper# multipath -v 3 -ll
    ram0: device node name blacklisted
    ram1: device node name blacklisted
    ram2: device node name blacklisted
    ram3: device node name blacklisted
    ram4: device node name blacklisted
    ram5: device node name blacklisted
    ram6: device node name blacklisted
    ram7: device node name blacklisted
    ram8: device node name blacklisted
    ram9: device node name blacklisted
    ram10: device node name blacklisted
    ram11: device node name blacklisted
    ram12: device node name blacklisted
    ram13: device node name blacklisted
    ram14: device node name blacklisted
    ram15: device node name blacklisted
    sda1: device node name blacklisted
    sda2: device node name blacklisted
    sda: device node name blacklisted
    sdb: not found in pathvec
    sdb: mask = 0x5
    sdb: dev_t = 8:16
    sdb: size = 2097016
    sdb: subsystem = scsi
    sdb: vendor = IET
    sdb: product = VIRTUAL-DISK
    sdb: rev = 0
    sdb: h:b:t:l = 3:0:0:0
    ===== paths list =====
    uuid hcil dev dev_t pri dm_st chk_st vend/prod/rev
    3:0:0:0 sdb 8:16 -1 [undef][undef] IET ,VIRTUAL-DISK

    Sans la blacklist :

    vm-mysql-sql1:/dev/mapper# multipath -v 3 -ll
    ram0: device node name blacklisted
    ram1: device node name blacklisted
    ram2: device node name blacklisted
    ram3: device node name blacklisted
    ram4: device node name blacklisted
    ram5: device node name blacklisted
    ram6: device node name blacklisted
    ram7: device node name blacklisted
    ram8: device node name blacklisted
    ram9: device node name blacklisted
    ram10: device node name blacklisted
    ram11: device node name blacklisted
    ram12: device node name blacklisted
    ram13: device node name blacklisted
    ram14: device node name blacklisted
    ram15: device node name blacklisted
    sda1: not found in pathvec
    sda1: mask = 0x5
    sda1: dev_t = 8:1
    sda1: size = 1048576
    sda1: subsystem = xen
    sda2: not found in pathvec
    sda2: mask = 0x5
    sda2: dev_t = 8:2
    sda2: size = 8388608
    sda2: subsystem = xen
    sda: not found in pathvec
    sda: mask = 0x5
    sda: dev_t = 8:0
    sda: size = 2097016
    sda: subsystem = scsi
    sda: vendor = IET
    sda: product = VIRTUAL-DISK
    sda: rev = 0
    sda: h:b:t:l = 2:0:0:0
    sdb: not found in pathvec
    sdb: mask = 0x5
    sdb: dev_t = 8:16
    sdb: size = 2097016
    sdb: subsystem = scsi
    sdb: vendor = IET
    sdb: product = VIRTUAL-DISK
    sdb: rev = 0
    sdb: h:b:t:l = 3:0:0:0
    dm-0: device node name blacklisted
    ===== paths list =====
    uuid hcil dev dev_t pri dm_st chk_st vend/prod/rev
    #:#:#:# sda1 8:1 -1 [undef][undef] ,
    #:#:#:# sda2 8:2 -1 [undef][undef] ,
    2:0:0:0 sda 8:0 -1 [undef][undef] IET ,VIRTUAL-DISK
    3:0:0:0 sdb 8:16 -1 [undef][undef] IET ,VIRTUAL-DISK
    params = 0 0 2 1 round-robin 0 1 1 8:0 1000 round-robin 0 1 1 8:16 1000
    status = 2 0 0 0 2 1 A 0 1 0 8:0 A 0 E 0 1 0 8:16 A 0
    sda: mask = 0x4
    sda: path checker = directio (config file default)
    directio: starting new request
    directio: async io getevents returns 1 (errno=No such file or directory)
    directio: io finished 4096/0
    sda: state = 2
    sda: mask = 0x8
    sda: getprio = NULL (internal default)
    sda: prio = 1
    sdb: mask = 0x4
    sdb: path checker = directio (config file default)
    directio: starting new request
    directio: async io getevents returns 1 (errno=No such file or directory)
    directio: io finished 4096/0
    sdb: state = 2
    sdb: mask = 0x8
    sdb: getprio = NULL (internal default)
    sdb: prio = 1
    mpath0 (1494554000000000000000000010000000000000002000000) dm-0 IET ,VIRTUAL-DISK
    [size=1024M][features=0][hwhandler=0]
    \_ round-robin 0 [prio=1][active]
    \_ 2:0:0:0 sda 8:0 [active][ready]
    \_ round-robin 0 [prio=1][enabled]
    \_ 3:0:0:0 sdb 8:16 [active][ready]

    Yiiiihaaaaaa !
    Maintenant, je casse tout et je regarde à quel point ça marche (ou pas)

  30. zarbi, tu peux m’envoyer tes fichiers de conf par mail (multipath.conf ietd.conf…) ?
    et me donner le resultat de :
    fdisk -l et du /proc/scsi ?

  31. nice 😀

    content que tu avances 😀

    (nos posts se sont croisés.. :-p ah les geeks a 11h du soir…)

  32. Maintenant, avec la bonne blacklist :

    vm-mysql-sql1:~# multipath -v 3 -ll
    ram0: device node name blacklisted
    ram1: device node name blacklisted
    ram2: device node name blacklisted
    ram3: device node name blacklisted
    ram4: device node name blacklisted
    ram5: device node name blacklisted
    ram6: device node name blacklisted
    ram7: device node name blacklisted
    ram8: device node name blacklisted
    ram9: device node name blacklisted
    ram10: device node name blacklisted
    ram11: device node name blacklisted
    ram12: device node name blacklisted
    ram13: device node name blacklisted
    ram14: device node name blacklisted
    ram15: device node name blacklisted
    sda1: device node name blacklisted
    sda2: device node name blacklisted
    sda: not found in pathvec
    sda: mask = 0x5
    sda: dev_t = 8:0
    sda: size = 2097016
    sda: subsystem = scsi
    sda: vendor = IET
    sda: product = VIRTUAL-DISK
    sda: rev = 0
    sda: h:b:t:l = 2:0:0:0
    sdb: not found in pathvec
    sdb: mask = 0x5
    sdb: dev_t = 8:16
    sdb: size = 2097016
    sdb: subsystem = scsi
    sdb: vendor = IET
    sdb: product = VIRTUAL-DISK
    sdb: rev = 0
    sdb: h:b:t:l = 3:0:0:0
    dm-0: device node name blacklisted
    ===== paths list =====
    uuid hcil dev dev_t pri dm_st chk_st vend/prod/rev
    2:0:0:0 sda 8:0 -1 [undef][undef] IET ,VIRTUAL-DISK
    3:0:0:0 sdb 8:16 -1 [undef][undef] IET ,VIRTUAL-DISK
    params = 0 0 2 1 round-robin 0 1 1 8:0 1000 round-robin 0 1 1 8:16 1000
    status = 2 0 0 0 2 1 A 0 1 0 8:0 A 0 E 0 1 0 8:16 A 1
    sda: mask = 0x4
    sda: path checker = directio (config file default)
    directio: starting new request
    directio: async io getevents returns 1 (errno=No such file or directory)
    directio: io finished 4096/0
    sda: state = 2
    sda: mask = 0x8
    sda: getprio = NULL (internal default)
    sda: prio = 1
    sdb: mask = 0x4
    sdb: path checker = directio (config file default)
    directio: starting new request
    directio: async io getevents returns 1 (errno=No such file or directory)
    directio: io finished 4096/0
    sdb: state = 2
    sdb: mask = 0x8
    sdb: getprio = NULL (internal default)
    sdb: prio = 1
    mpath0 (1494554000000000000000000010000000000000002000000) dm-0 IET ,VIRTUAL-DISK
    [size=1024M][features=0][hwhandler=0]
    \_ round-robin 0 [prio=1][active]
    \_ 2:0:0:0 sda 8:0 [active][ready]
    \_ round-robin 0 [prio=1][enabled]
    \_ 3:0:0:0 sdb 8:16 [active][ready]

  33. Hello,
    j’ai un pb équivalent à celui de djrise sur une paire de serveur apache2 avec un filer equallogic iscsi.
    Si le serveur est trop chargé, je vois apparaitre des erreurs comme ca:
    BUG: soft lockup – CPU#3 stuck for 61s! [apache2:27314]
    et au bout de qq minutes, le serveur reboot… 🙁
    Kernel 2.6.26-2-amd64 (patché avec http://patchwork.kernel.org/patch/58/)
    et ocfs2-tool 1.4.1-1.
    djrise: tu as réussi à régler ton pb??
    Ughy.

  34. Bonjour et bravo pour tes excellents articles que je viens de découvrir (celui-ci et le plus ancien sur drbd et heartbeat).

    Je suis même pas un béotien dans le domaine, mais je recherche quelqu’un qui pourrait (contre rémunération) expertiser une configuration un peu plus simple que celle que tu décris ici.

    La config :
    2 serveur en partage de charge, sur RHEL avec un file systeme GFS, drbd en maître/maître, les partitions synchronisées sont sur les disques durs des deux serveurs.

    C’est donc ton schéma du début, sans iSCSI ni serveur dédié au stockage. En amont, il n’y a rien non plus, c’est un des serveurs qui aiguille le traitement (smtp) vers l’autre.

    GFS se bloque régulièrement au bout de 2 à 3 semaines en production, avec corruption du file system, il faut tout réinitialiser.

    Je cherche quelqu’un capable de :
    1) expertiser la configuration qui a été faite
    2) dire si elle correspond à l’état de l’art, si elle est largement utilisée dans des environnements de production avec très haute exigence de dispo.
    3) soit donner des pistes pour la faire fonctionner telle quelle (modif de paramètrage etc.) soit préconiser une architecture plus robuste.

    En fait la charge n’est pas réellement un problème dans mon cas, ma seule exigence est de ne perdre aucun des mails qui sont stockés sur le drbd – j’envisage donc sérieusement de revenir à une architecture plus simple et j’espère plus robuste.

    J’étudie toute proposition.
    Malagone

  35. J’ai mis la solution en place en prod pour un client qui fait du oueb (donc plein, plein, plein de petits fichiers), j’avais des perfs complètement déplorables…

    J’ai été obligé de casser le multipath et d’utiliser le mode fileio pour iscsi, afin d’avoir un cache disque sur le nas… a part que ça pète la sémantique d’ocfs2, puisqu’il peut y avoir une légère différence d’écriture entre les 2 drbd.

    Quelqu’un aurait une idée pour avoir des bonnes perfs sur le blockio, afin de récupérer le multipath ? De ce que j’ai pu lire ici et là, le fileio est bien pour les petits fichiers, le blockio pour les (très) gros… A part que la redondance ne marche plus. Groumpf.

    (Enfin, du coup, je me retrouve avec un nas en slave, quoi…)

  36. Wow terrible ton article !
    Tu n’aurais pas le même avec la suite redhat cluster ? avec l’utilisation de GFS 🙂

    Quentin

  37. Salut et merci pour l’article

    j’ai mis en place cette technique, pour test. Le seul truc que je ne comprends pas est pourquoi je n’ai qu’un device iscsi? aucune des étapes ne me produit d’erreur

    le seul truc que j’ai rajouté par rapport au tuto est de passer les 2 drbd en primary avec drbdadm, puisqu’ils ne le font pas tout seul

    une idée?

  38. une similitude dans les noms des devices ? A part un soucis dans la conf je ne vois pas (cela reste de l’attachement de disque distant)

  39. Il me crache ça au démarrage des deux disques

    scsi8 : iSCSI Initiator over TCP/IP
    [ 593.597669] scsi9 : iSCSI Initiator over TCP/IP
    [ 593.893729] scsi 8:0:0:0: Direct-Access IET VIRTUAL-DISK 0 PQ: 0 ANSI: 4
    [ 593.893729] scsi 9:0:0:0: Direct-Access IET VIRTUAL-DISK 0 PQ: 0 ANSI: 4
    [ 593.893729] sd 8:0:0:0: [sdd] 2682344688 512-byte hardware sectors (1373360 MB)
    [ 593.896114] sd 8:0:0:0: [sdd] Write Protect is off
    [ 593.896114] sd 8:0:0:0: [sdd] Mode Sense: 77 00 00 08
    [ 593.896610] sd 9:0:0:0: [sdc] 2682344688 512-byte hardware sectors (1373360 MB)
    [ 593.896610] sd 8:0:0:0: [sdd] Write cache: disabled, read cache: disabled, doesn’t support DPO or FUA
    [ 593.896610] sd 9:0:0:0: [sdc] Write Protect is off
    [ 593.896610] sd 9:0:0:0: [sdc] Mode Sense: 77 00 00 08
    [ 593.896114] sd 9:0:0:0: [sdc] Write cache: disabled, read cache: disabled, doesn’t support DPO or FUA
    [ 593.896114] sd 8:0:0:0: [sdd] 2682344688 512-byte hardware sectors (1373360 MB)
    [ 593.898065] sd 8:0:0:0: [sdd] Write Protect is off
    [ 593.898127] sd 8:0:0:0: [sdd] Mode Sense: 77 00 00 08
    [ 593.900102] sd 9:0:0:0: [sdc] 2682344688 512-byte hardware sectors (1373360 MB)
    [ 593.900116] sd 9:0:0:0: [sdc] Write Protect is off
    [ 593.900116] sd 9:0:0:0: [sdc] Mode Sense: 77 00 00 08
    [ 593.901729] sd 8:0:0:0: [sdd] Write cache: disabled, read cache: disabled, doesn’t support DPO or FUA
    [ 593.901729] sdd:sd 9:0:0:0: [sdc] Write cache: disabled, read cache: disabled, doesn’t support DPO or FUA
    [ 593.900116] sdc: unknown partition table
    [ 593.904915] sd 9:0:0:0: [sdc] Attached SCSI disk
    [ 593.938687] unknown partition table
    [ 593.938687] sd 8:0:0:0: [sdd] Attached SCSI disk

    visiblement, sd9 unknow partition table… bizarre

    je vais repartir from scratch

    en tout cas, super tutoriel, merci