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

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.

[root@server1 ~]# cat /etc/hosts |grep server
10.0.0.2 server1
10.0.0.3 server2
[root@server1 ~]#

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:

[root@server1 ~]# cat /etc/drbd.d/global_common.conf
global {
 usage-count  yes;
 cmd-timeout-medium 121;
}
common {
 net {
  protocol C;
 }
}
[root@server1 ~]#
  • 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:

[root@server1 ~]# 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;
        }
}
[root@server1 ~]#

«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:

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

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

[root@server1 ~]# drbdadm up drbtest
[root@server1 ~]# 

[root@server1 ~]# 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:

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

[root@server1 ~]#

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

[root@server1 ~]# 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
[root@server1 ~]#

Probando la réplica de datos

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

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


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

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

[root@server1 ~]# umount /drbdtest/
[root@server1 ~]# drbdadm secondary drbtest

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

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:

[root@server1 ~]# drbdadm status mysql01
mysql01 role:Secondary
  disk:UpToDate
  peer role:Primary
    replication:Established peer-disk:UpToDate

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

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:

[root@server2 ~]# drbdadm disconnect drbtest
[root@server2 ~]# drbdadm status drbtest
drbtest role:Primary
  disk:UpToDate

[root@server2 ~]# drbdadm connect drbtest
[root@server2 ~]# drbdadm status drbtest
drbtest role:Primary
  disk:UpToDate
  peer role:Secondary
    replication:Established peer-disk:UpToDate

[root@server2 ~]#

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

[root@server1 ~]#  drbdadm status drbtest
drbtest role:Secondary
  disk:UpToDate
  peer role:Primary
    replication:Established peer-disk:UpToDate

[root@server1 ~]#

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:

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

[root@server1 drbd.d]#

[root@server2 drbd.d]# drbdadm down mysql
[root@server2 drbd.d]#

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

[root@server1 drbd.d]# mv mysql.res mysql01.res
[root@server1 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;
        }
}
[root@server1 drbd.d]#

Hacemos lo mismo en todos los nodos.

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

[root@server1 drbd.d]# drbdadm up mysql01
[root@server1 drbd.d]# drbdadm status mysql01
mysql01 role:Secondary
  disk:UpToDate
  peer connection:Connecting

[root@server1 drbd.d]# drbdadm status mysql01
mysql01 role:Secondary
  disk:UpToDate
  peer role:Secondary
    replication:Established peer-disk:UpToDate

[root@server1 drbd.d]# drbdadm primary mysql01
[root@server1 drbd.d]# mount /dev/drbd0 /drbdtest/
[root@server1 drbd.d]# df -hP /drbdtest/
Filesystem      Size  Used Avail Use% Mounted on
/dev/drbd0     1018M   33M  986M   4% /drbdtest
[root@server1 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:

[root@server2 drbd.d]# drbdadm detach mysql01
[root@server2 drbd.d]# drbdadm status mysql01
mysql01 role:Secondary
  disk:Diskless

[root@server2 drbd.d]#

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

[root@server2 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;
        }
}
[root@server2 drbd.d]#

El fichero lo copiamos a todos los nodos del cluster.

Recreamos el metadispositivo DRBD, de nuevo:

[root@server2 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.
[root@server2 drbd.d]#

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

[root@server2 drbd.d]#

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

[root@server2 drbd.d]# drbdadm status mysql01
mysql01 role:Secondary
  disk:UpToDate
  peer role:Primary
    replication:Established peer-disk:UpToDate

[root@server2 drbd.d]#

Reboot del nodo primario

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

[root@server2 ~]# drbdadm status mysql01
mysql01 role:Primary
  disk:UpToDate
  peer role:Secondary
    replication:Established peer-disk:UpToDate

[root@server2 ~]# reboot

[root@server1 ~]# drbdadm primary mysql01
[root@server1 ~]# drbdadm status mysql01
mysql01 role:Primary
  disk:UpToDate
  peer connection:Connecting

[root@server1 ~]#

[root@server1 ~]# mount /dev/drbd0 /drbdtest/
[root@server1 ~]#

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

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

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

[root@server1 ~]# drbdadm status mysql01
mysql01 role:Primary
  disk:UpToDate
  peer role:Secondary
    replication:Established peer-disk:UpToDate

[root@server1 ~]#

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:
[root@pcm1 ~]# vgcreate vgmysql /dev/xvdf
  Physical volume "/dev/xvdf" successfully created.
  Volume group "vgmysql" successfully created
[root@pcm1 ~]# lvcreate -n lvmysql -l+100%FREE vgmysql
  Logical volume "lvmysql" created.
[root@pcm1 ~]# 
  • Configuramos drbd para sincronizar los LVs que nos interesan:
[root@pcm2 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;
        }
}
[root@pcm2 drbd.d]#
  • Arrancamos DRBD igual que hemos hecho anteriormente con los discos sin LVM:
[root@pcm1 ~]# systemctl start drbd
[root@pcm2 ~]# systemctl start drbd

[root@pcm1 ~]# 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
[root@pcm1 ~]#

[root@pcm2 ~]# 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
[root@pcm2 ~]#

[root@pcm1 ~]# drbdadm up drbdmysql
[root@pcm1 ~]#  drbdadm primary --force drbdmysql
[root@pcm1 ~]# drbdadm status drbdmysql
drbdmysql role:Primary
  disk:UpToDate
  pcm2 role:Secondary
    peer-disk:UpToDate

[root@pcm1 ~]#
  • Una vez sincronizados los discos, ya podremos crear un filesystem sobre el metadispositivo de DRBD:
[root@pcm1 ~]# 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
[root@pcm1 ~]#

[root@pcm1 ~]# mkdir /mysql
[root@pcm1 ~]# mount /dev/drbd0 /mysql
[root@pcm1 ~]# df -hP /mysql/
Filesystem      Size  Used Avail Use% Mounted on
/dev/drbd0      5.0G   68M  5.0G   2% /mysql
[root@pcm1 ~]#

Te podría interesar

COMPÁRTEME

2 comentarios en «Réplica activa-pasiva de filesystems con DRBD en Linux CentOS»

  1. no funciono, estoy en centos 7.9.2009, y al realizar la instalacion al pie de la letra de tu post, en el segundo nodo genera este error:
    mount: /dev/drbd0 is write-protected, mounting read-only
    mount: mount /dev/drbd0 on /drbdtest failed: Wrong medium type

    en el nodo1 si lo dejo montar

    root@issa1 ~]# drbdadm status drbtest
    drbtest role:Primary
    disk:UpToDate
    peer connection:Connecting

    [root@issa2 ~]# drbdadm status drbtest
    drbtest role:Secondary
    disk:Inconsistent
    peer connection:Connecting

    Responder
    • Hola, el recurso solamente lo deja montar en el nodo primario. Para montar el FS en el nodo secundario, este nodo debería configurarse como primario.

      De hecho, en el artículo hablo de esto en el apartado «Protección de corrupción de datos por duplicidad de montaje del filesystem». Luego en «Reboot del nodo primario» puedes ver cómo configurar un nodo como primario.

      Si te sigue dando problemas, mándame todos los comandos que ejecutas, a ver si te puedo echar un cable.

      Un saludo.

      Responder

Deja un comentario