Aug 17, 2009

Almacenamiento compartido en red: GFS2 + iSCSI (I)

En el presente artículo vamos a desarrollar una arquitectura de almacenamiento compartido a la que accederán de forma concurrente un par de máquinas. Las pruebas van a ser realizadas bajo un sistema operativo de tipo CentOS 5.3.

El área de datos sobre el que se configurará el acceso compartido será un volumen lógico (LogVol00) cuyo sistema de archivos será GFS2 (Global File System 2). GFS es un sistema de ficheros nativo creado por Red Hat y distribuido bajo licencia GNU, que puede ser utilizado de forma local (como por ejemplo ext3) o en cluster, de manera que varios nodos puedan estar trabajando simultáneamente sobre él sin peligro a que se corrompan los datos. La capacidad máxima de almacenamiento de GFS2 es de 8 EB.

En la figura siguiente puede observarse que el espacio de almacenamiento compartido se instalará sobre la máquina centos01, el cual será exportado a los nodos centos02 y centos03 a través del driver iSCSI (Internet Small Computer Systems Interface).


iSCSI permite la interconexión directa entre dispositivos de almacenamiento y computadores, encapsulando para ello el protocolo SCSI (familia de protocolos para comunicaciones con dispositivos de entrada/salida, especialmente dispositivos de almacenamiento) a través de una red TCP/IP. iSCSI puede utilizar tarjetas hardware dedicadas o emplear iniciadores iSCSI junto con targets (u objetivos) SCSI para establecer la conectividad a través de tarjetas Ethernet. En este artículo se empleará la segunda opción.

Cada una de las máquinas deberá tener registrado los nombres de todos los nodos en el fichero /etc/hosts.
[... ~]# cat /etc/hosts
...
192.168.1.11 centos01 centos01.local
192.168.1.12 centos02 centos02.local
192.168.1.13 centos03 centos03.local

SELinux e iptables deberán estar desactivados en los tres nodos. Al final del artículo veremos la forma de configurarlos correctamente para que no interfieran en el sistema de almacenamiento.

[... ~]# setenforce 0

[... ~]# service iptables stop

Lo primero que vamos a hacer es instalar el software necesario en los tres nodos.
[root@centos01 ~]# yum install lvm2-cluster rgmanager gfs2-utils scsi-target-utils

[root@centos02 ~]# yum install lvm2-cluster rgmanager gfs2-utils iscsi-initiator-utils

[root@centos03 ~]# yum install lvm2-cluster rgmanager gfs2-utils iscsi-initiator-utils

En el nodo centos01 editaremos el fichero de configuración del demonio tgtd (encargado de servir los espacios de almacenamiento compartido), indicando el volumen o dispositivo a exportar, el nombre de usuario y contraseña que será necesario emplear por parte de los clientes para poder conectarse al volumen, y las direcciones IP de los clientes a los que se les estará permitido conectarse.

El volumen servidor se conoce como objetivo y es definido a través de un nombre cualificado. El estándar iSCSI establece que tanto los objetivos como los iniciadores tienen que tener un nombre que siga el patrón iqn.[yyyy-mm].[dominio invertido]:[identificador].

Por último, haremos que el servicio tgtd no sea persistente tras sucesivos reinicios de la máquina, ya que como veremos más adelante, será el propio cluster el encargado de iniciarlo y detenerlo automáticamente.

[root@centos01 ~]# cat /etc/tgt/targets.conf
<target iqn.2009-08.local:vol00>
backing-store /dev/VolGroup01/LogVol00
incominguser iscsi_user d6m1p9
initiator-address 192.168.1.12
initiator-address 192.168.1.13
</target>

[root@centos01 ~]# chkconfig tgtd off

Y en los nodos centos02 y centos03 haremos lo mismo pero con los demonios iniciadores (iscsid e iscsi). En el fichero de configuración especificaremos los datos de autenticación para poder descubrir el volumen y conectarnos a él.
[... ~]# cat /etc/iscsi/iscsid.conf
...
node.session.auth.authmethod = CHAP
node.session.auth.username = iscsi_user
node.session.auth.password = d6m1p9
discovery.sendtargets.auth.authmethod = CHAP
discovery.sendtargets.auth.username = iscsi_user
discovery.sendtargets.auth.password = d6m1p9
node.conn[0].timeo.noop_out_interval = 15
node.conn[0].timeo.noop_out_timeout = 15

[... ~]# chkconfig iscsid off

[... ~]# chkconfig iscsi off

Seguidamente vamos a crear el volumen lógico que se empleará como espacio compartido en centos01, empleando para ello una partición de 64 GB que ya tendremos creada previamente y etiquetada como Linux LVM.
[root@centos01 ~]# fdisk -l
...
Disposit. Inicio Comienzo Fin Bloques Id Sistema
/dev/sdb1 1 8354 67103473+ 8e Linux LVM

Primero habrá que crear un volumen físico sobre esa partición, después el grupo de volúmenes (VolGroup01) y por último el volumen lógico (LogVol00).
[root@centos01 ~]# pvcreate /dev/sdb1

[root@centos01 ~]# vgcreate VolGroup01 /dev/sdb1

[root@centos01 ~]# lvcreate -l 100%FREE -n LogVol00 VolGroup01

Una vez que ya se tenga el volumen lógico, crearemos dentro de él un sistema de archivos GFS2. El parámetro lock_dlm indica el protocolo de bloqueo a emplear, siendo lock_dlm (DLM - Distributed Lock Manager) para el caso de acceso concurrente y lock_nolock para el caso de acceso de un único nodo. Con la opción de -t se especifica el nombre del cluster y el nombre que le queremos dar al sistema de archivos, y con la opción -j se indica el número de nodos que accederán concurrentemente al sistema de archivos.
[root@centos01 ~]# mkfs.gfs2 -p lock_dlm -t mycluster:gfs2_data -j 3 /dev/VolGroup01/LogVol00

Una vez construido el volumen, reiniciaremos el servicio tgtd y haremos que los nodos centos02 y centos03 descubran ese espacio de almacenamiento ofrecido por centos01. Cuando se realice la operación, dicha información quedará registrada de forma permanente en los directorios /var/lib/iscsi/nodes/ y /var/lib/iscsi/send_targets/.

De esta forma cada vez que posteriormente se inicie el cluster, se utilizarán dichos datos para conectarse. Si en un momento dado se quiere prescindir de dicho volumen, habría que eliminarlo de los directorios mencionados, o si por ejemplo se quiere añadir un nuevo espacio de almacenamiento compartido, habría que volver a ejecutar el comando "iscsiadm -m discovery..." para descubrirlo previamente.

Decir también que una vez que se tiene registrado un espacio de almacenamiento, el demonio encargado de realizar su importación será iscsi.
[root@centos01 ~]# service tgtd restart

[... ~]# service iscsid restart

[... ~]# iscsiadm -m discovery -t sendtargets -p centos01.local
192.168.1.11:3260,1 iqn.2009-08.local:vol00

[... ~]# ls /var/lib/iscsi/nodes/
iqn.2009-08.local:vol00

[... ~]# ls /var/lib/iscsi/send_targets/
centos01.local,3260

Para ver los dispositivos exportados por el servidor centos01 se puede ejecutar el siguiente comando:
[root@centos01 ~]# tgtadm --lld iscsi --op show --mode target

A continuación se va a crear un archivo denominado cluster.conf el cual refleje la arquitectura de los tres nodos (deberá estar situado en las tres máquinas).
[... ~]# cat /etc/cluster/cluster.conf
<?xml version="1.0"?>
<cluster alias="mycluster" config_version="1" name="mycluster">
<fence_daemon clean_start="0" post_fail_delay="0" post_join_delay="3"/>
<clusternodes>
<clusternode name="centos03.local" nodeid="1" votes="1">
<fence>
<method name="1">
<device name="centos03.local" node="centos01.local"/>
</method>
</fence>
</clusternode>
<clusternode name="centos02.local" nodeid="2" votes="1">
<fence>
<method name="1">
<device name="centos02.local" node="centos01.local"/>
</method>
</fence>
</clusternode>
<clusternode name="centos01.local" nodeid="3" votes="1">
<fence>
<method name="1">
<device name="centos01.local" node="centos01.local"/>
</method>
</fence>
</clusternode>
</clusternodes>
<cman/>
<fencedevices>
<fencedevice agent="fence_scsi" name="iscsi"/>
</fencedevices>
<rm>
<failoverdomains>
<failoverdomain name="failover_centos01" nofailback="0" ordered="0" restricted="1">
<failoverdomainnode name="centos01.local" priority="1"/>
</failoverdomain>
<failoverdomain name="failover_centos02" nofailback="0" ordered="0" restricted="1">
<failoverdomainnode name="centos02.local" priority="1"/>
</failoverdomain>
<failoverdomain name="failover_centos03" nofailback="0" ordered="0" restricted="1">
<failoverdomainnode name="centos03.local" priority="1"/>
</failoverdomain>
</failoverdomains>
<resources>
<script file="/etc/init.d/iscsi" name="iscsi"/>
<script file="/etc/init.d/iscsid" name="iscsid"/>
<script file="/etc/init.d/tgtd" name="tgtd"/>
<clusterfs device="/dev/sdb" force_unmount="1" fsid="45982" fstype="gfs2" mountpoint="/mnt/gfs2_iscsi/" name="resource_gfs2_iscsi" self_fence="0"/>
</resources>
<service autostart="1" domain="failover_centos01" exclusive="0" name="service_centos01">
<script ref="tgtd"/>
</service>
<service autostart="1" domain="failover_centos02" exclusive="0" name="service_centos02">
<script ref="iscsid">
<script ref="iscsi">
<clusterfs ref="resource_gfs2_iscsi"/>
</script>
</script>
</service>
<service autostart="1" domain="failover_centos03" exclusive="0" name="service_centos03">
<script ref="iscsid">
<script ref="iscsi">
<clusterfs ref="resource_gfs2_iscsi"/>
</script>
</script>
</service>
</rm>
</cluster>

En una primera sección (clusternodes) se definen los nombres de los tres nodos (clusternode name) así como su método fencing asociado. El fencing viene a ser una especie de protección o de bloqueo que hace que los nodos esperen en esa "barrera" para poder sincronizarse.

Para el caso del ejemplo anterior, se ha declarado un dispositivo (fencedevice) de tipo fence_scsi en el nodo centos01, y a continuación se ha asociado a los tres nodos (fence). Esto significa que si por ejemplo iniciamos centos01, éste esperará a finalizar su proceso de arranque hasta que los otros dos nodos se hayan conectado al servidor iSCSI, o si por ejemplo arrancamos centos02 y centos03, y centos01 todavía no está inicializado, esos dos nodos esperarán hasta que el servicio iSCSI esté listo antes de lanzar el cliente.

La otra sección principal del fichero de configuración es la de los recursos. Se han definido cuatro recursos: los scripts de los iniciadores iSCSI (iscsi e iscsid), el script de gestión del objetivo iSCSI (tgtd) y un volumen a ser montado.

Cuando se importe automáticamente el volumen exportado en los nodos centos02 y centos03, éste será accesible a través del dispositivo /dev/sdb (cuando un dispositivo iSCSI es importado, se crea un nuevo dispositivo de bloque de igual forma que si se añadiera un nuevo disco duro).

También se ha creado un dominio (failoverdomain) exclusivo para cada uno de los nodos. De esta forma podremos asociar posteriormente a cada uno de los dominios un determinado servicio (service), el cual iniciará y detendrá ciertos recursos (script ref, clusterfs, ...).

Así de esta forma el servicio service_centos02 hará que cuando se inicie automáticamente (autostart="1"), se ejecute en el nodo centos02 el script iscsid, a continuación el script iscsi y por último, se monte el volumen importado sobre el directorio /mnt/gfs2_iscsi/, el cual tendremos que crear previamente en los nodos centos02 y centos03.
[... ~]# mkdir /mnt/gfs2_iscsi

Ahora sólo tendremos que reiniciar los demonios gfs2, cman, rgmanager y clvmd en cada uno de los nodos, y mediante el comando chkconfig haremos que dichos demonios se inicien automáticamente cada vez que arranque el nodo.
[... ~]# service gfs2 restart

[... ~]# service cman restart

[... ~]# service rgmanager restart

[... ~]# service clvmd restart


[... ~]# chkconfig gfs2 on

[... ~]# chkconfig cman on

[... ~]# chkconfig rgmanager on

[... ~]# chkconfig clvmd on

Si ejecutamos el comando clustat, podremos ver la configuración actual del cluster que acabamos de levantar. Por un lado se tiene la lista de miembros del cluster (Member Name) y por el otro, la lista de servicios definidos (Service Name), así como su propietario (Owner) y estado (State).
[root@centos01 ~]# clustat
Cluster Status for mycluster @ Thu Aug 6 12:55:51 2009
Member Status: Quorate

Member Name ID Status
------ ---- ---- ------
centos03.local 1 Online, rgmanager
centos02.local 2 Online, rgmanager
centos01.local 3 Online, Local, rgmanager

Service Name Owner (Last) State
------- ---- ----- ------ -----
service:service_centos01 centos01.local started
service:service_centos02 centos02.local started
service:service_centos03 centos03.local started

Si en un momento dado deseamos conocer el número de nodos asociados al sistema GFS2, podremos ejecutar el siguiente comando:
[root@centos02 ~]# gfs2_tool journals /mnt/gfs2_iscsi/
journal2 - 128MB
journal1 - 128MB
journal0 - 128MB
3 journal(s) found.

18 comments:

  1. Apreciado Javier, enhorabuena por el excelente artículo y por el blog en general. Soy uno de tus lectores anónimos en la sombra y tus publicaciones me han servidor de base para algunos proyectos tanto personales como profesionales.

    Después de este ladrillo de entrada me gustaría abusar de tu experiencia y exponerte una problemática que me ha surgido al intentar reproducir el escenario de almacenamiento compartido GFS2 + iSCSI.

    Te haré una pregunta directa y si estas interesado estaré encantado de explicarte mi configuración:
    Es posible utilizar en la configuración del sistema de fichero del cluster un dispositivo lógico (/dev/mapper/VolGroup02-LogVol00) en lugar de un dispositivo físico? (/dev/sdb) me refiero a esta definición:



    Un cordial saludo.

    ReplyDelete
  2. esta es la entra del fichero de configuración del cluster a la que me refiero:

    clusterfs device="/dev/sdb" force_unmount="1" fsid="45982" fstype="gfs2" mountpoint="/mnt/gfs2_iscsi/" name="resource_gfs2_iscsi" self_fence="0"

    Salu2

    ReplyDelete
  3. Hola Albert,

    pues me temo que no se puede hacer lo que comentas...

    El motivo es que cuando tú importas por iSCSI un target, a efectos del sistema es como si pincharas un nuevo disco duro, por eso el sistema operativo lo añade como una nueva unidad física (sdb, sdc, ...).

    De todos modos, con esta arquitectura las ventajas de los dispositivos lógicos ya la tienes ganada.

    Te pongo un ejemplo: si tú en un momento dado necesitaras aumentar el espacio de ese target, como en centos01 lo creaste como una unidad lógica, lo podrías redimensionar sin ningún problema (eso sí, desconectando previamente el target) y a continuación tendrías en centos02 y centos03 el dispositivo físico (/dev/sdb) ya redimensionado.

    Un saludo,

    ReplyDelete
  4. Grácias por la aclaración Javier, pues es una lástima que no se pueda hacer lo que te comento. Entonces, una desventaja notoria del sistema iSCSI respecto al GNBD p. ej. es que tienes que asegurarte que a los nodos que exportas tengas este recurso físico disponible (hdb, sdb, c0d0, etc...) aunque siempre podemos, teóricamente, renombrar los dispositivos físicos mediante udev, pero en mi caso con controladoras SmartArray (cciss) no es tan viable.
    Un saludo.

    ReplyDelete
  5. No tiene por qué tener el nombre disponible...

    Para que lo entiendas: imagina que en tu PC tienes dos discos duros de tipo SCSI. Linux los nombrará como sda y sdb.

    Si a continuación importas un target iSCSI, Linux lo nombrará como sdc (siguiente nombre libre a sdb).

    Si al cabo de una semana conectas un nuevo disco duro SCSI, Linux lo representará como sdd.

    http://redes-privadas-virtuales.blogspot.com/2009/03/sistema-de-particiones-en-linux_25.html

    En el fichero cluster.conf ("clusterfs device=...") de cada nodo que importa un target, tienes que utilizar el nombre del dispositivo con el que lo representa Linux.

    ReplyDelete
  6. ahhh vale, creo que ahora lo he pillado, me estas diciendo que el fichero cluster.conf de cada unos de los nodos que importa un target puede variar el "clusterfs device" en función del hardware que tenga ese nodo???

    En estos momentos tengo montado un escenario con 4 nodos que acceden a una librería de discos externos que solo esta conectada físicamente al nodo01, mediante GFS2+GNBD. La idea es ubicar ahi las imágenes de las máquinas virtuales que quiero crear para poder "clusterizarlas", mejor utilizar iSCSI en lugar de GNBD? No se si me explico correctamente. O lo que me estoy planteando no tiene demasiada lógica....
    Un cordial saludo

    ReplyDelete
  7. Sí, puede variar el "clusterfs device" en función del hardware.

    En cuanto a rendimiento, GFS2+iSCSI o GFS2+GNBD te van a ir igual de bien.

    Pero ojo con lo que tienes en mente... sólo te va a funcionar correctamente si los enlaces que unen a tu nodo01 con la librería, y al resto de nodos con nodo01, son de fibra óptica.

    Si tienes cables de red convencionales, te va a ir muy muy lento... date cuenta que estás hablando de máquinas virtuales, donde cada una de ellas puede llegar a ocupar muchos gigas...

    El esquema de mi artículo es óptimo por ejemplo para cuando tienes un DocRoot compartido por varios Apaches, una base de datos, etc., es decir, áreas de almacenamiento compartido que tradicionalmente las exportarías por NFS...

    ReplyDelete
  8. Eso es genial Javier, me ha quedado cristalino el tema de la exportación del iSCSI, gracias.

    Respecto a mi configuración comentarte que son servidores Blade en una misma cabina. La librería se conecta al nodo01 por bus interno, deduzco que por PCI-E, lo que no tengo tan claro es como se conectan los otros servidores entre si, lo que es seguro es que no tengo ningún cable ethernet entre ellos. Ya te contaré si da el rendimiento deseado.
    Salu2

    ReplyDelete
  9. Muy buenas Javier, al final modificando el "cluster device" he conseguido montar la librería de discos en todos los nodos. Pero no ha sido tan sencillo, resulta que el switch cisco que lleva la cabina de blades no viene por defecto habilitado el direccionamiento multicast y parece ser que para openais es imprescindible, (https://bugzilla.redhat.com/show_bug.cgi?id=469874)ha si que me ha tocado configurar previamente el switch, me estaba volviendo loco, no poda entender porque no se iniciaban los servicios del cluster.

    Un tema, me gustaría también acceder a la libreria de discos, desde el mismos servidor que la exporta via iscsi, cual seria según tu criterio la mejor forma de acceder a ella sin que interfiera al funcionamiento del resto de los nodos?

    Salu2

    ReplyDelete
  10. Hola,

    pues yo entiendo que para acceder desde el nodo que exporta el espacio de almacenamiento compartido, lo que puedes hacer es montarlo directamente.

    Para el caso de mi artículo haría un:

    # mount /dev/VolGroup01/LogVol00 /data

    Siendo '/data' el punto de montaje.

    No va a haber ningún problema al escribir por parte de centos01, ya que este espacio de almacenamiento tiene un filesystem de tipo GFS2, el cual ya provee los mecanismos de sincronización necesarios para que no se produzcan condiciones de carrera.

    Un saludo,

    ReplyDelete
  11. Buenas, muy bueno tu post, pero tengo un problema, estoy tratando de montar un gfs2 pero el disco lo tengo compartido en SAN para 2 servidores, es decir nodo01 y nodo02 ven el mismo disco, logre configurar el clusterfilesystem con OCFS2, pero quiero probar con la suit de redhat, ahora, el problema que tengo radica en que no he encoontrado un manual que me ayude con la configuracion del man, puesto que howto que sigo no me sirve, siempre tengo problemas para que levante el demonico cman, no tienes un buen manual para cluster en centos que explique un caso similar, es decir, 2 maquinas un disco compartido via SAN y GFS2. mi experiencia con ocfs fue muy buena porque fue muy muy sencilla la configuracion pero con gfs2 me he dado mas de una golpe contra un muro

    ReplyDelete
  12. Hola Ramón,

    prueba a echarle un ojo a la documentación de Red Hat:

    - RHEL 5: http://www.redhat.com/docs/manuals/enterprise/

    - RHEL 6 (beta): http://www.redhat.com/docs/en-US/Red_Hat_Enterprise_Linux/6-Beta/

    Un saludo,

    ReplyDelete
  13. Saludos,

    Tengo un problema, trato de montar un gfs2 en 2 servidores que tienen un disco en la SAN compartido, es decir ambos ven el disco, estoy tratando de configurar desde conga, pero cuando intentas iniciar el cluster se que da asi
    [root@PRUEBA]:/root>/etc/init.d/cman start
    Starting cluster:
    Loading modules... done
    Mounting configfs... done
    Starting ccsd... done
    Starting cman... done
    Starting daemons... done
    Starting fencing...
    y nunca levanta, ni puedes montar el gfs2, que puede ser, porque en elos logs no veo nada

    ReplyDelete
  14. Hola Ramón, yo he tenido problemas similares con el fencing, que fence divice estas usando? en mi caso al ser servidores HP he utilizado ilo. si estas implementando un escenario de pruebas mira de usar un manual fencing. Salu2

    ReplyDelete
  15. HOla Albert, dejame explicartelo asi, tengo los servidores conectados uno mediante una tarjeta emulex a un clarion, y el otro a traves de una qlogic. he leido el man de fenced pero aun no comprendo como configurarlo, puesto que he probado con varios fencedevice, pero aun no logro levantarlo, de hecho el servidor llega a un punto que no puedo ni reiniciarlo haciendo un init 6, debo bajar al data center a resetearlo manualmente, el servidor es un hp dl-580, que me recomiendas o que luces me puedes dar

    ReplyDelete
  16. probe con el manual facing tambien, pero sigue sin levantar y el los logs no veo nada que me indique que puede estar pasando

    ReplyDelete
  17. Hola Ramón,

    para temas de Conga yo ví muy útiles un par de documentos de Thomas Cameron (Red Hat). Te paso los enlaces:

    - http://people.redhat.com/tcameron/Summit2009/clustering/Clustering_Virtual_Machines_and_Applications_with_Red_Hat_Enterprise_Linux.pdf

    - http://people.redhat.com/tcameron/.cluster

    ReplyDelete
  18. Gracias!!, voy a chequear y les cuento como me va.

    ReplyDelete