Introducción

ISCSI es un estandar del protocolo SCSI que permite la distribución de dispositivos de bloques a través de TCP/IP. Dicho protocolo se utiliza por norma general en escenarios donde se ve involucrada una SAN o al menos una NAS, que se encargan de proveer almacenamiento en la red. Gracias a este estandar podemos tener centralizado el almacenamiento de múltiples máquinas y hasta podríamos hacer que estas arrancasen con un dispositivo de bloques proporcionado por ISCSI. Para ver su funcionamiento, vamos a plantear un escenario donde tendremos un servidor (debian) y dos clientes (debian y windows). Si queréis replicar el escenario, os dejo el Vagrantfile que he utilizado. Intentaremos conseguir los siguientes objetivos:

Para más información sobre ISCSI consulta aquí.

Configuración del servidor

Antes de configurar ISCSI en el servidor, vamos a crear un RAIDZ-2, tal y como hicimos en la entrada de ZFS. Crearemos el raid, nombrandolo como ISCSI, formado por 4 de los discos que hemos añadido. Después añadiremos un disco de reserva y crearemos 3 volúmenes lógicos, por lo que seguimos estas instrucciones.

zpool create -f ISCSI raidz2 /dev/sdb /dev/sdc /dev/sdd /dev/sde spare /dev/sfd
zfs create -V 500mb ISCSI/vol1
zfs create -V 500mb ISCSI/vol2
zfs create -V 500mb ISCSI/vol3

Reitero que esto no es necesario. Si queréis replicar el ejercicio, solo necesitáis terminar con una serie de volúmenes lógicos, o dispositivos de bloques reconocibles por el sistema, es decir, que podáis encontrarlos en /dev/. Dicho esto, pasamos a la configuración del servidor ISCSI. En este caso vamos a utilizar el paquete tgt, por lo que lo instalamos con apt.

apt install tgt

Caso 1. Target con 1 LUN y cliente Linux anónimo

Configuración del servidor

Y procedemos a crear el primer target con el siguiente comando.

tgtadm --lld iscsi --op new --mode target --tid 1 -T iqn.2020-02.es.luisvazquezalejo:target1

De aquí nos quedamos sobre todo con la sintáxis del último campo que determina la dirección y el propio nombre del target. Es decir la sintaxis sería

iqn.año-mes.es.dominio:nombre-del-target

Después añadimos la unidad lógica al target.

tgtadm --lld iscsi --op new --mode logicalunit --tid 1 --lun 1 -b /dev/ISCSI/vol1

Podemos ver el estado del target ejecutando tgtadm --lld iscsi --op show --mode target, obteniendo una salida como esta. Por último solo tenemos que introducir el siguiente comando para crear la ACL correspondiente y de esta forma que los clientes puedan encontrar la LUN.

tgtadm --lld iscsi --op bind --mode target --tid 1 -I ALL

Configuración del cliente [ISCSI Initiator]

La configuración de un cliente Linux para que use los target de ISCSI, es bastante simple. Para empezar tenemos que instalar open-iscsi, por lo que ejecutamos.

apt install open-iscsi

Después nos dirigimos al fichero /etc/iscsi/initiatorname.iscsi y modificamos última linea, estableciendo la dirección utilizará más tarde el demonio de iscsi. En mi caso queda de la siguiente forma.

## DO NOT EDIT OR REMOVE THIS FILE!
## If you remove this file, the iSCSI daemon will not start.
## If you change the InitiatorName, existing access control lists
## may reject this initiator.  The InitiatorName must be unique
## for each iSCSI initiator.  Do NOT duplicate iSCSI InitiatorNames.
InitiatorName=iqn.2020-02.es.luisvazquezalejo:target1

De momento, esto no lo vamos a necesitar, ya que primero vamos a buscar e iniciar el target manualmente. Para hacer esto tenemos que introducir las siguientes instrucciones.

# Escaneamos los targets de la máquina 192.168.100.10
iscsiadm -m discovery -t st -p 192.168.100.10
192.168.100.10:3260,1 iqn.2020-02.es.luisvazquezalejo:target1
# Iniciamos el target
root@clienteLinux:/home/vagrant# iscsiadm -m node -T iqn.2020-02.es.luisvazquezalejo:target1 -p 192.168.100.10 -l
Logging in to [iface: default, target: iqn.2020-02.es.luisvazquezalejo:target1, portal: 192.168.100.10,3260] (multiple)
Login to [iface: default, target: iqn.2020-02.es.luisvazquezalejo:target1, portal: 192.168.100.10,3260] successful.
# Comprobamos que se ha iniciado
lsblk -f
NAME FSTYPE LABEL UUID                                 FSAVAIL FSUSE% MOUNTPOINT
sda
├─sda1
│    ext4         b9ffc3d1-86b2-4a2c-a8be-f2b2f4aa4cb5   11.1G    34% /
├─sda2
│
└─sda5
     swap         f8f6d279-1b63-4310-a668-cb468c9091d8                [SWAP]
sdb
# Ahora tenemos un nuevo dispositivo de bloques; sdb que podremos formatearlo y montarlo.

Si quisiésemos cerrar la sesión, tenemos que utilizar el parámetro -u.

iscsiadm -m node -T iqn.2020-02.es.luisvazquezalejo:target1 -p 192.168.100.10 -u

Este nuevo dispositivo de bloques (/dev/sdb), podremos gestionarlo como otro cualquiera. Aunque el protocolo que estamos usando es tcp/ip, a ojos Linux es un dispositivo que está conectado como podría estarlo un disco SATA. Vamos a formatearlo y montarlo.

root@clienteLinux:/home/vagrant# mkfs.ext4 /dev/sdb
mke2fs 1.44.5 (15-Dec-2018)
Creating filesystem with 512000 1k blocks and 128016 inodes
Filesystem UUID: fddbeb8d-870f-4f5b-add2-b7aefaebd39b
Superblock backups stored on blocks: 
	8193, 24577, 40961, 57345, 73729, 204801, 221185, 401409

Allocating group tables: done
Writing inode tables: done
Creating journal (8192 blocks): done
Writing superblocks and filesystem accounting information: done 

root@clienteLinux:/home/vagrant# mkdir ISCSI
root@clienteLinux:/home/vagrant# mount /dev/sdb ISCSI/

Comprobamos que está montado

lsblk -f
NAME   FSTYPE LABEL UUID                                 FSAVAIL FSUSE% MOUNTPOINT

...

sdb    ext4         fddbeb8d-870f-4f5b-add2-b7aefaebd39b  382.5M    14% /home/vagrant/ISCSI

A continuación vamos a automatizar la cargar del target y el montaje del volumen. Para esto vamos a necesitar una unidad de systemd que se encargará de montar los volúmenes después de que inicie open-iscsi.service. Antes vamos a cargar el target en la configuración de iscsi con los siguientes parámetros.

iscsiadm --mode node -T iqn.2020-02.es.luisvazquezalejo:target1 -o update -n node.startup -v automatic

Después nos dirigimos al fichero /etc/iscsi/iscsiadm.conf y modificamos el siguiente valor de manual a automatic.

#node.startup = manual
node.startup = automatic

Después reiniciamos el servicio y observamos como se carga automáticamente.

Por útlimo vamos a crear la unidad de systemd tipo .mount que mencionamos antes. La sintaxis es bastante sencilla, y es que solo tenemos que indicar qué vamos a montar y dónde lo vamos a montar. En este ejercicio vamos a crear el directorio /ISCSI donde crearemos a su vez, el árbol de directorios en el cual estarán todas las unidades montadas por ISCSI (por lo que ejecutamos mkdir /ISCSI). Ahora sí, creamos la unidad:

[Unit]
Description=Unidad de montaje para el target1
After=open-iscsi.service

[Mount]
What=/dev/disk/by-uuid/fddbeb8d-870f-4f5b-add2-b7aefaebd39b
Where=/ISCSI/target1
Type=ext4
Options=defaults

[Install]
WantedBy=multi-user.target

Las unidades de tipo mount deben tener un nombre igual al directorio del punto de montaje, solo que cambiamos las / por -. En este caso se llamará ISCSI-target1.mount. Ya solo nos faltaría reiniciar los demonios, habilitar la unidad e iniciarla:

systemctl daemon-reload
systemctl enable ISCSI-target1.mount
systemctl start ISCSI-target1.mount

Si probamos a ver el estado del servicio de esta unidad, podemos comprobar que está en enable por lo que se ejecutará al inicio del sistema después de open-iscsi.

● ISCSI-target1.mount - Unidad de montaje para el target1
   Loaded: loaded (/etc/systemd/system/ISCSI-target1.mount; enabled; vendor preset: enabled)
   Active: active (mounted) since Tue 2020-02-04 17:39:22 GMT; 4min 15s ago
    Where: /ISCSI/target1
     What: /dev/sdb
    Tasks: 0 (limit: 544)
   Memory: 112.0K
   CGroup: /system.slice/ISCSI-target1.mount

Feb 04 17:39:22 clienteLinux systemd[1]: Mounting Unidad de montaje para el target1...
Feb 04 17:39:22 clienteLinux systemd[1]: Mounted Unidad de montaje para el target1.

Caso 2. Target con 2 LUN y cliente Windows CHAP

Configuración del servidor

Esta vez vamos a crear un target con dos LUN. El procedimiento es prácticamente el mismo que en el primer caso por lo que primero creamos el target:

tgtadm --lld iscsi --op new --mode target --tid 2 -T iqn.2020-02.es.luisvazquezalejo:targetwindows

Después añadimos las unidades lógicas al target como hicimos antes.

tgtadm --lld iscsi --op new --mode logicalunit --tid 2 --lun 1 -b /dev/ISCSI/vol2
tgtadm --lld iscsi --op new --mode logicalunit --tid 2 --lun 2 -b /dev/ISCSI/vol3

Esta vez vamos a establecer una restricción a la hora de acceder al target, y es que activaremos la autenticación CHAP. Básicamente consiste en una autenticación usuario/contraseña, así que primero creamos al usuario y después lo añadimos al target.

#Creamos al usuario
tgtadm --lld iscsi --mode account --op new --user "Usuario" --password "contrasena1234"
#Lo añadimos al target
tgtadm --lld iscsi --mode account --op bind --tid 2 --user "Usuario"

Como este target lo utilizaremos en windows, tenemos que tener en cuenta que la contraseña tiene que tener obligatoriamente entre 12 y 15 caracteres. Por último creamos la ACL para que sea visible en el discovery.

tgtadm --lld iscsi --op bind --mode target --tid 1 -I ALL

De la misma forma que antes, podremos comprobar el estado del target ejecutando tgtadm --lld iscsi --op show --mode target, y obtendremos una salida como esta.

Configuración del cliente

Los pasos a seguir en windows son bastante simples. Encendemos la máquina, en el buscador del menú de inicio introducimos “ISCSI” y accedemos al programa “ISCSI Initiator

Después nos dirigimos a la última pestaña, la de configuración y cambiamos el nombre del initiator.

Volvemos a la primera pestaña, refrescamos la página, seleccionamos el target deseado y nos conectamos. Se nos abrirá una ventana, donde tendremos que acceder a la configuración avanzada. Aparecerá una última ventana donde tendremos que dejar marcado la casilla de enable CHAP log on e introduciremos el usuario y la contraseña que establecimos antes.

Ahora vamos a darle formato al disco y vamos a probar que podemos acceder. Para hacer esto utilizaremos el programa “Create and format disk partitions”. En este caso, vamos a crear un raid 0 y lo formatearemos con NTFS.

Por último probamos a acceder a la unidad.