Retrouvez cet article dans : Linux Magazine 109
Cet article est consacré à la transformation d’un serveur Ubuntu en serveur iSCSI. Le protocole iSCSI est un " protocole de la couche application permettant le transport de commandes SCSI sur un réseau ". Ce qu’il faut comprendre, c’est qu’il est possible d’exporter un périphérique au travers d’un réseau en le présentant comme un périphérique SCSI. Outre le fait que le protocole SCSI est un standard de l’industrie déployé massivement en production, le fait de passer par un réseau IP classique permet de réduire les coûts de mise en œuvre par rapport au déploiement de solutions de stockage basées sur la technologie Fibre Channel. Par ailleurs, la sauvegarde des données peut se faire au niveau du serveur iSCSI, ce qui limite le coût de la solution de sauvegarde.
Néanmoins, les solutions libres ne sont pas nombreuses et il est donc difficile de convaincre un directeur informatique de basculer vers une solution de ce type basée sur du logiciel libre. Pour ma part, j’ai essayé d’utiliser la distribution OpenFiler, basée sur rPath Linux (méta-distribution à base de RedHat) et iSCSI Enterprise Target pour la partie iSCSI ; mais le produit n’est pas encore suffisamment abouti pour envisager une utilisation professionnelle.
Après un rapide passage sur la configuration matérielle et logicielle de base de la maquette, nous verrons comment exporter un disque depuis le serveur, puis comment l’importer sur le client et enfin nous configurerons le client pour utiliser ce nouveau disque.
Le schéma ci-dessous montre l’architecture que nous allons mettre en place.
![]() |
|
Fig. 1 : Architecture générale |
|
1 |
Pour ne pas m’encombrer inutilement, je me suis basé sur des machines virtuelles KVM pour monter la maquette servant de support à cet article. Les deux machines virtuelles (une pour le serveur et une pour le client) ont une configuration de base identique, à savoir :
|
Matériel |
|
|
Mémoire vive |
128 Mo |
|
Disque dur n°1 (/dev/sda) |
Disque dur IDE de 2 Go |
|
Carte réseau n°1 (eth0) |
Carte Ethernet 100Mb/s |
|
Carte réseau n°2 (eth1) |
Carte Ethernet 100Mb/s |
|
Logiciel |
|
|
Système d’exploitation |
Ubuntu Server 8.04 LTS |
|
Services |
OpenSSH Server avec les options suivantes : ? attachement du service sur l’interface eth0 ? désactivation de la connexion en root ? désactivation du forward X11 ? désactivation du sous-service SFTP |
Les éléments de configuration spécifiques sont l’adressage IP et le nom d’hôte de chacune des machines, ainsi que l’ajout d’un disque dur IDE de 10 Go au serveur iSCSI qui servira de LUN pour l’export vers le client.
Comme nous l’avons indiqué précédemment, nous disposons de 2 disques durs sur le serveur : 1 disque de 2 Go sur lequel nous avons installé le système d’exploitation et 1 disque de 10 Go que nous voulons exporter vers le client. Nous pouvons le voir avec la commande suivante :
|
2 |
|
ufiler@ufiler:~$ sudo fdisk -l Disk /dev/sda: 2147 MB, 2147483648 bytes 255 heads, 63 sectors/track, 261 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Disk identifier: 0x00059089 Device Boot      Start         End   Blocks   Id  System /dev/sda1               1          31   248976   82  Linux swap / Solaris /dev/sda2   *          32         261  1847475   83  Linux Disk /dev/sdb: 10.3 GB, 10309599232 bytes 255 heads, 63 sectors/track, 1253 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Disk identifier: 0x00000000 Disk /dev/sdb doesn’t contain a valid partition table |
Pour l’export de nos périphériques, nous utiliserons le démon ietd fourni par le package iscsitarget ; il s’agit du logiciel libre iSCSI Enterprise Target. Ce démon a en charge la présentation des périphériques aux clients, ainsi que la gestion des sessions de connexion. Il se base sur le module noyau iscsi_trgt. L’installation du package iscsitarget est simple :
|
ufiler@ufiler:~$ sudo apt-get install iscsitarget |
Une fois l’installation terminée, le démon ietd est lancé automatiquement et se met en écoute sur le port 3260. Nous pouvons le vérifier comme suit :
|
ufiler@ufiler:~$ ps -edf | grep ietd | grep -v grep root      4269     1  0 16:40 ?       00:00:00 /usr/sbin/ietd ufiler@ufiler:~$ sudo netstat -antp | grep LISTEN | grep 3260 tcp    0    0 0.0.0.0:3260    0.0.0.0:*   LISTEN    4269/ietd |
Par défaut, une target d’exemple est créée : iqn.2001-04.com.example:storage.disk2.sys1.xyz. Le format de nommage d’une target tel que défini dans la RFC est : iqn.yyyy-mm.<reversed domain name>:<identifier>. Nous pouvons voir les volumes exportés par le serveur via le fichier /proc/net/iet/volume :
|
ufiler@ufiler:~$ cat /proc/net/iet/volume tid:1 name:iqn.2001-04.com.example:storage.disk2.sys1.xyz |
Bien évidemment, il ne s’agit que d’un exemple et nous allons le modifier pour qu’il corresponde à nos besoins. Nous créons une target nommée iqn.2008-05.info.evenit.virtual:storage, à laquelle nous rattachons le périphérique /dev/sdb en tant que Lun 0. Cela nous donne donc le fichier /etc/ietd.conf suivant :
|
Target iqn.2008-05.info.evenit.virtual:storage Lun 0 Path=/dev/sdb,Type=fileio |
Il suffit maintenant de redémarrer le service iscsitarget pour que les modifications soient prises en compte :
|
ufiler@ufiler:~$ sudo /etc/init.d/iscsitarget restart |
Nous pouvons vérifier que la target et le LUN associé ont bien été créés :
|
ufiler@ufiler:~$ cat /proc/net/iet/volume tid:1 name:iqn.2008-05.info.evenit.virtual:storage lun:0 state:0 iotype:fileio iomode:wt path:/dev/sdb |
|
3 |
Avant de commencer les manipulations pour l’import du périphérique iSCSI, prenons une photo de la liste des disques durs visibles sur le client. La commande ci-dessous montre qu’il n’y a qu’un seul disque, celui sur lequel nous avons installé le système d’exploitation :
|
evenit@iscsicli1:~$ sudo fdisk -l Disk /dev/sda: 2147 MB, 2147483648 bytes 255 heads, 63 sectors/track, 261 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Disk identifier: 0x000eedc9 Device Boot      Start         End   Blocks   Id  System /dev/sda1               1          31   248976   82  Linux swap / Solaris /dev/sda2   *          32         261  1847475   83  Linux |
À l’instar de ce qui se fait côté serveur, nous utilisons un démon pour gérer les sessions de connexion aux périphériques iSCSI. Celui-ci se nomme iscsid et est fourni par le package open-iscsi. Il s’appuie sur les modules noyau libiscsi et iscsi_tcp. L’installation du package open-iscsi se fait comme suit :
|
evenit@iscsicli1:~$ sudo apt-get install open-iscsi |
Une fois l’installation terminée, le démon iscsid est lancé automatiquement. Nous pouvons donc commencer la configuration proprement dite. La première étape est la découverte des targets disponibles sur le serveur (10.0.1.254) ; cela permet au client de connaître les détails de la target avant de s’y connecter et cela se fait ainsi :
|
evenit@iscsicli1:~$ sudo iscsiadm --mode discovery \ --type sendtargets \ --portal 10.0.1.254 10.0.1.254:3260,1 iqn.2008-05.info.evenit.virtual:storage |
La commande iscsiadm est la commande à tout faire. Dans le cas présent, elle se met en mode découverte (--mode discovery) et demande au serveur 10.0.1.254 (--portal 10.0.1.254) de lui envoyer la liste des targets (--type sendtargets). Elle renvoie la liste des targets disponibles sur le serveur.
Maintenant que notre client connaît les targets disponibles, il suffit de se connecter à celles que nous souhaitons utiliser, à savoir iqn.2008-05.info.evenit.virtual:storage. La commande est simple :
|
evenit@iscsicli1:~$ sudo iscsiadm --mode node \ --targetname iqn.2008-05.info.evenit.virtual:storage \ --portal 10.0.1.254 \ --login |
Cette fois, nous sommes en mode gestion des périphériques (--mode node) et nous demandons à nous connecter (--login) à la target dont le nom est iqn.2008-05.info.evenit.virtual:storage (--targetname iqn.2008-05.info.evenit.virtual:storage) sur le serveur 10.0.1.254 (--portal 10.0.1.254). Cette commande crée une session entre le client et le serveur qui sert à la communication avec le périphérique iSCSI.
Nous pouvons vérifier très simplement que le nouveau périphérique est présent sur le système :
|
evenit@iscsicli1:~$ sudo fdisk -l Disk /dev/sda: 2147 MB, 2147483648 bytes 255 heads, 63 sectors/track, 261 cylinders Units = cylinders of 16065 * 512 = 8225280 bytes Disk identifier: 0x000eedc9 Device Boot      Start         End   Blocks   Id  System /dev/sda1               1          31   248976   82  Linux swap / Solaris /dev/sda2   *          32         261  1847475   83  Linux Disk /dev/sdb: 10.3 GB, 10309599232 bytes 64 heads, 32 sectors/track, 9832 cylinders Units = cylinders of 2048 * 512 = 1048576 bytes Disk identifier: 0x00000000 Disk /dev/sdb doesn’t contain a valid partition table |
Contrairement au démon ietd, iscsid conserve les informations relatives aux périphériques iSCSI lors du reboot. La commande iscsiadm modifie le contenu du répertoire /etc/iscsi de manière dynamique, ce qui fait que la configuration est maintenue. Par contre, la configuration par défaut fait qu’au prochain reboot la session ne sera pas ouverte automatiquement. Pour remédier à cela, nous avons deux méthodes :
1. Modifier le paramètre global de démarrage des sessions dans /etc/iscsi/iscsid.conf. Pour cela, il suffit de remplacer la ligne node.startup = manual par la ligne node.startup = automatic. C’est pratique si vous êtes sûr que vous ne ferez pas d’import dynamique que vous ne souhaitez pas garder et que vous risqueriez d’oublier au prochain boot.
2. Modifier le paramètre de démarrage session par session. Personnellement, je privilégie cette méthode qui suppose que tous les périphériques sont gérés individuellement. Pour cela, il suffit de taper la commande suivante qui modifie (--op update) le paramètre node.startup (--name node.startup) en lui donnant la valeur automatic (--value automatic) :
|
evenit@iscsicli1:~$ sudo iscsiadm --mode node  \ --targetname iqn.2008-05.info.evenit.virtual:storage \ --op update \ --name node.startup \ --value automatic |
Nous avons maintenant un serveur exportant son périphérique /dev/sdb via iSCSI et un client qui importe ce même périphérique.
Vous pourriez vouloir désactiver la session sur le client (pour maintenance par exemple). Cela se fait comme suit :
|
evenit@iscsicli1:~$ sudo iscsiadm --mode node \ --targetname iqn.2008-05.info.evenit.virtual:storage \ --portal 10.0.1.254 \ --logout |
Vous pourriez aussi souhaiter ajouter des disques durs au serveur et connecter d’autres clients à ces disques en iSCSI. Il vous faudra alors vérifier que le nom d’initiator des nouveaux clients est unique sur le réseau ; cela générerait des conflits entre les clients à la manière d’une duplication d’adresse IP. Ce paramètre est défini dans le fichier /etc/initiatorname.iscsi, dans le champ InitiatorName.
|
4 |
À présent que nous avons importé un disque dur iSCSI, il est grand temps de l’utiliser. Nous allons donc dérouler les étapes nécessaires pour l’intégrer à notre système.
Commençons donc par le partitionner ; pour cela, nous utiliserons sfdisk en remplacement du bon vieux fdisk. L’intérêt de sfdisk est qu’il accepte un fichier de configuration en entrée pour partitionner le disque en mode non interactif. Le jeu de commandes suivant permet de générer une seule partition de type Linux (83) sur le disque /dev/sdb que nous venons tout juste d’importer :
|
evenit@iscsicli1:/etc/iscsi$ echo ",,83" > /tmp/sfdisk.cfg evenit@iscsicli1:/etc/iscsi$ sudo sfdisk /dev/sdb < /tmp/sfdisk.cfg evenit@iscsicli1:/etc/iscsi$ rm /tmp/sfdisk.cfg |
Nous pouvons vérifier simplement le résultat, une partition de 10 Go et de type Linux :
|
evenit@iscsicli1:/etc/iscsi$ sudo fdisk -l /dev/sdb Disk /dev/sdb: 10.3 GB, 10309599232 bytes 64 heads, 32 sectors/track, 9832 cylinders Units = cylinders of 2048 * 512 = 1048576 bytes Disk identifier: 0xd38c3f35 Device Boot      Start         End   Blocks   Id  System /dev/sdb1               1        9832 10067967+  83  Linux |
L’étape logique qui suit est bien entendu le formatage. Nous ferons de /dev/sdc1 une partition ext3 :
|
evenit@iscsicli1:/etc/iscsi$ sudo mke2fs -j /dev/sdb1 |
Et comme une partition formatée ne sert à rien tant qu’elle n’est pas montée sur une arborescence du système, nous allons tout naturellement la monter. Pour cela, nous créons l’arborescence /data et montons /dev/sdc1 dedans. Un petit df -h permet de confirmer que la partition est bien montée (la dernière de la liste).
|
evenit@iscsicli1:/etc/iscsi$ sudo mkdir /data evenit@iscsicli1:/etc/iscsi$ sudo mount -t ext3 /dev/sdb1 /data evenit@iscsicli1:/etc/iscsi$ df -h Filesystem            Size  Used Avail Use% Mounted on /dev/sda2             1,8G  498M  1,2G  30% / varrun                 61M   44K   61M   1% /var/run varlock                61M     0   61M   0% /var/lock udev                   61M   48K   61M   1% /dev devshm                 61M     0   61M   0% /dev/shm /dev/sdb1             9,6G  150M  8,9G   2% /data |
Bien ! Si vous vous souvenez bien, le périphérique sera toujours présent au prochain boot, sans rien avoir à faire. Il faut donc faire en sorte qu’il soit utilisable aussi sans rien avoir à faire. Pour cela, il suffit d’éditer le fichier /etc/fstab pour indiquer au système que la partition /dev/sdb1 doit être montée dans /data :
|
evenit@iscsicli1:/etc/iscsi$ sudo sh -c \ "echo ‘/dev/sdb1 /data ext3 relatime 0 0’ >> /etc/fstab" |
|
5 |
Le mode de configuration du serveur que nous venons de voir passe uniquement via le fichier de configuration /etc/ietd.conf, car c’est le seul moyen de conserver la configuration lors des futurs reboots. Il est cependant possible de gérer les targets et LUN dynamiquement au travers de la commande ietadm ; c’est pratique pour tester une configuration, mais ce n’est pas pérenne. Voici cependant quelques commandes utiles :
Création d’une target de nom iqn.2008-05.info.evenit.virtual:storage2 et d’ID 2 :
|
ufiler@ufiler:~$ sudo ietadm --op new \ --tid 2 \ --params Name=iqn.2008-05.info.evenit.virtual:storage2 |
Ajout d’un LUN dont le périphérique réel est /dev/sdc à la target dont l’ID est 0 :
|
ufiler@ufiler:~$ sudo ietadm --op new \ --tid 2 \ --lun 0 \ --params Path=/dev/sdc,Type=fileio |
Nous pouvons la voir dans /proc/net/ietf/volume :
|
ufiler@ufiler:~$ cat /proc/net/iet/volume tid:1 name:iqn.2008-05.info.evenit.virtual:storage lun:0 state:0 iotype:blockio iomode:wt path:/dev/sdb tid:2 name:iqn.2008-05.info.evenit.virtual:storage 2 lun:0 state:0 iotype:blockio iomode:wt path:/dev/sdc |
Suppression du Lun 0 associé à la target 2 :
|
ufiler@ufiler:~$ sudo ietadm --op delete --tid 2 --lun 0 |
Suppression de la target dont l’ID est 2 :
|
ufiler@ufiler:~$ sudo ietadm --op delete --tid 2 |
Comme tout administrateur, nous développons un début de paranoïa et nous souhaitons sécuriser un minimum les droits d’accès aux ressources. Pour cela, nous avons à notre disposition 2 mécanismes :
1. Restreindre les adresses IP autorisées à voir les périphériques : une machine ne peut voir que les targets qu’on l’autorise à découvrir.
2. Mettre en place une authentification par mot de passe : permet de bloquer l’usurpation d’adresse IP (IP spoofing).
|
6 |
|
6.1 |
La règle la plus élémentaire en matière de sécurité est de tout interdire, puis d’autoriser au cas par cas. Nous allons donc appliquer ce principe pour restreindre l’accès à nos targets iSCSI. Pour cela, nous utiliserons les fichiers /etc/initiators.allow et /etc/initiators.deny. En sachant que /etc/initiators.deny est prioritaire sur /etc/initiators.allow, nous allons simplement écrire la ligne suivante dans /etc/initiators.deny et effacer tout le reste :
|
ALLÂ ALL |
Cela interdit l’accès à tous les targets (ALL) à partir de tous les hôtes (ALL).
Il ne nous reste plus qu’à ouvrir l’accès aux hôtes autorisés en les ajoutant dans /etc/initiators.allow comme suit :
|
iqn.2008-05.com.example:storage 10.0.1.10 |
À partir de maintenant, le target iqn.2008-05.com.example:storage est accessible uniquement à l’hôte 10.0.1.10.
|
6.2 |
Maintenant que nous avons limité l’accès à certains hôtes, nous allons restreindre l’accès aux seuls utilisateurs authentifiés. Dans notre exemple, nous limitons l’accès à la ressource iqn.2008-05.com.example:storage à l’utilisateur bob dont le mot de passe est leponge. Côté target, nous devons ajouter la limitation à la définition du target dans le fichier /etc/ietd.conf :
|
Target iqn.2008-05.com.example:storage.lvm.share01 IncomingUser bob leponge Lun 0 Path=/dev/mapper/iScsiShares_vg-iScsiShare01_lv,Type=fileio |
Une fois la modification réalisée, il faut redémarrer le démon :
|
fabien@iscsi_srv$ sudo /etc/init.d/iscsitarget restart |
Côté initiator, nous devons ajouter les mêmes informations dans le fichier /etc/iscsi/iscsid.conf :
|
node.session.auth.authmethod = CHAP node.session.auth.username = bob node.session.auth.password = leponge |
Il suffit de redémarrer le démon : sudo /etc/init.d/open-iscsi restart, pour appliquer les changements. Ensuite, il ne reste plus qu’à importer le target comme vu précédemment.
|
7 |
Vous avez maintenant vu les bases de la configuration d’un iSCSI sur Ubuntu. Loin de faire de vous un expert du sujet (je n’en suis pas un moi-même), cela vous ouvre de nouvelles perspectives dans la gestion de votre stockage. À vous d’imaginer votre propre configuration, en fonction des besoins qui sont les vôtres : multiplication des périphériques exportés et des clients.
Il faut aussi prévoir la sécurisation des données, aussi bien sur le serveur que sur le réseau. Pour le serveur, vous devriez pouvoir vous en sortir avec du RAID. Pour le réseau, il est intéressant de mettre en place des VLAN et du filtrage pour restreindre les accès, ainsi que de la redondance de lien (bonding) en cas de panne. Mais, ces sujets pourraient faire l’objet d’un article chacun...
|
Auteur : Fabien Dupont |
|
Liens |
|
iSCSI sur Wikipédia : http://fr.wikipedia.org/wiki/ISCSI iSCSI Enterprise Target : http://iscsitarget.sourceforge.net Open iSCSI : http://www.open-iscsi.org OpenFiler : http://www.openfiler.com |
Retrouvez cet article dans : Linux Magazine 109






Une target iSCSI est un périphérique bloc.
On peut donc utiliser un disque, une partition, un volume logique, une grappe de RAID, une LUN d’un SAN, etc.
Bonjour,
Je ne sais pas si c’est le lieux pour ça mais j’aurais une question concernant l’article (qui je dois l’avouer correspond exactement à ce que je cherchais)
Supposons avoir plusieurs disques durs réunis dans un VG de LVM.
Est-il possible d’avoir pour target les LV créés à partir du VG ?
Cela augmenterait la flexibilité de la gestion des disques.
Je vous cache pas que je cherche à faire un SAN maison pour pas grand chose !!!
Cordialement