Réplica activa-pasiva de filesystems con DRBD en Linux CentOS

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

Hace poco os hablaba de Gluster para crear filesystems con alta disponibilidad en un cluster activo-activo. Sin embargo, hoy os voy a hablar de DRBD para crear un cluster de filesystems activo-pasivo, muy útil para levantar servicios sólo en el nodo del cluster correspondiente.

Tutorial de GlusterFS

Como siempre, voy a utilizar un Linux CentOS 7 para documentar esta prueba. Vamos allá.

Réplica de datos activa-pasiva con DRBD

Definición de los hosts que van a formar el cluster

En el fichero /etc/hosts de cada nodo voy a definir los hostnames e IPs de cada nodo que va a formar parte del cluster.

[[email protected] ~]# cat /etc/hosts |grep server
10.0.0.2 server1
10.0.0.3 server2
[[email protected] ~]#

Instalación de DRBD

Ejecutaremos los siguientes comandos en todos los nodos del cluster para instalar DRBD:

rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org
rpm -Uvh http://www.elrepo.org/elrepo-release-7.0-3.el7.elrepo.noarch.rpm
yum install -y kmod-drbd84 drbd84-utils

Configuración de DRBD

Antes de nada, vamos a hacernos una copia de seguridad del fichero de configuración original:

mv /etc/drbd.d/global_common.conf /etc/drbd.d/global_common.conf.orig

Definimos el protocolo de sincronización de datos en ambos nodos del cluster:

[[email protected] ~]# cat /etc/drbd.d/global_common.conf
global {
 usage-count  yes;
 cmd-timeout-medium 121;
}
common {
 net {
  protocol C;
 }
}
[[email protected] ~]#
  • Protocolo A: Sincronización asíncrona.
  • Protocolo B: Replicación semi-síncrona o en memoria. Tan pronto se ha realizado la escritura en el disco local se considera finalizada la replicación. El paquete TCP de escritura se almacena en memoria para ser sincronizado cuanto antes al nodo secundario.
  • Protocolo C: Es la más utilizada por los nodos de los clusters que están a mucha distancia.

A continuación, definimos los filesystems que se van a sincronizar. Lo que se llama, sincronización de recursos:

[[email protected] ~]# cat /etc/drbd.d/drbtest.res
resource drbtest {
        on server1 {
                device /dev/drbd0;
                disk /dev/sdc;
                        meta-disk internal;
                        address 10.0.0.2:7789;
        }
        on server2  {
                device /dev/drbd0;
                        disk /dev/sdc;
                        meta-disk internal;
                        address 10.0.0.3:7789;
        }
}
[[email protected] ~]#

«server1» es el hostname exacto. No sirve poner un alias.

Este fichero lo creamos en ambos nodos.

Creación del metadispositivo

En ambos nodos ejecutaremos el siguiente comando para crear el metadispositivo que se va a sincronizar:

[[email protected] ~]# drbdadm create-md drbtest
initializing activity log
initializing bitmap (64 KB) to all zero
Writing meta data...
New drbd meta data block successfully created.
[[email protected] ~]#

[[email protected] ~]# drbdadm create-md drbtest
initializing activity log
initializing bitmap (64 KB) to all zero
Writing meta data...
New drbd meta data block successfully created.
[[email protected] ~]#

[[email protected] ~]# drbdadm up drbtest
[[email protected] ~]# 

[[email protected] ~]# drbdadm status drbtest
server1 role:Secondary
  disk:Inconsistent
  peer role:Secondary
    replication:Established peer-disk:Inconsistent

A continuación, forzamos el nodo primario (la primera vez):

Tarda un ratito en sincronizar:

[[email protected] ~]# drbdadm primary --force drbtest
[[email protected] ~]# drbdadm status drbtest
server1 role:Primary
  disk:UpToDate
  peer role:Secondary
    replication:Established peer-disk:UpToDate

[[email protected] ~]#

Creamos el filesystem sólo en el nodo primario, ya que en el secundario se sincroniza la operación:

[[email protected] ~]# mkfs.xfs /dev/drbd0
meta-data=/dev/drbd0             isize=512    agcount=4, agsize=131066 blks
         =                       sectsz=4096  attr=2, projid32bit=1
         =                       crc=1        finobt=0, sparse=0
data     =                       bsize=4096   blocks=524263, 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=4096  sunit=1 blks, lazy-count=1
realtime =none                   extsz=4096   blocks=0, rtextents=0
[[email protected] ~]#

Probando la réplica de datos

En el nodo primario vamos a montar el filesystem y escribir un dato:

[[email protected] ~]# mkdir /drbdtest
[[email protected] ~]# mount /dev/drbd0 /drbdtest/
[[email protected] ~]# df -hP /drbdtest/
Filesystem      Size  Used Avail Use% Mounted on
/dev/drbd0      2.0G   33M  2.0G   2% /drbdtest
[[email protected] ~]#


[[email protected] ~]# echo "test" > /drbdtest/test.txt
[[email protected] ~]# ll /drbdtest/
total 4
-rw-r--r-- 1 root root 5 Jun 14 20:07 test.txt
[[email protected] ~]#

Ahora vamos a desmontar el filesystem en el nodo primario y vamos a levantarlo en el secundario:

[[email protected] ~]# umount /drbdtest/
[[email protected] ~]# drbdadm secondary drbtest

[[email protected] ~]# drbdadm primary drbtest
[[email protected] ~]# mkdir /drbdtest
[[email protected] ~]#  mount /dev/drbd0 /drbdtest/
[[email protected] ~]# ll /drbdtest/
total 4
-rw-r--r-- 1 root root 5 Jun 14 20:07 test.txt
[[email protected] ~]#

Como podemos observar, en el nodo secundario también vemos el fichero que hemos creado desde el primer nodo.

Protección de corrupción de datos por duplicidad de montaje del filesystem

Obviamente, en el nodo secundario no es posible montar el filesystem. Sólo se puede hacer en el primario:

[[email protected] ~]# drbdadm status mysql01
mysql01 role:Secondary
  disk:UpToDate
  peer role:Primary
    replication:Established peer-disk:UpToDate

[[email protected] ~]# mount /dev/drbd0 /drbdtest/
mount: /dev/drbd0 is write-protected, mounting read-only
mount: mount /dev/drbd0 on /drbdtest failed: Wrong medium type
[[email protected] ~]#

Desconectar un nodo del cluster

Si por alguna razón queremos desconectar un nodo del cluster, por ejemplo, por sustitución de un disco, lo haremos de la siguiente manera:

[[email protected] ~]# drbdadm disconnect drbtest
[[email protected] ~]# drbdadm status drbtest
drbtest role:Primary
  disk:UpToDate

[[email protected] ~]# drbdadm connect drbtest
[[email protected] ~]# drbdadm status drbtest
drbtest role:Primary
  disk:UpToDate
  peer role:Secondary
    replication:Established peer-disk:UpToDate

[[email protected] ~]#

Al volverlo a conectar, se queda como nodo secundario. El otro nodo se convierte en primario:

[[email protected] ~]#  drbdadm status drbtest
drbtest role:Secondary
  disk:UpToDate
  peer role:Primary
    replication:Established peer-disk:UpToDate

[[email protected] ~]#

Renombrar un recurso de DRBD

En este ejemplo vamos a renombrar el recurso de DRBD «mysql» a «mysql01».

Lo primero que hacemos es parar el recurso desde todos los nodos del cluster:

[[email protected] drbd.d]# umount /drbdtest/
[[email protected] drbd.d]# drbdadm status mysql
mysql role:Primary
  disk:UpToDate
  peer role:Secondary
    replication:Established peer-disk:UpToDate

[[email protected] drbd.d]#

[[email protected] drbd.d]# drbdadm down mysql
[[email protected] drbd.d]#

Seguidamente, renombramos el fichero del recurso y el nombre que contiene dentro. En ambos casos, a «mysql01».

[[email protected] drbd.d]# mv mysql.res mysql01.res
[[email protected] drbd.d]# cat mysql01.res
resource mysql01 {
        on server1 {
                device /dev/drbd0;
                disk /dev/sdc;
                        meta-disk internal;
                        address 10.0.0.2:7789;
        }
        on server2  {
                device /dev/drbd0;
                        disk /dev/sdc;
                        meta-disk internal;
                        address 10.0.0.3:7789;
        }
}
[[email protected] drbd.d]#

Hacemos lo mismo en todos los nodos.

Por último, levantamos el recurso de DRBD, ya con el nuevo nombre:

[[email protected] drbd.d]# drbdadm up mysql01
[[email protected] drbd.d]# drbdadm status mysql01
mysql01 role:Secondary
  disk:UpToDate
  peer connection:Connecting

[[email protected] drbd.d]# drbdadm status mysql01
mysql01 role:Secondary
  disk:UpToDate
  peer role:Secondary
    replication:Established peer-disk:UpToDate

[[email protected] drbd.d]# drbdadm primary mysql01
[[email protected] drbd.d]# mount /dev/drbd0 /drbdtest/
[[email protected] drbd.d]# df -hP /drbdtest/
Filesystem      Size  Used Avail Use% Mounted on
/dev/drbd0     1018M   33M  986M   4% /drbdtest
[[email protected] drbd.d]#

Sustitución de un disco estropeado

En el caso de avería hardware de un disco, tendremos que sustituirlo por uno nuevo. En este ejemplo, vamos a sustituir el disco «sdc» por el «sdd» en el nodo «server2».

Lo primero que hacemos es desactivar el recurso:

[[email protected] drbd.d]# drbdadm detach mysql01
[[email protected] drbd.d]# drbdadm status mysql01
mysql01 role:Secondary
  disk:Diskless

[[email protected] drbd.d]#

Modificamos el fichero de configuración del recurso, configurando el disco sdd:

[[email protected] drbd.d]# cat mysql01.res
resource mysql01 {
        on server1 {
                device /dev/drbd0;
                disk /dev/sdc;
                        meta-disk internal;
                        address 10.0.0.2:7789;
        }
        on server2  {
                device /dev/drbd0;
                        disk /dev/sdd;
                        meta-disk internal;
                        address 10.0.0.3:7789;
        }
}
[[email protected] drbd.d]#

El fichero lo copiamos a todos los nodos del cluster.

Recreamos el metadispositivo DRBD, de nuevo:

[[email protected] drbd.d]# drbdadm create-md mysql01
initializing activity log
initializing bitmap (64 KB) to all zero
Writing meta data...
New drbd meta data block successfully created.
[[email protected] drbd.d]#

[[email protected] drbd.d]# drbdadm status mysql01
mysql01 role:Secondary
  disk:Inconsistent
  peer role:Primary
    replication:SyncTarget peer-disk:UpToDate done:14.48

[[email protected] drbd.d]#

Esperamos un poco a que se termine de sincronizar (va por el 14,48%).

[[email protected] drbd.d]# drbdadm status mysql01
mysql01 role:Secondary
  disk:UpToDate
  peer role:Primary
    replication:Established peer-disk:UpToDate

[[email protected] drbd.d]#

Reboot del nodo primario

Si el nodo primario cae, tendremos que configurar manualmente quién hace de nodo primario:

[[email protected] ~]# drbdadm status mysql01
mysql01 role:Primary
  disk:UpToDate
  peer role:Secondary
    replication:Established peer-disk:UpToDate

[[email protected] ~]# reboot

[[email protected] ~]# drbdadm primary mysql01
[[email protected] ~]# drbdadm status mysql01
mysql01 role:Primary
  disk:UpToDate
  peer connection:Connecting

[[email protected] ~]#

[[email protected] ~]# mount /dev/drbd0 /drbdtest/
[[email protected] ~]#

Cuando el nodo que ha caído se ha restablecido, podemos volver a activarlo, aunque quedará como secundario:

[[email protected] ~]# drbdadm up mysql01
Marked additional 8192 KB as out-of-sync based on AL.
[[email protected] ~]#

[[email protected] ~]# drbdadm status mysql01
mysql01 role:Primary
  disk:UpToDate
  peer role:Secondary
    replication:SyncSource peer-disk:Inconsistent done:99.84

[[email protected] ~]# drbdadm status mysql01
mysql01 role:Primary
  disk:UpToDate
  peer role:Secondary
    replication:Established peer-disk:UpToDate

[[email protected] ~]#

Uso de LVM con DRBD

Para utilizar la sincronización de discos con DRBD y utilizar los metadispositivos con LVM, seguiremos los siguientes pasos en todos los nodos del cluster de réplica:

  • Desactivamos el servicio de caché de LVM (lvm2-lvmetad).
  • Eliminamos el fichero /etc/lvm/cache/.cache.
  • Creamos la estructura de LVM y filesystems:
  • gzip /etc/lvm/lvm.conf

Lo siguiente, será configurar DRBD para que sincronice Logical Volumes, en vez de discos.

  • Creamos la estructura de LVM y filesystems en ambos nodos:
[[email protected] ~]# vgcreate vgmysql /dev/xvdf
  Physical volume "/dev/xvdf" successfully created.
  Volume group "vgmysql" successfully created
[[email protected] ~]# lvcreate -n lvmysql -l+100%FREE vgmysql
  Logical volume "lvmysql" created.
[[email protected] ~]# 
  • Configuramos drbd para sincronizar los LVs que nos interesan:
[[email protected] drbd.d]# cat drbdmysql.res
resource drbdmysql {
        on pcm1 {
                device /dev/drbd0;
                disk /dev/vgmysql/lvmysql;
                meta-disk internal;
                address 10.0.3.27:7789;
        }
        on pcm2  {
                device /dev/drbd0;
                disk /dev/vgmysql/lvmysql;
                meta-disk internal;
                address 10.0.3.65:7789;
        }
}
[[email protected] drbd.d]#
  • Arrancamos DRBD igual que hemos hecho anteriormente con los discos sin LVM:
[[email protected] ~]# systemctl start drbd
[[email protected] ~]# systemctl start drbd

[[email protected] ~]# drbdadm create-md drbdmysql
initializing activity log
initializing bitmap (160 KB) to all zero
Writing meta data...
New drbd meta data block successfully created.
success
[[email protected] ~]#

[[email protected] ~]# drbdadm create-md drbdmysql
initializing activity log
initializing bitmap (160 KB) to all zero
Writing meta data...
New drbd meta data block successfully created.
success
[[email protected] ~]#

[[email protected] ~]# drbdadm up drbdmysql
[[email protected] ~]#  drbdadm primary --force drbdmysql
[[email protected] ~]# drbdadm status drbdmysql
drbdmysql role:Primary
  disk:UpToDate
  pcm2 role:Secondary
    peer-disk:UpToDate

[[email protected] ~]#
  • Una vez sincronizados los discos, ya podremos crear un filesystem sobre el metadispositivo de DRBD:
[[email protected] ~]# mkfs.xfs /dev/drbd0
meta-data=/dev/drbd0             isize=512    agcount=4, agsize=327412 blks
         =                       sectsz=512   attr=2, projid32bit=1
         =                       crc=1        finobt=1, sparse=1, rmapbt=0
         =                       reflink=1
data     =                       bsize=4096   blocks=1309647, 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] ~]# mkdir /mysql
[[email protected] ~]# mount /dev/drbd0 /mysql
[[email protected] ~]# df -hP /mysql/
Filesystem      Size  Used Avail Use% Mounted on
/dev/drbd0      5.0G   68M  5.0G   2% /mysql
[[email protected] ~]#

Te podría interesar

¿Te ha gustado? ¡Compártelo!

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

SUSCRÍBETE A PUERTO53

Recibe un email periódico con los artículos más interesantes de Puerto53.com

Antes de suscribirte lee los términos y condiciones. Gracias.

Contenido Relacionado

Artículos Recientes

Deja un comentario

About Author