Saltar al contenido principal

GlusterFS

Introducción

Los contenedores están orientados a ser desplegados en unos u otros nodos del clúster, si un contenedor requiere almacenar información en el disco perderá los datos.

Esto no es una novedad, pasa en todos los clústeres, así que la solución también existe desde hace tiempo. En la mayoría de los casos, esto se soluciona con carpetas compartidas o con discos conectados a todos los nodos, también tenemos la variante gratuita: crear una RAID en software.

RAID software

GlusterFS es un servicio que permite desplegar una RAID en software y ser montada como una carpeta compartida, ya sea en el mismo servidor u otro.

Es muy similar a una RAID, permite crear sistemas distribuidos, donde se requiere que todos los nodos estén activos para tener acceso a los datos (RAID0), o replicas donde todos los datos se duplican en cada nodo (RAID1), solo con uno será suficiente para acceder a todos los datos.

En este caso, se utilizará la versión de réplica, este requiere tener al menos 3 nodos para crear los volúmenes. Cada nodo del clúster será también un nodo de GlusterFS, lo que permite evitar transferencias de datos por la red, todo estará accesible en local, y únicamente se transferirá datos cuando GlusterFS tenga que hacer sus sincronizaciones, lo que evitará sobrecarga en lectura.

Este sistema tiene dos grandes problemas:

  • Todos los datos están replicados en cada nodo, así que, asignando 200 GiB a cada nodo, únicamente tenemos disponible esos 200 GiB, no se suman entre ellos (igual que pasa en una RAID1, espejo).
  • GlusterFS se encarga de la sincronización entre nodos, y aunque es bueno haciendo su trabajo, tiene problemas con procesos que modifican gran cantidad de datos en poco tiempo (como una base de datos), no debería usarse con servicios así.

Como añadido, GlusterFS puede ser desplegado con sincronización cifrada.

tip

GlusterFS es un servicio monstruoso, en este artículo solo detallo su uso simple para lo que se necesita para este proyecto, pero tiene más servicios para arreglar volúmenes, gestión de instantáneas o incluso geolocalización.

Carpetas compartidas

Además de GlusterFS, tenemos la opción de compartir una carpeta por NFS desde otro servidor (un NAS o similar), este se encargará de aquellos que no sean buena opción para GlusterFS.

important

Si no tenemos un NAS o un servidor que se pueda encargar del NFS, podemos desplegar un servidor de NFS en uno de los nodos, si es el caso, habrá que añadirle un tercer disco para almacenar los datos.

Ventajas:

  • Todos los nodos se conectan a este servidor, ya que los datos no se replican, no se desperdicia espacio, lo que es ideal para contenedores que disponen de datos muy grandes, como gestores documentales o repositorios.

Desventajas:

  • Sin importar que sea lectura o escritura, debe ser leído a través de la red, lo que limitará la velocidad.
  • Si el servidor de NFS cae, todos los contenedores que lo utilizan serán bloqueados. Esto es realmente malo, no es que los contenedores se caigan o devuelvan errores, si no que quedan bloqueados y los servicios se quedan en espera de poder reconectar, así que incluso los sistemas que vigilan estos pueden creer que simplemente va lento, cuando en realidad no funciona. Incluso si nuestro sistema detecta que el servicio ha caído e intenta reiniciarlo, no servirá de nada y entrará en un bucle de despliegues hasta que el NFS vuelva a funcionar.
  • La comunicación de NFS no está cifrada, únicamente algunas de las últimas versiones lo permiten.

Igual que GlusterFS, si disponemos de servicios que requieren modificar muchos datos en poco tiempo, es posible que NFS no sea una buena opción por el rendimiento de la red y del servidor.

Carpetas no compartidas

Si ninguna de las opciones anteriores nos sirve, entonces tenemos un truco: prefijar el nodo donde se desplegará el contenedor que nos está ocasionando los problemas.

Esto significa que el contenedor siempre se desplegará en el mismo nodo, así que siempre tendrá acceso al mismo volumen, también significa que, si ese nodo cae, este contenedor no podrá ser desplegado.

En caso de necesitar utilizar esta opción, es preferible crear un nuevo disco para ello en ese nodo. Si vamos a tener muchos servicios así, cada uno debería ir prefijado en un nodo diferente para balancear la carga.

Instalación

important

Todos los comandos requieren permisos de root, así que los comandos se ejecutarán como root, por ello no tienen el sudo. Estos pasos se deben replicar en todos los nodos.

El segundo disco que dejamos de lado en la instalación es el que utilizará GlusterFS, es hora de crear la partición.

parted /dev/sdb mklabel msdos
parted -a opt /dev/sdb mkpart primary xfs 0% 100%
mkfs.xfs /dev/sdb1 -i size=512 -L gfsdisk

Creamos una carpeta y montamos el disco en ella, los datos se almacenan en esa carpeta, pero nunca accederemos directamente a ella, siempre accederemos desde las carpetas compartidas que crearemos para cada volumen.

Si modificamos los datos de esta carpeta, podríamos bloquear el sincronizador de GlusterFS y provocar una pérdida de datos.

mkdir -p /gluster/bricks
echo "/dev/sdb1 /gluster/bricks xfs defaults 0 0" >> /etc/fstab
mount -a

Con la partición preparada, instalamos el servicio.

apt -y install glusterfs-server
systemctl enable --now glusterd

En uno de los nodos, añadimos al resto y comprobamos que estén todos.

gluster peer probe swarm2.domain.intranet
gluster peer probe swarm3.domain.intranet
gluster pool list

GlusterFS para clientes

En caso de que tengamos otros nodos que no queramos que sean servidores u otros servidores que requieran acceso a estas carpetas compartidas, instalaremos únicamente el cliente.

sudo apt -y install glusterfs-client

Sincronización cifrada

Para cada servicio crearemos un volumen diferente de GlusterFS, en cada uno de ellos podemos decidir si irá cifrado o no, así que es conveniente preparar el entorno para aceptar cifrado.

Como recomendación, yo suelo cifrar todas las conexiones, la pérdida de rendimiento no suele notarse y nos evitamos un posible problema.

Para cada nodo y cliente tenemos que generar un certificado.

cd /etc/ssl/
openssl genrsa -out glusterfs.key 4096
openssl req -new -x509 -key glusterfs.key -subj "/CN=swarm1.domain.intranet" -days 3650 -out glusterfs.pem
important

Cada certificado debe tener el nombre de DNS igual al que utilizamos para incluirlos en el pool.

Vamos a reunir todos los certificados en un servidor para generar el fichero final.

mkdir /tmp/ca
cd /tmp/ca

En esta carpeta copiamos el resto de los certificados, ya sean de servidor o de clientes.

cp /etc/ssl/glusterfs.pem gfs_swarm1.pem
scp [email protected]:/etc/ssl/glusterfs.pem gfs_swarm2.pem
scp [email protected]:/etc/ssl/glusterfs.pem gfs_swarm3.pem
scp [email protected]:/etc/ssl/glusterfs.pem gfs_client.pem

Para los servidores, tendremos que generar un fichero que contendrá el certificado de todos (servidores y clientes), y para los clientes otro certificado con únicamente los servidores (si no tenemos clientes, este lo podemos descartar).

cat gfs_swarm1.pem gfs_swarm2.pem gfs_swarm3.pem gfs_client.pem > glusterfs.ca
cat gfs_swarm1.pem gfs_swarm2.pem gfs_swarm3.pem > glusterfs-client.ca

Copiamos los nuevos ficheros al resto de servidores.

scp glusterfs.ca [email protected]:/home/user
scp glusterfs.ca [email protected]:/home/user
scp glusterfs-client.ca [email protected]:/home/user

En los nodos de GlusterFS, copiamos el fichero al lugar de destino, generamos el fichero de seguridad y reiniciamos el servicio.

sudo mv /home/user/glusterfs.ca /etc/ssl
sudo chown root:root /etc/ssl/glusterfs.ca
sudo touch /var/lib/glusterd/secure-access
sudo systemctl restart glusterd
caution

El servidor donde hemos generado los ficheros tiene el certificado en /tmp/ca no en la 'home' del usuario, además sería conveniente borrar esta carpeta.

En los clientes, copiamos el fichero al destino y generamos el fichero de seguridad.

sudo mv /home/user/glusterfs-client.ca /etc/ssl/glusterfs.ca
sudo chown root:root /etc/ssl/glusterfs.ca
sudo mkdir -p /var/lib/glusterd
sudo touch /var/lib/glusterd/secure-access

Volúmenes

important

Esta sección explica cómo crear volúmenes, los comandos son un ejemplo de cómo crearlo acorde a todas las opciones que podemos tener, para cada servicio tendremos que adaptar el nombre del volumen y la configuración según qué nodos y clientes tenemos.

Las carpetas sincronizadas de GlusterFS se dividen en volúmenes, cada uno es un servicio totalmente diferente al resto, tiene su propia sincronización, configuración y carpeta raíz, debido a ello, por cada servicio de Swarm que requiera de volúmenes, crearemos un nuevo volumen de GlusterFS para él.

Si un servicio contiene diferentes contenedores que requieren de esto, y creemos que la carga de todos ellos puede ser demasiado grande, podemos dividirlos en diferentes volúmenes.

warning

Es una terrible idea crear un único volumen y dentro crear una carpeta por cada servicio o contenedor, ya que, si este volumen colapsara o su sincronización fallara por alguna razón, todos los servicios quedarían comprometidos, aunque tener más volúmenes requiere de más memoria (ya que hay más sincronizadores), es preferible.

En cada nodo debemos crear la carpeta de destino

sudo mkdir /gluster/bricks/volumeName

Una vez está creada, desde uno de los nodos la inicializamos.

sudo gluster volume create volumeName replica 3 \
swarm1.domain.intranet:/gluster/bricks/volumeName \
swarm2.domain.intranet:/gluster/bricks/volumeName \
swarm3.domain.intranet:/gluster/bricks/volumeName

Con esto le hemos dicho a GlusterFS que inicie una réplica de hasta en 3 nodos, hemos indicado cuales son esos 3 nodos y la carpeta de destino. Las carpetas de destino pueden ser diferentes para cada nodo (aunque después a ver quién es el que entiende dónde va cada cosa) y podemos tener más nodos donde no se sincronice, sino que se distribuya (similar a una RAID5).

También es posible disponer de más nodos añadidos al pool y utilizar unos para unos volúmenes y otros para otros (aunque igual que las carpetas, a ver quién gestiona todo eso después).

Si queremos encriptar este volumen, debemos hacerlo antes de iniciar el volumen. Si encriptamos tanto en servidor como en cliente, deberemos añadir la lista de todos ellos.

sudo gluster volume set volumeName auth.ssl-allow 'swarm1.domain.intranet,swarm2.domain.intranet,swarm3.domain.intranet,client.domain.intranet'
sudo gluster volume set volumeName client.ssl on
sudo gluster volume set volumeName server.ssl on

Con la configuración terminada, iniciamos el volumen.

sudo gluster volume start volumeName

Montar unidad en servidor

Los servidores montarán únicamente la unidad local, no requieren conectarse a otros ya que, en teoría, su GlusterFS únicamente estará caído cuando todo el servidor lo esté.

sudo mkdir /mnt/volumeName
echo "localhost:volumeName /mnt/volumeName glusterfs _netdev" | sudo tee -a /etc/fstab
sudo mount -a

Montar unidad en cliente

Los clientes deben tener la lista de todos los servidores, de esta forma, si el servidor principal se cae, reconectará con cualquiera de los otros. El servicio seguirá intentando conectar al principal hasta que lo consiga.

tip

Debido a que el cliente siempre intentará conectarse al servidor principal, en caso de tener muchos clientes, debería alternarse quién será su principal para no sobrecargar el mismo servidor.

sudo mkdir /mnt/volumeName
echo "swarm1.domain.intranet:volumeName /mnt/volumeName glusterfs _netdev,backup-volfile-servers=swarm2.domain.intranet:swarm3.domain.intranet 0 0" | sudo tee -a /etc/fstab
sudo mount -a