Montando un iniciador iSCSI en Linux
Este post es una continuación del anterior (bueno y del anterior del anterior
). En la última entrada explicamos cómo instalar un target o servidor iSCSI en un sistema Linux con Debian Etch. Ahora vamos a continuar con el siguiente paso que es instalar el cliente iSCSI, también en un equipo con Linux, que como dijimos en los artículos anteriores se le conoce como iniciador iSCSI.
Plantearemos un ejemplo en el que nuestro disco iSCSI contiene una partición con los datos de los recursos compartidos de un servidor Samba. Para ello necesitaremos hacer lo siguiente:
- Instalar y configurar el iniciador iSCSI
- Conectar automáticamente el recurso iSCSI
- Particionar y formatear el disco iSCSI
- Montar automáticamente las particiones dentro del disco cada vez que se conecte
- Desmontar las particiones y desconectar el recurso iSCSI cuando el sistema se apague
Instalación de open-iscsi
Lo primero que vamos a hacer es instalar el software iniciador. En Linux contamos con varios iniciadores iSCSI, sin embargo el más usado es open-iscsi, además está dentro de la paquetería de Debian. Lo instalamos
# apt-get install open-iscsi
Esto nos instalará un script de inicio que carga los módulos y lanza un programa que controla el iniciador (
iscsid
), y un programa para configurar nuestro iniciador (iscsiadm
). Los módulos para iSCSI ya están presente en los kernels actules (desde el 2.6.18 en adelante) por eso no se incluyen en el paquete de open-iscsi
.
Lo primero que debemos hacer es iniciar el servicio
# /etc/init.d/open-iscsi start
Configuración de open-iscsi
La configuración de
open-iscsi
se realiza a través del comandoiscsiadm
y la misma se guarda en una base de datos. Si queremos cambiar algún parámetro de la configuración tenemos que hacerlo a través de iscsiadm
.
Detección del target
En primer lugar tenemos que indicarle a
iscsiadm
que detecte nuestro target iSCSI y lo agregue a su base de datos. Hay que aclarar queiscsiadm
tiene tres formas de operacióndiscovery
: En este modo se pueden descubrir targets y agregarlos a la base de datos.node
: En este modo se administran los targets ya descubiertos y se pueden visualizar datos acerca de estos nodos, así como conectarse a ellos.session
: En este modo se administran los targets a los que se está conectados (en los que se ha hecho login).
Para descubrir nuestro target usamos obviamente “
discovery
“
# iscsiadm -m discovery -t sendtargets -p 192.168.1.110
192.168.1.110,1 iqn.2005-02.au.com.empresa:san.200G.samba
Con lo que le indicamos a
iscsiadm
que descubra los targets que le ofrece el portal ubicado en 192.168.1.110. El método que usa para descubrirlo es “sendtargets
“, que es el método soportado más estable a la fecha (existen otros métodos, como por ejemplo uno que resuelve nombre de targets).
Como vemos descubrió el target que instalamos anteriormente.
Por lo cual, si hacemos solo:
# iscsiadm -m discovery
192.168.1.110:3260 via sendtargets
Vemos que la información del servidor iSCSI target descubierto quedó almacenada en la base de datos de iscsiadm
Ahora, si queremos saber cuál es la información que se almacenó sobre el target descubierto, tenemos que operar en modo nodo
# iscsiadm -m node --targetname iqn.2005-02.au.com.empresa:san.200G.samba -p 192.168.1.110
node.name = iqn.2005-02.au.com.empresa:san.200G.samba
node.transport_name = tcp
node.tpgt = 1
node.active_conn = 1
node.startup = manual
node.session.initial_cmdsn = 0
node.session.auth.authmethod = None
node.session.auth.username =
node.session.auth.password =
node.session.auth.username_in =
node.session.auth.password_in =
node.session.timeo.replacement_timeout = 120
node.session.err_timeo.abort_timeout = 10
node.session.err_timeo.reset_timeout = 30
node.session.iscsi.InitialR2T = No
node.session.iscsi.ImmediateData = Yes
node.session.iscsi.FirstBurstLength = 262144
node.session.iscsi.MaxBurstLength = 16776192
node.session.iscsi.DefaultTime2Retain = 0
node.session.iscsi.DefaultTime2Wait = 0
node.session.iscsi.MaxConnections = 1
node.session.iscsi.MaxOutstandingR2T = 1
node.session.iscsi.ERL = 0
...
Configuración de la autenticación
Si el target tiene configurada la autenticación, para pedir al iniciador un usuario y una contraseña, entonces debemos configurar esa información en nuestro iniciador. Para ello también usamos
iscsiadm
y modificamos la información almacenada para el target ya descubierto.# iscsiadm -m node --targetname iqn.2005-02.au.com.empresa:san.200G.samba -p 192.168.1.110 -o update -n node.session.auth.username -v usuario-iniciador
# iscsiadm -m node --targetname iqn.2005-02.au.com.empresa:san.200G.samba -p 192.168.1.110 -o update -n node.session.auth.password -v clave-iniciador
El comando ahora varía porque include la opcion “
-o update
“, lo que indica que la operación que vamos a llevar a cabo sobre el registro del nuestro target es de actualización de la configuración.
La opción “
-n
“, indica el registro que vamos a actualizar, que como se puede ver lo hemos tomado de las salida del mismo comando pero sin la opción de actualización. Mientras que con “v
” indicamos el valor que debe tener dicho registro. De manera que la configuración quedaría así:node.session.auth.username=usuario-iniciador
node.session.auth.password=clave-iniciador
Obviamente, el usuario y la clave deben corresponder con los que configuramos en el servidor iSCSI.
Login en el dispositivo
Ahora que la información del target ya está configurada, podemos empezar a usarlo. Para ello debemos hacer login o autenticarnos en el target.
# iscsiadm -m node -targetname iqn.2005-02.au.com.empresa:san.200G.samba
-p 192.168.1.110
-l
La opción “
-l
” indica que queremos hacer login en el target. Esto significa que el disco iSCSI estará disponible como un dispositivo de hardware más en nuestro servidor. Para comprobar si el disco iSCSI se detecto y se “conectó” al equipo, basta con ver la salida de dmesg
#dmesg
SCSI device sda: 390620475 512-byte hdwr sectors (199998 MB)
sda: Write Protect is off
sda: Mode Sense: 77 00 00 08
SCSI device sda: drive cache: write through
SCSI device sda: 390620475 512-byte hdwr sectors (199998 MB)
sda: Write Protect is off
sda: Mode Sense: 77 00 00 08
SCSI device sda: drive cache: write through
sda: sda1
sd 1:0:0:0: Attached scsi disk sda
En el ejemplo el disco iSCSI se detectó y se “conectó” al equipo como un disco SCSI más. También notamos que para el sistema nuestro disco iSCSI no se diferencia de un dsico SCSI conectado físicamente.
Creación de particiones y formateo.
Aunque el disco iSCSI ya está conectado, no es usuable hasta que definamos particiones en él y las formateemos en un sistema que el kernel maneje. Para ello podemos usar
fdisk
y mkfs
en cualquiera de sus variantes. La información de dmesg
que obtuvimos anteriormente nos indica que el disco se reconoció como /dev/sda
# fdisk /dev/sda
Para nuestro ejemplo creamos una sola partición con todo el espacio (
/dev/sda1
) y la formateamos como ext3:
# mkfs.ext3 /dev/sda1
Montaje automático del dispositivo de hardware iSCSI
Como último punto relacionado con la configuración del iniciador, deberíamos definir que se haga login al target y se conecte el disco automáticamente cada vez que se inicie el servicio
open-iscsi
, de manera que no tengamos que hacerlo a mano luego de que nuestro sistema inicie. Volvemos a utilizar iscsiadm para modificar el parámetro que maneja esta opción:# iscsiadm -m node -targetname iqn.2005-02.au.com.empresa:san.200G.samba
-p 192.168.1.110
-o update -n node.conn[0].startup -v automatic
Luego de esto, si hacemos
# /etc/init.d/open-iscsi restart
El disco iSCSI debería ser detectado automáticamente y conectado al equipo.
Montaje automático del filesystem
En nuestro ejemplo queremos que el disco iSCSI sea usado por un servicio, en este caso para almacenar los datos de usuarios que compartiremos con Samba. Por ello, necesitamos no solo que el disco iSCSI se conecte automáticamente sino que también las particiones dentro del disco se monten al inicio para que estén disponibles para el servicio que las usará.
En los sistemas Linux, el fichero
/etc/fstab
indica qué particiones deben ser montadas en el inicio, dónde y con qué opciones.
Identificación del dispositivo de hardware.
Para poder indicarle al sistema automáticamente qué partición debemos montar, tenemos que saber el dispositivo que apunta a dicha partición. En los ejemplos anteriores vimos que al iniciarse el servicio
open-iscsi
nuestro disco iSCSI se detectó como /dev/sda
y por lo tanto la partición dentro de este disco es /dev/sda1.
El problema que se presenta es que los nombres que se dan a los dispositivos iSCSI no son estáticos y pueden variar cada vez que se reinicie el equipo. Si tuvieramos más de un disco iSCSI conectado al equipo, estos pueden ser cargados en distinto orden y por lo tanto los nombres no serían consistentes.
Por ejemplo, puede ser que dos discos iSCSI, uno de 100 Gb y otro de 200 Gb se detectaran como
/dev/sda
y /dev/sdb
respectivamente; pero que luego de reiniciar el servidor, el de 100 Gb se conectara como/dev/sdb
y el de 200 Gb como /dev/sda
.
También pudiera suceder que un dispositivo usb conectado al equipo tomara el nombre
/dev/sda
, con lo que el nombre de nuestro dispositivo iSCSI tomaría otro nombre.
Por ello es necesario buscar una forma de referirnos a nuestro dispositivo de forma estática. Afortunadamente hay una forma de solucionarlo. El programa Udev es el encargado de crear los nodos de dispositivos conectados al sistema (archivos de dispositivos que se crean en
/dev
), darles un nombre, y crear links simbólicos para referirse a los dispositivos de más de una forma. Las últimas versiones de Udev crean links simbólicos persistentes a los dispositivos iSCSI.
El comando
udevinfo
nos dice qué links creó Udev para nuestro dispositivo.# udevinfo --query symlink --name /dev/sda1
disk/by-id/scsi-149455400000000000000000001000000980b00000d000000 disk/by-path/ip-192.168.1.110:3260-iSCSI-iqn.2005-02.au.com.empresa:san.200G.samba-lun-0 disk/by-uuid/3c5c1fc8-cec1-41d4-8b92-11becd5f4832
Udevinfo
nos muestra tres links simbólicos que creó en /dev
. De manera que podemos referirnos a nuestro dispositivo por su nodo o nombre en /dev
(en el ejemplo /dev/sda1
) o usando cualquiera de estos tres links creados por Udev. De estos links, los dos útlimos nos son de utilidad porque identifican unívocamente a nuestro disco.
El primero está creado usando el path, que en el caso incluye el ip del servidor iSCSI, el puerto, el nombre del target, y el identificador de la partición (
lun-0
).
El segundo se crea a partir del uuid del disco, que es un identificador único que se asigna a la partición cuando es creada, y que por ende se borra solamente si eliminamos la partición. El uuid de nuesrtra partición según udevinfo es:
3c5c1fc8-cec1-41d4-8b92-11becd5f4832
Teniendo esta información, ya sabemos qué nodo en
/dev
(o qué link simbólico) tenemos que usar en nuestra entrada en /etc/fstab
. En nuestro caso vamos a utilizar la identificación por path, usamos por lo tanto el siguiente link simbólico para el dispositivo:/dev/ disk/by-path/ip-192.168.1.110:3260-iSCSI-iqn.2005-02.au.com.empresa:san.200G.samba-lun-0 /datos auto rw 0 0
Sin embargo si reiniciamos el servidor, vemos que el disco iSCSI no es montado y que el sistema da un error diciéndonos que el dispositivo no existe. La razón es simple: el script que monta las particiones en
/etc/fstab
es cargado antes de que la red y que el servicio iniciadoropen-iscsi
. Por lo tanto el dispositivo es creado luego y por eso no se monta.
La documentación del comando mount nos dice que existe una opción de montaje para discos en red. La opción es “
_netdev
“. Esta opción indica que la partición no debe ser montada con las demás, sino que se deja sin montar para que un script posterior lo haga una vez que la red esté disponible.
En Debian el script que se encarga de montar este tipo de particiones es
/etc/init.d/mountnfs.sh
Este script es ejecutado inmediatamente después de que la red está configurada y operando (es llamado dentro de
/etc/network/if-up.d
). El script está hecho para montar principalmente recursos nfs o samba por la red. Sin embargo al mirar el script vemos que no nos sirve para dispositivos iSCSI, porque entre el inicio de la red y el montado del disco iSCSI, necesitamos que se inicie el servico open-iscsi
, y este script no provee esta opción.
De nuevo Udev nos provee un método para solucionar este problema. Además de nombrar dispositivos, Udev permite que se ejecuten programas una vez que un dispositivo es reconocido y conectado al sistema. En este caso, tenemos que decirle a Udev que ejecute el comando
mount
una vez que el disco iSCSI es reconocido y conectado.
De manera que la forma en que se monta nuestro disco, tomando en cuenta el sistema de inicio de Linux, es la siguiente:
- Se montan los sistemas de archivos que no dependen de la red
- Se configura y levanta la red
- Se levanta el servicio iniciador
open-iscsi
open-iscsi
conecta el disco iSCSI- Udev reconoce un nuevo dispositivo y corre un comando para montar las particiones dentro de él.
La configuración de Udev funciona en base a reglas. Estas reglas comparan que la información sobre el hardware conectado coincida con ciertos valores y si es así, crean el nodo del dispositivo con cierto nombre o ejecutan algún programa.
En nuestro caso debemos obtener los valores que Udev recibe de nuestro dispositivo remoto e identificar uno que nos diga que el dispositivo es un disco iSCSI. Para ello volvemos a usar
udevinfo
# udevinfo -q env -n /dev/sda
ID_VENDOR=IET
ID_MODEL=VIRTUAL-DISK
ID_REVISION=0
ID_SERIAL=1494554000000000030303030303100000000000000000000
ID_SERIAL_SHORT=494554000000000030303030303100000000000000000000
ID_TYPE=disk
ID_BUS=scsi
ID_PATH=ip-192.168.1.110:3260-iscsi-iqn.2005-02.au.com.empresa:san.200G.samba-lun-0
ID_FS_USAGE=filesystem
ID_FS_TYPE=ext3
ID_FS_VERSION=1.0
ID_FS_UUID=3c5c1fc8-cec1-41d4-8b92-11becd5f4832
ID_FS_LABEL=
ID_FS_LABEL_SAFE=
El comando interroga a Udev y le dice que muestre todos los valores del tipo “
env
” para el dispositivo /dev/sda
, o sea, nuestro disco iSCSI.
Nos interesa el valor “
ID_PATH
“, porque su valor contiene la palabra “iscsi”.
Creamos el archivo
/etc/udev/rules.d/z99_open-iSCSI.rules
con la siguiente líneaENV{ID_PATH}=="*iscsi*", RUN+="/bin/mount -a -O _netdev"
Esta regla es leída por Udev cada vez que se conecta un dispositivo nuevo al sistema. Lo que hace es verificar que el valor “
ID_PATH
” del dispositivo contenga la cadena “iscsi”, si es así, el dispositivo conectado es del tipo iSCSI y por lo tanto corre el comando mount.
Como se puede ver, mount se llama con dos parámetros:
“
-a
” para que trate de montar lo que encuentre en /etc/fstab
“
-O _netdev
” para que solo monte las entradas de /etc/fstab
que tengan marcada la opción “_netdev
“
Como la entrada en
fstab
para nuestro disco iSCSI contiene la opción “_netdev
“, será montado automáticamente.
Si hacemos la prueba y reiniciamos el servicio
open-iscsi
, veremos que en cuanto Udev detecta el nuevo disco iSCSI, monta la partición que creamos en él.
Nota 1: Es importante que el archivo de la regla de Udev tenga en su nombre un número alto, para que sea ejecutada en último lugar; de manera que primero se le de un nombre al dispositivo y se creen los links simbólicos correspondientes.
Nota 2: Hay que tener en cuenta que esta regla montará cualquier recurso en
/etc/fstab
_netdev
“, sea o no iSCSI. que tenga la opción “
Nota 3: Para entender más cómo crear reglas de udev, se puede consultar esta excelente guía
Desmontaje automático
Desmontar los sistemas de archivos alojados en un disco iSCSI de forma correcta es importante para mantener la integridad de los datos almacenados en ellos. Hay que recordar que las particiones en un disco iSCSI deben ser desmontadas mientras el servicio
open-iscsi
esta corriendo; si detenemos el servicio open-iscsi
, el disco se desconectará del equipo y por lo tanto cuando tratemos de desmontar alguna partición en él, no solo obtendremos un error sino que hasta podríamos perder datos valiosos.
Por lo tanto, debemos asegurarnos de que cuando apaguemos o reiniciemos el servidor, nuestras particiones sean desmontadas correctamente.
Debian Etch (4.0), no tiene ningún script que desmonte las particiones en un disco iSCSI. Por lo tanto, tendremos que crear un script que lo haga automáticamente. La secuencia para hacerlo correctamente, teniendo en cuenta las dependencia que hay entre servicios, es la siguiente:
- Detener cualquier programa servidor que utilice los discos iSCSI conectados
- Desmontar las particiones en los discos iSCSI
- Detener el servicio iniciador
open-iscsi
- Detener el servicio de red
Si no se sigue ese orden, lo más probable es que obtengamos algún error.
Para ello creamos el siguiente script, que es solo una modificación del script
/etc/init.d/umountnfs.sh
de Debian, pero adaptado para el servicio iSCSI:#!/bin/sh
PATH=/sbin:/usr/sbin:/bin:/usr/bin
. /lib/init/vars.sh
. /lib/lsb/init-functions
. /lib/init/vars.sh
. /lib/lsb/init-functions
do_stop() {
DIR=”"
while read DEV MTPT FSTYPE OPTS REST
do
if echo $OPTS | grep “_netdev” >/dev/null
then
DIR=”$MTPT $DIR”
fi
done</etc/mtab
DIR=”"
while read DEV MTPT FSTYPE OPTS REST
do
if echo $OPTS | grep “_netdev” >/dev/null
then
DIR=”$MTPT $DIR”
fi
done</etc/mtab
if [ $DIR ]
then
[ "$VERBOSE" = no ] || log_action_begin_msg “Unmounting iSCSI filesystems”
umount $DIR
ES=$?
[ "$VERBOSE" = no ] || log_action_end_msg $ES
fi
then
[ "$VERBOSE" = no ] || log_action_begin_msg “Unmounting iSCSI filesystems”
umount $DIR
ES=$?
[ "$VERBOSE" = no ] || log_action_end_msg $ES
fi
}
case $1 in
start)
;;
restart|reload|force-reload)
echo “Error argument ‘$1′ no supported” >&2
exit 3
;;
stop|”")
do_stop
;;
*)
echo “Usage: umount-iscsi.sh [start|stop]” >&2
exit 3
;;
esac
case $1 in
start)
;;
restart|reload|force-reload)
echo “Error argument ‘$1′ no supported” >&2
exit 3
;;
stop|”")
do_stop
;;
*)
echo “Usage: umount-iscsi.sh [start|stop]” >&2
exit 3
;;
esac
Lo que hace el script es recorrer línea por línea el archivo
/etc/mtab
(este archivo tiene líneas idénticas a las de fstab
pero solo para los sistemas de archivos que están montados en el momento), y busca aquellas en las que aparezca la opción “_netdev
“, entonces desmonta la partición correspondiente a esa línea.
Una vez creado este archivo, le damos permiso de ejecución y lo copiamos a
/etc/init.d
.# chmod u+x umount-open-iscsi.sh
# cp umount-open-iscsi.sh /etc/init.d/
Luego debemos agregar este script a los niveles de ejecución de apagado y reinicio del servidor. En Debian estos niveles son 0 y 6 respectivamente, y se usa el comando
update-rc.d
para agregarlos.# update-rc.d umount-open-iscsi.sh stop 20 0 6 .
Lo que hace este comando es crear un link simbólico a nuestro script en los directorios
/etc/rc0.d
y /etc/rc6.d
, con un identificador igual a 20 para indicar el órden en que debe ser ejecutado.
Nota: Hay que tener en cuenta que este script desmontará cualquier recurso que encuentre montado con la opción “
_netdev
“, esto puede incluir recursos smb
o nfs
.
Como en Debian, el servicio Samba (que en nuestro ejemplo es el programa que usará el disco iSCSI) tiene un identificador igual a 19 para el apagado, el servicio se apagará antes de que se desmonten las particiones en el recurso iSCSI, lo cual es correcto. Si no fuera así tendríamos que modificar el link simbólico del servicio que use el disco iSCSI, para que se apague antes de que se ejecute el script para desmontar el filesystem.
Ahora bien en Debian, el servicio
Esto debemos hacerlo en los niveles de ejecución 0 y 6, o sea en los directorios
open-iscsi
tiene un identificador igual a 20 en el apagado. Para asegurarnos de que open-iscsi
no se apague hasta que no se hayan desmontado las particiones en los discos iSCSI, cambiamos el identificador a un número más alto para que el apagado se ejecute después.Esto debemos hacerlo en los niveles de ejecución 0 y 6, o sea en los directorios
/etc/rc0.d
y /etc/rc6.d
# mv K20open-iscsi K21open-iscsi
El servicio de red se apaga después, por lo tanto no tenemos que modificarlo.
Este es el último paso y si todo sale bien tendremos nuestro servidor pereparado para conectar a discos iSCSI. A probar ya comentar.
Comentarios
Publicar un comentario