GlusterFS – Filesystems con Alta Disponibilidad en Linux

Alguna vez os he hablado de ServiceGuard para montar entornos de alta disponibilidad robustos, que monten filesystems y levanten servicios, pero este es un software de pago que no quería utilizar para montar un único filesystem con alta disponibilidad. En su lugar, he elegido GlusterFS, que es opensource y con soporte de RedHat.

¿Para qué vamos utilizar GlusterFS exactamente?

Lo que vamos a hacer a continuación es crear un filesystem con todos sus datos accesibles y sincronizados en tiempo real en tres servidores, lo que significa que si alguno de ellos cae (avería hardware, reinicio, etc.), los datos siguen siendo accesibles a través de otro nodo del cluster.

Instalación de GlusterFS en CentOS 7

En primer lugar, vamos a instalar Gluster en los tres nodos que van a formar el cluster de filesystems. Lo haremos en CentOS 7.

[[email protected] ~]# lsb_release -a
LSB Version:    :core-4.1-amd64:core-4.1-noarch:cxx-4.1-amd64:cxx-4.1-noarch:desktop-4.1-amd64:desktop-4.1-noarch:languages-4.1-amd64:languages-4.1-noarch:printing-4.1-amd64:printing-4.1-noarch
Distributor ID: CentOS
Description:    CentOS Linux release 7.6.1810 (Core)
Release:        7.6.1810
Codename:       Core
[[email protected] ~]#

Los pasos de instalación son muy sencillos:

  • Buscamos el repositorio de la última versión disponible del producto y lo instalamos:
[[email protected] ~]# yum search centos-release-gluster
Loaded plugins: fastestmirror
Loading mirror speeds from cached hostfile
 * base: mirror.sax.uk.as61049.net
 * centosplus: mirror.cwcs.co.uk
 * epel: mirror.team-cymru.com
 * extras: mirror.netweaver.uk
 * updates: mirror.cwcs.co.uk
============================================================================== N/S matched: centos-release-gluster ===============================================================================
centos-release-gluster-legacy.noarch : Disable unmaintained Gluster repositories from the CentOS Storage SIG
centos-release-gluster40.x86_64 : Gluster 4.0 (Short Term Stable) packages from the CentOS Storage SIG repository
centos-release-gluster41.noarch : Gluster 4.1 (Long Term Stable) packages from the CentOS Storage SIG repository
centos-release-gluster5.noarch : Gluster 5 packages from the CentOS Storage SIG repository
centos-release-gluster6.noarch : Gluster 6 packages from the CentOS Storage SIG repository

  Name and summary matches only, use "search all" for everything.
[[email protected] ~]# yum install -y centos-release-gluster6.noarch
  • A continuación, instalamos Gluster con todas sus dependencias:
[[email protected] ~]# yum install -y glusterfs gluster-cli glusterfs-libs glusterfs-server
[[email protected] ~]# rpm -qa |grep -i gluster
glusterfs-6.1-1.el7.x86_64
glusterfs-server-6.1-1.el7.x86_64
glusterfs-api-6.1-1.el7.x86_64
glusterfs-libs-6.1-1.el7.x86_64
glusterfs-cli-6.1-1.el7.x86_64
glusterfs-fuse-6.1-1.el7.x86_64
glusterfs-client-xlators-6.1-1.el7.x86_64
centos-release-gluster6-1.0-1.el7.centos.noarch
[[email protected] ~]#

Repetimos los pasos en los otros dos servidores del cluster.

Habilitamos el servicio de Gluster

Una vez instalado el producto, tenemos que arrancarlo. Ejecutaremos el siguiente comando en los tres servidores CentOS 7 del cluster:

[[email protected] ~]# systemctl enable glusterd.service
Created symlink from /etc/systemd/system/multi-user.target.wants/glusterd.service to /usr/lib/systemd/system/glusterd.service.
[[email protected] ~]#

[[email protected] ~]# systemctl start glusterd.service
[[email protected] ~]# ps -ef |grep -i gluster |grep -v grep
root       6432      1  0 10:50 ?        00:00:00 /usr/sbin/glusterd -p /var/run/glusterd.pid --log-level INFO
[[email protected] ~]#

Asignación de IPs de servicio a cada nodo de GlusterFS

En cada uno de los servidores vamos a asociar una IP distinta de servicio y un nombre. Para ello, configuraremos el fichero /etc/hosts de cada nodo con su IP correspondiente:

[[email protected] ~]# cat /etc/hosts |grep gluster
10.0.0.2 glusterfs1
10.0.0.3 glusterfs2
10.0.0.4 glusterfs3
[[email protected] ~]#

Asignación de un disco a cada nodo

Si leísteis el artículo de ServiceGuard, lo que hacíamos era dar visibilidad de una LUN de la cabina de discos a los tres nodos a la vez.

El concepto de GlusterFS cambia. Lo que haremos aquí será asignar tres discos independientes. Uno para cada nodo y luego sincronizar los datos. Para esta guía, asignamos un disco de 1GB.

[[email protected] ~]# fdisk -l |grep dev |grep -v mapper
Disk /dev/sdb: 1073 MB, 1073741824 bytes, 2097152 sectors
Disk /dev/sda: 10.7 GB, 10737418240 bytes, 20971520 sectors
/dev/sda1   *        2048     2099199     1048576   83  Linux
/dev/sda2         2099200    20971519     9436160   8e  Linux LVM
[[email protected] ~]#

[[email protected] ~]# fdisk -l |grep dev |grep -v mapper
Disk /dev/sdb: 1073 MB, 1073741824 bytes, 2097152 sectors
Disk /dev/sda: 10.7 GB, 10737418240 bytes, 20971520 sectors
/dev/sda1   *        2048     2099199     1048576   83  Linux
/dev/sda2         2099200    20971519     9436160   8e  Linux LVM
[[email protected] ~]#

[[email protected] /]# fdisk -l |grep dev |grep -v mapper
Disk /dev/sdb: 1073 MB, 1073741824 bytes, 2097152 sectors
Disk /dev/sda: 10.7 GB, 10737418240 bytes, 20971520 sectors
/dev/sda1   *        2048     2099199     1048576   83  Linux
/dev/sda2         2099200    20971519     9436160   8e  Linux LVM
[[email protected] /]#

Creación de los filesystems

En cada uno de los nodos, crearemos un filesystem independiente pero con el mismo nombre. En realidad, le puedes poner el nombre que quieras al punto de montaje, pero me gusta ser consistente y darle el mismo nombre a los tres filesystems si son para el mismo servicio.

[[email protected] ~]# grep -i gluster /etc/fstab
/dev/vggluster/lvgluster        /gluster        xfs     defaults        0 0
[[email protected] ~]#

[[email protected] ~]# df -hP /gluster/
Filesystem                       Size  Used Avail Use% Mounted on
/dev/mapper/vggluster-lvgluster 1014M   33M  982M   4% /gluster
[[email protected] ~]#

[[email protected] ~]# grep -i gluster /etc/fstab
/dev/vggluster/lvgluster        /gluster        xfs     defaults        0 0
[[email protected] ~]#

[[email protected] ~]# df -hP /gluster/
Filesystem                       Size  Used Avail Use% Mounted on
/dev/mapper/vggluster-lvgluster 1014M   33M  982M   4% /gluster
[[email protected] ~]#

[[email protected] /]# grep -i gluster /etc/fstab
/dev/vggluster/lvgluster        /gluster        xfs     defaults        0 0
[[email protected] /]#

[[email protected] /]# df -hP /gluster/
Filesystem                       Size  Used Avail Use% Mounted on
/dev/mapper/vggluster-lvgluster 1014M   33M  982M   4% /gluster
[[email protected] /]#

Como véis, hemos creado un filesystem XFS estándar con arquitectura LVM.

Creación del Cluster de Filesystems con GlusterFS

Por fin llegamos al punto interesante, que es la creación del cluster del sistema de archivos con Gluster para replicar los datos entre todos los nodos.

Configuración de los nodos

Lo primero que haremos será configurar el número de nodos del cluster. Así que nos conectamos al servidor1 y ejecutamos el siguiente comando hacia los otros dos nodos del cluster:

[[email protected] ~]# gluster peer probe glusterfs2
peer probe: success.
[[email protected] ~]# gluster peer probe glusterfs3
peer probe: success.
[[email protected] ~]#

Si comprobamos el estado del cluster, veremos que está formado por los tres nodos:

[[email protected] ~]# gluster peer status
Number of Peers: 2

Hostname: glusterfs2
Uuid: c94cb2f7-2784-41ed-8502-065f7855b4e6
State: Peer in Cluster (Connected)

Hostname: glusterfs3
Uuid: ed01e2fa-1cd5-4e8b-9acb-90e331e35560
State: Peer in Cluster (Connected)
[[email protected] ~]#

En caso de que queramos eliminiar alguno de los nodos, utilizaremos el comando gluster detach servidor3.

Configuración de la réplica de datos entre los diferentes filesystems

Primer intento fallido

[[email protected] ~]# gluster volume create glustervol1 replica 3 arbiter 1 transport tcp glusterfs1:/gluster glusterfs2:/gluster glusterfs3:/gluster
volume create: glustervol1: failed: The brick glusterfs1:/gluster is a mount point. Please create a sub-directory under the mount point and use that as the brick directory. Or use 'force' at the end of the command if you want to override this behavior.
[[email protected] ~]#

Lo que nos está diciendo este error es que Gluster necesita guardar sus metadatos en un subdirectorio y no en un punto de montaje.

Segundo intento OK

Creamos el subdirectorio “brick”, tal y como dice el error y lo volvemos a intentar.

[[email protected] ~]# gluster volume create glustervol1 replica 3 arbiter 1 transport tcp glusterfs1:/gluster/brick glusterfs2:/gluster/brick glusterfs3:/gluster/brick
volume create: glustervol1: success: please start the volume to access data
[[email protected] ~]#

[[email protected] ~]# gluster volume start glustervol1
volume start: glustervol1: success
[[email protected] ~]#

Comprobamos el estado del volumen de gluster que acabamos de crear

[[email protected] ~]# gluster volume info

Volume Name: glustervol1
Type: Replicate
Volume ID: 7a5f6b90-5dab-4d3a-b686-023aedd38bf3
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x (2 + 1) = 3
Transport-type: tcp
Bricks:
Brick1: glusterfs1:/gluster/brick
Brick2: glusterfs2:/gluster/brick
Brick3: glusterfs3:/gluster/brick (arbiter)
Options Reconfigured:
transport.address-family: inet
nfs.disable: on
performance.client-io-threads: off
[[email protected] ~]#

[[email protected] ~]# gluster volume status glustervol1
Status of volume: glustervol1
Gluster process                             TCP Port  RDMA Port  Online  Pid
------------------------------------------------------------------------------
Brick glusterfs1:/glustersrv/brick         49152     0          Y       5593
Brick glusterfs2:/glustersrv/brick         49152     0          Y       5284
Brick glusterfs3:/glustersrv/brick         49152     0          Y       5368
Self-heal Daemon on localhost               N/A       N/A        Y       5604
Self-heal Daemon on glusterfs3             N/A       N/A        Y       5422
Self-heal Daemon on glusterfs2             N/A       N/A        Y       5343

Task Status of Volume glustervol1
------------------------------------------------------------------------------
There are no active volume tasks

[[email protected] ~]#

[[email protected] ~]# gluster pool list
UUID                                    Hostname        State
062d4a7e-bd66-45ad-a11c-c0f5f796b4d6    glusterfs2     Connected
0187b96f-f6f8-4e8b-9e9f-4a7583b57005    glusterfs3     Connected
0386eef3-268d-4bb6-8c4f-8388a990b3ce    localhost       Connected
[[email protected]er1 ~]#

Montaje de los filesystems

Ahora ya tenemos configurada la réplica entre filesystems pero todavía no los hemos montado como «cluster de Gluster». Lo haremos así:

[[email protected] ~]# mount -t glusterfs glusterfs1:/glustervol1 /gluster_client
[[email protected] ~]# df -hP /gluster_client/
Filesystem               Size  Used Avail Use% Mounted on
glusterfs1:/glustervol1 1014M   43M  972M   5% /gluster_client
[[email protected] ~]#

El fichero /etc/fstab de cada nodo lo he configurado así:

[[email protected] ~]# grep gluster_client /etc/fstab
glusterfs1:/glustervol1         /gluster_client glusterfs       defaults        0 0
[[email protected] ~]#

[[email protected] ~]# grep gluster_client /etc/fstab
glusterfs2:/glustervol1         /gluster_client glusterfs       defaults        0 0
[[email protected] ~]#

[[email protected] /]# grep gluster_client /etc/fstab
glusterfs3:/glustervol1         /gluster_client glusterfs       defaults        0 0
[[email protected] /]#

Los filesystems no montan tras el reboot del servidor

Durante las pruebas, me he dado cuenta de que los filesystems no siempre montan tras rebotar los servidores. Seguramente, el servicio de gluster todavía no se ha levantado y la entrada del fstab falla.

La solución pasa por crear un servicio que se encargue de montar los filesystems cuando el servicio de gluster ya esté arrancado:

  • Creamos el fichero de configuración del servicio:
[[email protected] ~]# cat /etc/systemd/system/glusterfsmounts.service
[Unit]
Description=Glustermounting
Requires=glusterfs-server.service

[Service]
Type=simple
RemainAfterExit=true
ExecStartPre=/usr/sbin/gluster volume list
ExecStart=/bin/mount -a -t glusterfs
Restart=on-failure
RestartSec=3

[Install]
WantedBy=multi-user.target
[[email protected] ~]#

[[email protected] ~]# systemctl daemon-reload
[[email protected] ~]# systemctl enable glusterfsmounts
Created symlink from /etc/systemd/system/multi-user.target.wants/glusterfsmounts.service to /etc/systemd/system/glusterfsmounts.service.
[[email protected] ~]#
  • Rebotamos el servidor

Veremos que, tras el reboot, los filesystems de tipo gluster siempre montan correctamente.

Pruebas de réplica de datos

Ya hemos montado el cluster. Ahora vamos a comprobar que los datos se replican correctamente, así que voy a escribir un fichero en uno de los servidores y voy a comprobar que puedo verlo en el resto:

[[email protected] gluster_client]# touch kk
[[email protected] gluster_client]# ll
total 0
-rw-r--r-- 1 root root 0 May 29 12:09 kk
[[email protected] gluster_client]#

Y el fichero «kK» sí existe en los otros nodos:

[[email protected] gluster_client]# ll
total 0
-rw-r--r-- 1 root root 0 May 29 12:09 kk
[[email protected] gluster_client]#

[[email protected] gluster_client]# ll
total 0
-rw-r--r-- 1 root root 0 May 29 12:09 kk
[[email protected] gluster_client]#

Lo mismo ocurre si escribimos otro archivo desde cualquiera de los otros servidores:

[[email protected] gluster_client]# echo "david" >> david.txt
[[email protected] gluster_client]# ll
total 1
-rw-r--r-- 1 root root 6 May 29 12:11 david.txt
-rw-r--r-- 1 root root 0 May 29 12:09 kk
[[email protected] gluster_client]#

[[email protected] gluster_client]# ll
total 1
-rw-r--r-- 1 root root 6 May 29 12:11 david.txt
-rw-r--r-- 1 root root 0 May 29 12:09 kk
[[email protected] gluster_client]#

[[email protected] gluster_client]# ll
total 1
-rw-r--r-- 1 root root 6 May 29 12:11 david.txt
-rw-r--r-- 1 root root 0 May 29 12:09 kk
[[email protected] gluster_client]#

Ampliación de un filesystem GlusterFS

Como he montado la estructura con LVM, la ampliación se realiza, exactamente igual que en cualquier otro FS con estructura LVM. Veamos un ejemplo:

[[email protected] ~]# pvresize /dev/xvdb
  Physical volume "/dev/xvdb" changed
  1 physical volume(s) resized or updated / 0 physical volume(s) not resized
[[email protected] ~]#
[[email protected] ~]# xfs_growfs  /dev/vggluster/lvgluster
meta-data=/dev/mapper/vggluster-lvgluster isize=512    agcount=4, agsize=65280 b                                                                                                                     lks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0 spinodes=0
data     =                       bsize=4096   blocks=261120, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal               bsize=4096   blocks=855, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
data blocks changed from 261120 to 2620416
[[email protected] ~]#
[[email protected] ~]# df -hP /glusterclient/
Filesystem               Size  Used Avail Use% Mounted on
glustercl1:/glustervol1   10G  137M  9.9G   2% /glusterclient
[[email protected] ~]#

¿Y si quiero ampliar el filesytem añadiendo un nuevo Brick?

Otra manera de ampliar un filesystem de GlusterFS es añadiendo un nuevo Brick a un volumen existente.

Así que crearemos un nuevo filesystem en los tres servidores del cluster, que lo llamaremos glustersrv2 y luego lo añadiremos al volumen glustervol1.

[[email protected] ~]# df -hP /glustersrv2
Filesystem                        Size  Used Avail Use% Mounted on
/dev/mapper/vggluster-lvgluster2 1017M   33M  985M   4% /glustersrv2
[[email protected] ~]#

[[email protected] ~]# gluster volume add-brick glustervol1 replica 3 arbiter 1  glustercl1:/glustersrv2/brick glustercl2:/glustersrv2/brick glustercl3:/glustersrv2/brick
volume add-brick: success
[[email protected] ~]#

[[email protected] ~]# gluster volume info

Volume Name: glustervol1
Type: Distributed-Replicate
Volume ID: 8d51c4b2-f53b-403d-baa8-2d3d4ae1af00
Status: Started
Snapshot Count: 0
Number of Bricks: 2 x (2 + 1) = 6
Transport-type: tcp
Bricks:
Brick1: glustercl1:/glustersrv/brick
Brick2: glustercl2:/glustersrv/brick
Brick3: glustercl3:/glustersrv/brick (arbiter)
Brick4: glustercl1:/glustersrv2/brick
Brick5: glustercl2:/glustersrv2/brick
Brick6: glustercl3:/glustersrv2/brick (arbiter)
Options Reconfigured:
nfs.rpc-auth-allow: *
performance.client-io-threads: off
nfs.disable: off
transport.address-family: inet
[[email protected] ~]#

Una vez añadido el nuevo FS al cluster de Gluster, también vemos que ha aumentado el tamaño del FS. En este caso, en 1GB más:

[[email protected] ~]# df -hP /glusterclient/
Filesystem               Size  Used Avail Use% Mounted on
glustercl1:/glustervol1   11G  1.2G  9.9G  11% /glusterclient
[[email protected] ~]#

Ampliar un cluster de GlusterFS de 3 nodos a 5

Tal y como podemos observar en la siguiente consulta de estado del cluster de GlusterFS, tenemos tres nodos activos:

[[email protected] glusterfs]# gluster volume info

Volume Name: glustervol1
Type: Replicate
Volume ID: e490a217-237a-42d7-8c9b-ecd3cb9b569f
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x (2 + 1) = 3
Transport-type: tcp
Bricks:
Brick1: lsltsat2:/glustersrv/brick01
Brick2: lsltsat3:/glustersrv/brick01
Brick3: lsltsax4:/glustersrv/brick01 (arbiter)
Options Reconfigured:
changelog.capture-del-path: on
changelog.changelog: on
storage.build-pgfid: on
features.scrub: Active
features.bitrot: on
features.trash: on
transport.address-family: inet
storage.fips-mode-rchecksum: on
nfs.disable: on
performance.client-io-threads: off
[[email protected] glusterfs]#

Lo que queremos ahora es ampliar el cluster de tres nodos a cinco, con réplica de datos.

Primer intento fallido

Intentamos añadir el cuarto nodo pero hay un conflicto con el parámetro «arbiter», tal y como podemos ver a continuación.

[[email protected] glusterfs]# gluster volume add-brick glustervol1 replica 4 lsltsax5:/glustersrv/brick01
volume add-brick: failed: Increasing replica count for arbiter volumes is not supported.
[[email protected] glusterfs]#

Ocurre lo mismo si intento añadir los dos nuevos nodos a la vez.

Solución

Lo que he hecho ha sido eliminar el «brick» arbiter y añadir los tres nodos (el eliminado y los dos nuevos). Veamos cómo se hace:

[[email protected] glusterfs]# gluster volume remove-brick glustervol1 replica 2 lsltsax4:/glustersrv/brick01 force
Remove-brick force will not migrate files from the removed bricks, so they will no longer be available on the volume.
Do you want to continue? (y/n) y
volume remove-brick commit force: success
[[email protected] glusterfs]#

[[email protected] glusterfs]# gluster volume info

Volume Name: glustervol1
Type: Replicate
Volume ID: e490a217-237a-42d7-8c9b-ecd3cb9b569f
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x 2 = 2
Transport-type: tcp
Bricks:
Brick1: lsltsat2:/glustersrv/brick01
Brick2: lsltsat3:/glustersrv/brick01
Options Reconfigured:
changelog.capture-del-path: on
changelog.changelog: on
storage.build-pgfid: on
features.scrub: Active
features.bitrot: on
features.trash: on
transport.address-family: inet
storage.fips-mode-rchecksum: on
nfs.disable: on
performance.client-io-threads: off
[[email protected] glusterfs]#

[[email protected] ~]# gluster volume add-brick glustervol1 replica 5 lsltsax4:/glustersrv/brick01 lsltsax5:/glustersrv/brick01 lsltsax6:/glustersrv/brick01 force
volume add-brick: success
[[email protected] ~]#


[[email protected] ~]# gluster volume status
Status of volume: glustervol1
Gluster process                             TCP Port  RDMA Port  Online  Pid
------------------------------------------------------------------------------
Brick lsltsat2:/glustersrv/brick01          49152     0          Y       7435
Brick lsltsat3:/glustersrv/brick01          49152     0          Y       71566
Brick lsltsax4:/glustersrv/brick01          49152     0          Y       50642
Brick lsltsax5:/glustersrv/brick01          49152     0          Y       11948
Brick lsltsax6:/glustersrv/brick01          49152     0          Y       19600
Self-heal Daemon on localhost               N/A       N/A        Y       50670
Bitrot Daemon on localhost                  N/A       N/A        Y       50682
Scrubber Daemon on localhost                N/A       N/A        Y       50694
Self-heal Daemon on lsltsax6                N/A       N/A        Y       20172
Bitrot Daemon on lsltsax6                   N/A       N/A        Y       20384
Scrubber Daemon on lsltsax6                 N/A       N/A        Y       20775
Self-heal Daemon on lsltsax5                N/A       N/A        Y       11978
Bitrot Daemon on lsltsax5                   N/A       N/A        Y       12047
Scrubber Daemon on lsltsax5                 N/A       N/A        Y       12058
Self-heal Daemon on lsltsat3                N/A       N/A        Y       851406
Bitrot Daemon on lsltsat3                   N/A       N/A        Y       851472
Scrubber Daemon on lsltsat3                 N/A       N/A        Y       851511
Self-heal Daemon on lsltsat2.8798.1286.ecs.
hp.com                                      N/A       N/A        Y       41308
Bitrot Daemon on lsltsat2.8798.1286.ecs.hp.
com                                         N/A       N/A        Y       41375
Scrubber Daemon on lsltsat2.8798.1286.ecs.h
p.com                                       N/A       N/A        Y       41410

Task Status of Volume glustervol1
------------------------------------------------------------------------------
There are no active volume tasks

[[email protected] ~]#

¿Puedo crear un cluster con nodos impares?

Si quisiera crear un cluster de cinco nodos, por ejemplo, también es posible. Veamos un ejemplo:

[[email protected] ~]# gluster volume create glustervol1 replica 5 transport tcp gluster1:/gluster/brick gluster2:/gluster/brick gluster3:/gluster/brick gluster4:/gluster/brick gluster5:/gluster/brick
volume create: glustervol1: success: please start the volume to access data
[[email protected] ~]#

[[email protected] ~]# gluster volume info

Volume Name: glustervol1
Type: Replicate
Volume ID: fe0ae11b-cb98-43d5-ad0a-8e396dd4bce8
Status: Created
Snapshot Count: 0
Number of Bricks: 1 x 5 = 5
Transport-type: tcp
Bricks:
Brick1: gluster1:/gluster/brick
Brick2: gluster2:/gluster/brick
Brick3: gluster3:/gluster/brick
Brick4: gluster4:/gluster/brick
Brick5: gluster5:/gluster/brick
Options Reconfigured:
transport.address-family: inet
nfs.disable: on
performance.client-io-threads: off
[[email protected] ~]# gluster volume start glustervol1
volume start: glustervol1: success
[[email protected] ~]#

[[email protected] gluster_client]# ls -la
total 1
drwxr-xr-x   3 root root  41 Jun 17 11:09 .
dr-xr-xr-x. 19 root root 261 Jun 17 11:08 ..
-rw-r--r--   1 root root   6 Jun 17 11:09 david.txt
[[email protected] gluster_client]#

[[email protected] gluster_client]# ll
total 1
-rw-r--r-- 1 root root 6 Jun 17 11:09 david.txt
[[email protected] gluster_client]#

Reemplazar un disco del cluster de Gluster

Si hemos tenido una avería hardware en un disco o estamos migrando de cabina de discos, nos interesará reemplazar un disco de gluster por uno nuevo. En el siguiente ejemplo, vamos a sustituir el «brick» glustercl1:/glustersrv2/brick por el glustercl1:/glustersrv3/brick.

Primero de todo, consultamos el estado del cluster:

[[email protected] ~]# gluster volume status glustervol1
Status of volume: glustervol1
Gluster process                             TCP Port  RDMA Port  Online  Pid
------------------------------------------------------------------------------
Brick glustercl1:/glustersrv/brick          49152     0          Y       4198
Brick glustercl2:/glustersrv/brick          49152     0          Y       4286
Brick glustercl3:/glustersrv/brick          49152     0          Y       3970
Brick glustercl1:/glustersrv2/brick         49153     0          Y       4211
Brick glustercl2:/glustersrv2/brick         49153     0          Y       4296
Brick glustercl3:/glustersrv2/brick         49153     0          Y       3980
NFS Server on localhost                     N/A       N/A        N       N/A
Self-heal Daemon on localhost               N/A       N/A        Y       4222
NFS Server on glustercl2                    N/A       N/A        N       N/A
Self-heal Daemon on glustercl2              N/A       N/A        Y       4307
NFS Server on glustercl3                    N/A       N/A        N       N/A
Self-heal Daemon on glustercl3              N/A       N/A        Y       3991

Task Status of Volume glustervol1
------------------------------------------------------------------------------
There are no active volume tasks

[[email protected] ~]#

Añadimos un disco nuevo (/dev/xvdg) con la estructura de gluster:

Añado un disco nuevo, el xvdg:

[[email protected] ~]# fdisk -l |grep dev |grep -v mapper
Disk /dev/xvda: 8589 MB, 8589934592 bytes, 16777216 sectors
/dev/xvda1   *        2048    16777215     8387584   83  Linux
Disk /dev/xvdf: 1073 MB, 1073741824 bytes, 2097152 sectors
Disk /dev/xvdb: 10.7 GB, 10737418240 bytes, 20971520 sectors
Disk /dev/xvdg: 1073 MB, 1073741824 bytes, 2097152 sectors
[[email protected] ~]#


[[email protected] ~]# mkfs.xfs /dev/xvdg
meta-data=/dev/xvdg              isize=512    agcount=4, agsize=65536 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=0, sparse=0
data     =                       bsize=4096   blocks=262144, imaxpct=25
         =                       sunit=0      swidth=0 blks
naming   =version 2              bsize=4096   ascii-ci=0 ftype=1
log      =internal log           bsize=4096   blocks=2560, version=2
         =                       sectsz=512   sunit=0 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
[[email protected] ~]#


[[email protected] ~]# df -hP /glustersrv3
Filesystem      Size  Used Avail Use% Mounted on
/dev/xvdg      1014M   33M  982M   4% /glustersrv3
[[email protected] ~]#


[[email protected] ~]# mkdir /glustersrv3/brick

Y reemplazamos el disco o brick:

[[email protected] ~]# gluster volume replace-brick glustervol1 glustercl1:/glustersrv2/brick glustercl1:/glustersrv3/brick commit force
volume replace-brick: success: replace-brick commit force operation successful
[[email protected] ~]#

[[email protected] ~]# gluster volume info

Volume Name: glustervol1
Type: Distributed-Replicate
Volume ID: 8d51c4b2-f53b-403d-baa8-2d3d4ae1af00
Status: Started
Snapshot Count: 0
Number of Bricks: 2 x (2 + 1) = 6
Transport-type: tcp
Bricks:
Brick1: glustercl1:/glustersrv/brick
Brick2: glustercl2:/glustersrv/brick
Brick3: glustercl3:/glustersrv/brick (arbiter)
Brick4: glustercl1:/glustersrv3/brick
Brick5: glustercl2:/glustersrv2/brick
Brick6: glustercl3:/glustersrv2/brick (arbiter)
Options Reconfigured:
nfs.rpc-auth-allow: *
performance.client-io-threads: off
nfs.disable: off
transport.address-family: inet
[[email protected] ~]#

¿Qué ocurre si se cae el servidor de quorum (arbiter)?

Los otros clientes que tienen montado el filesystem de gluster se quedan «congelados» durante unos segundos. Luego, ya vuelven a responder y la réplica de datos funciona con normalidad.

No obstante, esto podría ser un problema para alguna aplicación, ya que el sistema operativo le podría devolver un error de acceso al sistema de archivos mientras éste no está respondiendo, si los timeouts y reintentos de acceso al filesystem no están configurados con el suficiente tiempo.

En este ejemplo, he apagado el servidor árbitro y un simple «ll» no responde.

GlusterFS - Comando ll no responde tras apagar el servidor de Quorum (arbiter)

Para añadir un nuevo servidor de quorum, tendríamos que añadir tres servidores nuevos al cluster de gluster, ya que la configuración es 3 a 1 (3 réplicas y un árbitro).

# gluster volume create testvol replica 3 arbiter 1 \
server1:/bricks/brick server2:/bricks/brick server3:/bricks/arbiter_brick \
server4:/bricks/brick server5:/bricks/brick server6:/bricks/arbiter_brick

# gluster volume info testvol
Volume Name: testvol
Type: Distributed-Replicate
Volume ID: ed9fa4d5-37f1-49bb-83c3-925e90fab1bc
Status: Created
Snapshot Count: 0
Number of Bricks: 2 x (2 + 1) = 6
Transport-type: tcp
Bricks:
Brick1: server1:/bricks/brick
Brick2: server2:/bricks/brick
Brick3: server3:/bricks/arbiter_brick (arbiter)
Brick1: server4:/bricks/brick
Brick2: server5:/bricks/brick
Brick3: server6:/bricks/arbiter_brick (arbiter)
Options Reconfigured:
transport.address-family: inet
performance.readdir-ahead: on
nfs.disable: on

No es posible hacer un 3 a 2, por ejemplo, ni ninguna otra configuración:

[[email protected] ~]# gluster volume add-brick glustervol1 replica 3 arbiter 2 glustercl4:/glustersrv
For arbiter configuration, replica count must be 3 and arbiter count must be 1. The 3rd brick of the replica will be the arbiter

Usage:
volume add-brick <VOLNAME> [<stripe|replica> <COUNT> [arbiter <COUNT>]] <NEW-BRICK> ... [force]

[[email protected] ~]#


[[email protected] ~]# gluster volume add-brick glustervol1 replica 4  glustercl4:/glustersrv
volume add-brick: failed: Increasing replica count for arbiter volumes is not supported.
[[email protected] ~]#

Eliminar un nodo del cluster de Gluster

Si queremos dar de baja uno de los nodos del cluster de GlusterFS, utilizaremos el siguiente comando:

[[email protected] ~]# gluster peer detach glustercl4
All clients mounted through the peer which is getting detached need to be remounted using one of the other active peers in the trusted storage pool to ensure client gets notification on any changes done on the gluster configuration and if the same has been done do you want to proceed? (y/n) y
peer detach: success
[[email protected] ~]#

Exportar por NFS un filesystem de GlusterFS

Lo que vamos a hacer a continuación es exportar por NFS el volumen de Gluster glustervol1.

Instalación del servidor NFS Ganesha en el servidor de Gluster

En el servidor de Gluster, tendremos que instalar el software Ganesha-NFS para exportar por NFS un volumen de Gluster, ya que no utiliza el servicio tradicional de NFS (está obsoleto). Lo haremos de la siguiente manera:

[[email protected] ~]# yum install -y nfs-ganesha nfs-ganesha-gluster
[[email protected] ~]# systemctl start nfs-ganesha
[[email protected] ~]# systemctl enable nfs-ganesha
Created symlink from /etc/systemd/system/multi-user.target.wants/nfs-ganesha.service to /usr/lib/systemd/system/nfs-ganesha.service.
[[email protected] ~]#

Configuración del filesystem NFS a exportar

Editaremos el fichero de configuración /etc/ganesha/ganesha.conf para indicar qué volumen de Gluster queremos exportar. Para ello, añadiremos las siguientes líneas:

EXPORT{
Export_Id = 1;
Path = «/glustervol1»;
FSAL {
name = GLUSTER;
hostname=»localhost»;
volume=»glustervol1″;
}
Access_type = RW;
Disable_ACL = true;
Squash=»No_root_squash»;
Pseudo=»/glustervol1″;
Protocols = «3», «4» ;
Transports = «UDP»,»TCP»;
SecType = «sys»;
}

Si quisiéramos exportar otro filesystem, añadiríamos una nueva sección «EXPORT».

Reiniciamos Ganesha y comprobamos que se está exportando por NFS el volumen de GlusterFS indicado:

[[email protected] ~]# systemctl reload nfs-ganesha

[[email protected] ~]# showmount -e localhost
Export list for localhost:
/glustervol1 (everyone)
[[email protected] ~]#

Configurar el servicio de Gluster para permitir exportar volúmenes por NFS

Primero habilitamos NFS:

[[email protected] ~]# gluster volume set glustervol1  nfs.disable off
Gluster NFS is being deprecated in favor of NFS-Ganesha Enter "yes" to continue using Gluster NFS (y/n) y
volume set: success
[[email protected] ~]#

Y luego permitimos las IPs que se podrán conectar al servicio:

[[email protected] ~]# gluster volume set glustervol1 nfs.rpc-auth-allow glustercl1,glustercl2,glustercl3,glustercl4
volume set: success
[[email protected] ~]#

Para permitir a todas las IPs, ejecutar el comando:

gluster volume set glustervol1 nfs.rpc-auth-allow "*"

[[email protected] ~]# service glusterd restart
Redirecting to /bin/systemctl restart glusterd.service
[[email protected] ~]#


[[email protected] ~]# gluster volume info

Volume Name: glustervol1
Type: Replicate
Volume ID: 8d51c4b2-f53b-403d-baa8-2d3d4ae1af00
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x (2 + 1) = 3
Transport-type: tcp
Bricks:
Brick1: glustercl1:/glustersrv/brick
Brick2: glustercl2:/glustersrv/brick
Brick3: glustercl3:/glustersrv/brick (arbiter)
Options Reconfigured:
transport.address-family: inet
nfs.disable: off
performance.client-io-threads: off
nfs.rpc-auth-allow: glustercl1,glustercl2,glustercl3,glustercl4
[[email protected] ~]#

Montar el filesystem de Gluster por NFS desde el cliente NFS

En cliente tendremos que instalar el paquete nfs-utils:

yum install -y nfs-utils

Y luego montar el volumen de Gluster como si de cualquier otro cualquier filesystem NFS se tratara:

[[email protected] ~]# mount -t nfs glustercl1:/glustervol1 /glusternfs
[[email protected] ~]# df -hP /glusternfs/
Filesystem               Size  Used Avail Use% Mounted on
glustercl1:/glustervol1   10G  1.2G  8.9G  12% /glusternfs
[[email protected] ~]#

Control de concurrencia de datos

GlusterFS no tiene ningún control sobre la concurrencia de datos. Es decir, podemos escribir de manera simultánea en el mismo fichero desde cualquiera de los nodos del cluster, algo que podría causa corrupción de datos.

No obstante, este comportamiento es normal. También ocurre con NFS o si, accidentalmente, compartimos el mismo FS de LVM en varios nodos al mismo tiempo.

El control de la concurrencia de datos se debe dar por parte de la lógica de la aplicación que utilice el filesystem. Por ejemplo, las bases de datos Oracle incorporan controles de este tipo.

Para demostrarlo, hice varias pruebas:

Edición del mismo fichero con vi y con echo

  • Creo el fichero david.txt
  • Desde el nodo lsltsat3, lo abro con el “vi”.
  • Desde el nodo lsltsat2 modifico el fichero con “echo “Prueba 2” >> david.txt
[[email protected] gluster_client_test]# cat david.txt
Prueba David
Prueba 2
[[email protected] gluster_client_test]#
  • Veo que el fichero queda modificado.
  • Desde el nodo lsltsat3, con el vi todavía abierto, intento grabarlo pero el propio vi me avisa conque el fichero ha sido modificado:
"david.txt"
WARNING: The file has been changed since reading it!!!
Do you reallywant to write to it (y/n)?

En este caso, el “vi” tiene su “inteligencia” para detectar esto, pero no estoy seguro de si esta casuística podría causar algún problema de corrupción de datos que no contemplen estas comprobaciones.

Escritura con dd

  • Desde el nodo lsltsat2 escribo un fichero de 1GB con el comando dd (dd if=/dev/zero of=prueba_borrar01.txt bs=8192 count=131072)
  • Un segundo después, en lsltsat3, escribo un fichero de 2GB con el mismo nombre (dd if=/dev/zero of=prueba_borrar01.txt bs=8192 count=262144)
  • El resultado es que el fichero que queda escrito es el de 2GB (acaba más tarde). Ambos comandos están escribiendo al mismo tiempo en el mismo fichero.

Por lo tanto, podría existir un problema de corrupción de datos si una aplicación escribe al mismo tiempo en el mismo fichero desde dos nodos diferentes.

Prueba con fopen

Otra prueba que quería hacer para corroborarlo, es escribir en un fichero abierto:

  • Abro un fichero durante 40 segundos:
[[email protected] gluster_client_test]# cat fopen.py
import time

tf = 'prueba_borrar01.txt'
f = open(tf)
time.sleep(40)
[[email protected] gluster_client_test]#
  • Mientras el fichero está abierto, escribo un fichero de 2GB con el mismo nombre con el comando dd
  • Finaliza el dd a los 12 segundos.
  • Un poco más tarde finaliza el script del fopen.
  • Resultado: Queda escrito el fichero de 2GB.

Por lo tanto, de nuevo, se demuestra que no hay control de concurrencia de datos.

Activar la papelera de reciclaje

Si queremos recuperar archivos que hemos borrado en un filesystem de Gluster, podremos activar la papelera de reciclaje para el volumen de Gluster que nos interese. Esto creará un subdirectorio «trash» que nos permitirá recuperar los archivos eliminados.

  • Activación de la papelera de reciclaje:

Podemos apreciar que aparece la directiva features.trash: on.

[[email protected] ~]# gluster volume set glustervol1 features.trash on
volume set: success
[[email protected] ~]#


[[email protected] ~]# gluster volume info

Volume Name: glustervol1
Type: Replicate
Volume ID: e490a217-237a-42d7-8c9b-ecd3cb9b569f
Status: Started
Snapshot Count: 0
Number of Bricks: 1 x (2 + 1) = 3
Transport-type: tcp
Bricks:
Brick1: lsltsat2:/glustersrv/brick01
Brick2: lsltsat3:/glustersrv/brick01
Brick3: lsltsax4:/glustersrv/brick01 (arbiter)
Options Reconfigured:
features.trash: on
performance.client-io-threads: off
nfs.disable: on
storage.fips-mode-rchecksum: on
transport.address-family: inet
[[email protected] ~]#
  • Creamos un archivo de prueba:
[[email protected] gluster_client_test]# echo "david" > david.txt
[[email protected] gluster_client_test]# ll
total 1
-rw-r--r-- 1 root root 6 Nov 21 16:37 david.txt
[[email protected] gluster_client_test]#
  • Eliminamos el archivo:
[[email protected] gluster_client_test]# rm david.txt
[[email protected] gluster_client_test]# ll
total 0
[[email protected] gluster_client_test]#
  • Comprobamos que se ha guardado una copia en la papelera de reciclaje:
[[email protected] gluster_client_test]# cd .trashcan/
[[email protected] .trashcan]# ll
total 1
-rw-r--r-- 1 root root 6 Nov 21 16:37 david.txt_2019-11-21_153809
[[email protected] .trashcan]#

RedHat Gluster Storage – Instalación de la versión empresarial de GlusterFS

RedHat Gluster Storage es la implementación de GlusterFS para los entornos profesionales con soporte de RedHat. El procedimiento de instalación es diferente a como lo hemos hecho en CentOS pero, igualmente, es muy sencillo.

Lo primero que necesitamos es una cuenta en RedHat para podernos descargar el producto, gratuitamente. Obviamente, si pagas por el soporte del producto, podrás acceder al repositorio directamente sin tener que descargarte la ISO.

Nosotros hemos instalado RedHat Gluster Storage 3.5.

Descargar RedHat Gluster Storage

Una vez descargado el archivo ISO, creamos el repositorio que nos servirá para instalar el producto:

  • Montamos el fichero ISO
[[email protected] RedHat_Gluster_Storage]# mkdir iso
[[email protected] RedHat_Gluster_Storage]# mount -o loop rhgs-3.5-rhel-7-x86_64-dvd-1.iso iso
mount: /dev/loop0 is write-protected, mounting read-only
[[email protected] RedHat_Gluster_Storage]#
  • Copiamos el contenido en un directorio con permisos de escritura
[[email protected] RedHat_Gluster_Storage]# cp -pr iso RHGS35
[[email protected] RedHat_Gluster_Storage]# umount iso
  • Creamos el repositorio de RedHat Gluster Storage y comprobamos su funcionamiento
[[email protected] RedHat_Gluster_Storage]# createrepo -g /RedHat_Gluster_Storage/RHGS35/repodata/repomd.xml /RedHat_Gluster_Storage/RHGS35/Packages
Spawning worker 0 with 1168 pkgs
Workers Finished
Saving Primary metadata
Saving file lists metadata
Saving other metadata
Generating sqlite DBs
Sqlite DBs complete
[[email protected] RedHat_Gluster_Storage]#

[[email protected] RedHat_Gluster_Storage]# cat /etc/yum.repos.d/gluster.repo
[RHGS35]
name=RedHat Gluster Storage 3.5
baseurl="file:///RedHat_Gluster_Storage/RHGS35/"
enabled=1
gpgcheck=0
[[email protected] RedHat_Gluster_Storage]#

[[email protected] RedHat_Gluster_Storage]# yum repolist
Loaded plugins: amazon-id, search-disabled-repos
repo id                                                                         repo name                                                                                                      status
RHGS35                                                                          RedHat Gluster Storage 3.5                                                                                      1,168
rhui-client-config-server-7/x86_64                                              Custom Repositories - Red Hat Update Infrastructure 3 Client Configuration Server 7                                 3
rhui-rhel-7-server-rhui-rh-common-rpms/7Server/x86_64                           Red Hat Enterprise Linux 7 Server - RH Common from RHUI (RPMs)                                                    239
rhui-rhel-7-server-rhui-rpms/7Server/x86_64                                     Red Hat Enterprise Linux 7 Server from RHUI (RPMs)                                                             26,530
repolist: 27,940
[[email protected] RedHat_Gluster_Storage]#

[[email protected] RedHat_Gluster_Storage]# yum grouplist
Loaded plugins: amazon-id, search-disabled-repos
There is no installed groups file.
Maybe run: yum groups mark convert (see man yum)
Available Environment Groups:
   Default Install
   Minimal Install
   Infrastructure Server
   File and Print Server
   Basic Web Server
   Virtualization Host
   Server with GUI
Available Groups:
   Compatibility Libraries
   Console Internet Tools
   Development Tools
   Graphical Administration Tools
   Legacy UNIX Compatibility
   RH-Gluster-AD-Integration
   RH-Gluster-NFS-Ganesha
   RH-Gluster-Samba-Server
   Scientific Support
   Security Tools
   Smart Card Support
   System Administration Tools
   System Management
Done
[[email protected] RedHat_Gluster_Storage]#

Una vez creado el repositorio, ya estamos preparados para instalarlo. Para ello, hemos seguido la guía de instalación oficial de RedHat Gluster Storage. Los comandos que hemos ejecutado han sido:

yum install redhat-storage-server
yum groupinstall RH-Gluster-Samba-Server
yum groupinstall RH-Gluster-AD-Integration
reboot

Una vez que ha arrancado el servidor tras el reinicio, habilitamos el servicio de GlusterFS:

[[email protected] ~]# systemctl enable glusterd
[[email protected] ~]# systemctl start glusterd
[[email protected] ~]# systemctl status glusterd
● glusterd.service - GlusterFS, a clustered file-system server
   Loaded: loaded (/usr/lib/systemd/system/glusterd.service; enabled; vendor preset: disabled)
   Active: active (running) since Wed 2019-11-13 08:32:10 UTC; 1min 38s ago
     Docs: man:glusterd(8)
 Main PID: 1286 (glusterd)
   CGroup: /system.slice/glusterd.service
           └─1286 /usr/sbin/glusterd -p /var/run/glusterd.pid --log-level INFO

Nov 13 08:32:07 ip-10-0-1-58.eu-west-1.compute.internal systemd[1]: Starting GlusterFS, a clustered file-system server...
Nov 13 08:32:10 ip-10-0-1-58.eu-west-1.compute.internal systemd[1]: Started GlusterFS, a clustered file-system server.
[[email protected] ~]#

El resto de pasos, son iguales a como los hicimos anteriormente en CentOS.

¿Te ha gustado? ¡Compártelo!

Share on facebook
Share on twitter
Share on linkedin
Share on whatsapp
Share on telegram
Share on email

Deja un comentario

Tal vez también te gustaría leer...

Corrompiendo un filesystem ext4 a propósito

He tenido la necesidad de corromper un filesystem ext4 en un RedHat 6 a propósito para realizar un test de chequeo de filesystem. En mi caso, el filesystem era el /dev/sdb. Para corromperlo, he utilizado el siguiente comando: Rebajas Lenovo S145-15IWL – Ordenador portátil 15.6″… 549,99 EUR Comprar en Amazon Rebajas HP 15s-fq1013ns – Ordenador

Leer más »

Tutorial de Ansible

Recientemente me he estado mirando el funcionamiento de Ansible para automatizar tareas de manera masiva en servidores Linux remotos mediante esta aplicación. Hasta ahora utilizo otra pero como Ansible está cada vez más extendida y considero que vale la pena mirárselo. Más aún si RedHat está apostando por esta herramienta como estándar de automatización. Su

Leer más »

RHEL y Oracle RAC – Paquetes Dropped

En un entorno de dos servidores Linux RedHat 6.9 con un cluster de Oracle RAC, hemos detectado muchos paquetes dropped en las tarjetas de red (dropped: 311815750): El equipo de Oracle ejecuta un análisis del sistema (OSWatcher) donde se indica que debemos aumentar el valor de MTU de todos los nodos del cluster, y así

Leer más »

lun4194304 has a LUN larger than allowed by the host adapter

En un RedHat 7.6 he pedido una LUN para ampliar un filesystem. Esta es una tarea rutinaria de cualquier técnico de sistemas Linux, si embargo, hoy me he encontrado con que la LUN estaba asignada al servidor pero no la veía. En el log del sistema operativo (/var/log/messages) aparecía el siguiente mensaje: Es decir, que

Leer más »

Conexiones seguras con SSH

SSH es un protocolo de comunicaciones que proporciona seguridad criptográfica cuando nos conectamos a un servidor para iniciar una sesión o transfereir archivos por SFTP o SCP. Los comandos SSH, SFTP y SCP utilizan el mismo puerto de comunicaciones, que es el 22. Teclado Mecánico Gaming de VicTsing, 104 Teclas y… 39,88 EUR Comprar en

Leer más »

root: fork failed: Cannot allocate memory

En uno de los servidores que administro me ha ocurrido que no podía entrar con SSH ni ejecutar procesos en remoto a través de un software que tiene un agente instalado, etc. dando el error root: fork failed: Cannot allocate memory. Sin embargo, la aplicación del usuario no se estaba viendo afectada. Toshiba Canvio Basics

Leer más »