By

Compartiendo ficheros con GlusterFS

Cuando aparece la necesidad de escalar una aplicación web, o cualquier otro servicio, en Internet; también aparecen nuevos problemas a resolver que antes incluso ni habíamos reparado en ellos. Uno de estos problemas es la compartición de ficheros entre servidores.

En mi opinión, a día de hoy éste sigue siendo un dolor de cabeza para muchos Sysadmins o Systems Architects. Hay muchas formas de compartir ficheros entre servidores como NFS, S3FS, FileConveyor, un crontab con un rsync entre servidores. Hay muchas soluciones, algunas mejores y otras peores; pero hoy quería compartir la que hasta ahora creo que puede ser una buena solución para compartir ficheros, usando GlusterFS.

GlusterFS es un sistema de ficheros escalable en red, con el que poder crear soluciones de almacenamiento distribuidos por la red y de gran capacidad. Ni que decir tiene que GlusterFS es software libre.

Antes de empezar

Normalmente en los despliegues que hacemos en AWS en Crononauta, siempre utilizamos un mínimo de un par de instancias EC2 para el sistema de almacenamiento en red con GlusterFS. Además, a cada una de estas dos instancias EC2, hacemos attach de un disco EBS donde almacenaremos los ficheros en el clúster de ficheros en red. Esto nos permite tener redundancia en los datos, alta disponibilidad y escalabilidad horizontal en el servicio. Con lo cual, tendremos un par de instancias que mantienen en clúster de almacenamiento actuando como GlusterFS Server y por otro lado, tendremos los clientes de GlusterFS que montarán este volumen compartido por la red.

Como detalle, en Crononauta siempre usamos Debian como distribución, en este caso contamos con una Debian 8 (Jessie), aunque es totalmente aplicable a cualquier distribución basada en Debian como Ubuntu y/o derivadas.

Una vez tenemos esto, podemos empezar a trabajar… ;-)

Particionando los discos

Utilizaremos XFS como sistema de ficheros para el volumen compartido en red. Por lo que necesitaremos instalar las utilidades para trabajar con XFS, si no las tenemos ya instaladas.

apt-get install xfsprogs

El siguiente paso será crear una partición en el volumen, en mi caso es /dev/xvdf. Usaremos fdisk para ello:

fdisk /dev/xvdf

y una vez en la shell interactiva de fdisk, teclearemos:

  1. n para crear una nueva partición. No necesitamos especificar nada más, así que los siguientes datos que pide podemos usar los valores por defecto que ofrece fdisk, asi que pulsaremos Intro hasta finalizar. Una vez hecho esto, seguiremos dentro de la shell interactiva de fdisk, y habremos creado una partición primaria que ocupa todo el espacio del volumen.
  2. w indicando que queremos escribir esta definición de partición en el disco y hacerla efectiva.

Ya tenemos la partición en el volumen, así que ahora la formatearemos y la añadiremos a nuestro /etc/fstab para montarla en cada arranque del sistema. Seguiremos los siguientes pasos:

mkfs.xfs -i size=512 /dev/xvdf1
mkdir -p /export/brick1
echo "/dev/xvdf1 /export/brick1 xfs defaults 1 2"  >> /etc/fstab
mount -a && mount

Instalando GlusterFS

Ya tenemos el volumen preparado para GlusterFS, ahora instalaremos el servicio.

apt-get update
apt-get install glusterfs-server glusterfs-client glusterfs-common

Importante realizar este paso en aquellas instancias / servidores que vayan a actuar como un GlusterFS Server.

Lo siguiente que haremos será configurar nuestro fichero /etc/hosts para definir unos nombres DNS para nuestros GlusterFS Servers. También es posible hacerlo con un DNS interno. Si vuestros servidores, como en el caso de AWS EC2, contáis con IPs privadas, mejor usar esas. Si no, podéis usar las IPs pública.

Definiremos algo como lo siguiente en /etc/hosts:

xxx.xxx.xxx.xxx    gfs01.example.com
xxx.xxx.xxx.xxx    gfs02.example.com

Un anillo para gobernarlos a todos

Ya tenemos GlusterFS preparado para ser configurado. Ahora tendremos que configurar el anillo de confianza entre ambos servidores GlusterFS Server. Para ello serán necesarios los siguientes pasos:

  1. Desde gfs01.example.com:

    gluster peer probe gfs02.example.com
    
  2. Desde gfs02.example.com:

    gluster peer probe gfs01.example.com
    

Es muy importante que haya conectividad entre ambos servidores, en caso contrario, los comandos anteriores fallarán. Si estás en AWS, asegúrate de tener bien configurado el Security Group para ambas instancias de storage.

Si todo ha ido bien, tendremos el pool de confianza funcionando, así que lo siguiente será definir el volumen compartido. Usaremos la siguiente instrucción desde uno de los servidores GlusterFS:

gluster volume create gv0 replica 2 gfs01.example.com:/export/brick1/<volume-name> gfs02.example.com:/export/brick1/<volumen-name»

Por último, iniciaremos el volumen que justo acabamos de crear:

gluster volume start gv0

Como detalle, podemos ver información sobre el volumen con la siguiente instrucción:

gluster volume info

Llegados a este punto, el cluster de almacenamiento debe estar totalmente operativo. Si queremos hacer una prueba, es posible crear el punto de montaje hacia el volumen compartido y probar si se replican correctamente los ficheros. Crearemos el punto de montaje en gfs01.example.com de la siguiente forma:

mount -t glusterfs localhost:/gv0 /mnt

Ahora crearemos ficheros para comprobar si el funcionamiento de GlusterFS es correcto. Con la siguiente instrucción crearemos diez ficheros vacíos en el punto de montaje previamente creado:

touch /mnt/test-file{1..10}.txt

Si GlusterFS funciona correctamente, debemos poder ver estos mismos ficheros en gfs02.example.com en el directorio /export/brick1/<volume-name>.

Configurando los clientes

Nos falta muy poco para terminar, ya sólo nos falta configurar los clientes de GlusterFS. Necesitaremos tener instalado el cliente de GlusterFS glusterfs-client si no lo tenemos instalado.

apt-get install glusterfs-client

Hecho esto, podremos probar a montar el volumen compartido por la red, y si todo va bien debemos ver los ficheros de prueba creados previamente.

mount -t glusterfs gfs01.example.com:/gv0 /mnt

Por último, necesitaremos un script /etc/init.d/glusterfs-mount que se encargue de montar el volumen compartido. En mi caso suelo utilizar el siguiente script:

#! /bin/bash
### BEGIN INIT INFO
# Provides:          glusterfs-mount
# Required-Start:    $remote_fs $syslog
# Required-Stop:     $remote_fs $syslog
# Default-Start:     2 3 4 5 
# Default-Stop:      0 1 6 
# Short-Description: Start daemon at boot time
# Description:       Enable service provided by daemon.
### END INIT INFO
#

MOUNTPOINT="/var/www/shared"
GLUSTERFS_SERVER="gfs01.example.com"
GLUSTERFS_VOLUME="gv0"

# Some things that run always at boot
mount -t glusterfs $GLUSTERFS_SERVER:/$GLUSTERFS_VOLUME $MOUNTPOINT
#
# Uncomment this line if you need to start Apache after mount glusterFS volume
# service apache2 start
#
# Carry out specific functions when asked to by the system
case "$1" in
  start)
    echo "Mounting glusterfs volumes "
    mount -t glusterfs $GLUSTERFS_SERVER:/$GLUSTERFS_VOLUME $MOUNTPOINT
    ;;
  stop)
    echo "Unmount glusterfs volumes"
    umount $MOUNTPOINT
    ;;
  *)
    echo "Usage: /etc/init.d/glusterfs-mount {start|stop}"
    exit 1
    ;;
esac
exit 0

Ya solo nos queda dar permisos de ejecución a nuestro script y configurarlo para que se ejecute durante el inicio del sistema:

chmod +x /etc/init.d/glusterfs-mount
update-rc.d glusterfs-mount defaults

FAQ

  • Q: No puedo crear el anillo de confianza. Los comandos gluster peer probe terminan fallando con un timeout ¿Qué ocurre?

  • A: Es muy probable que sea un problema de conectividad entre ambos GlusterFS Servers. Revisa si hay algún firewall entre ellos que pueda estar bloqueando conexiones TCP y UDP entre ellos. Puedes ver los puertos abiertos con netstat -ntlp.

Si estás en AWS, asegúrate que el Security Group que usan ambas instancias tienen permitidos los accesos a puerto TCP y UDP entre ellos.

  • Q: No puedo montar el volumen compartido desde las instancias que actuan como clientes. El comando mount responde con mount failed. ¿Qué puede estar ocurriendo?

  • A: Al igual que con los servidores GlusterFS, revisa que las instancias clientes tienen conectividad con los servidores. GlusterFS suele abrir un rango de puertos para cada volumen exportado (gv0, gv1, gv2, etc). Es recomendable permitir todo el tráfico TCP y UDP entre las instancias clientes y servidor. De otra forma es probable que alguna vez tengamos problemas al montar los volumenes.

  • Q: Sigo sin poder crear el punto de montaje desde las instancias clientes. El comando mount indica que hubo un problema. La conectividad entre cliente y servidor de GlusterFS es correcta ¿Qué problema puede haber?

  • A: Es muy común que las versiones de las distribuciones entre cliente y servidor difieran. Si esto es así, es muy probable que la versión de glusterfs-client difiera de la versión de glusterfs-server. En este caso, es muy probable que no podamos montar el volumen compartido con el driver glusterfs.

GlusterFS permite montar los volumenes con el driver de NFS. En este tipo de situaciones es normal recurrir al driver de NFS para crear el punto de montaje. Para ello se necesita tener instalado nfs-common y crear el punto de montaje con la siguiente instrucción:

mount -t nfs gfs01.example.com:/gv0 /var/www/shared
  • Q: ¿Por qué crear un script en /etc/init.d pudiendo configurar el montaje en el fichero /etc/fstab?

  • A: Sí, es posible configurar el punto de montaje en /etc/fstab, pero a diferencia del resto de punto de montajes, en este caso se trata de un volumen compartido por la red. Es muy probable que cuando se monten los volumenes de /etc/fstab, aún no esté disponible la red en el sistema, con lo cual el montaje no solo fallará, sino que además es posible que ralentize el arranque del sistema hasta que el intento de montar el volumen por la red de un Timeout. Por eso es más fiable hacerlo con un script en init.d, una vez la red ya esté disponible.

Creo que esto es todo. ¿Encontráis algún otro problema? ¡Dejadlo en los comentarios! Saludos.

:wq