Alta disponibilidad con clúster en Centos 7

En esta entrada vamos a ver como montar un clúster de alta disponibilidad, en sus siglas HA, de su nombre en inglés “High Availability”, en un servidor con Centos 7. De esta manera podemos ver su instalación, configuración y mantenimiento.

Hay que tener en cuenta que un clúster, en computación, está formado por dos o más nodos, que trabajan juntos para realizar cierta tarea. De esta manera si uno de los nodos falla el otro nodo seguirá suministrando el servicio.

Alta disponibilidad con clúster en Centos 7

Los clústeres pueden ser de diferentes tipos:

  • De Almacenamiento: proporciona una imagen del sistema de ficheros coherente, a través de los servicios suministrados por el clúster, permitiendo que los servidores lean y escriban simultáneamente en un solo de ficheros compartido.
  • Alta disponibilidad: elimina los puntos únicos de fallo y conmuta los servicios ante un error en unos de los nodos.
  • Equilibrio de carga: envía solicitudes de servicio de red a varios nodos del clúster para equilibrar la carga de solicitud entre los nodos.
  • Alto rendimiento: realiza un procesamiento en paralelo o simultaneo, lo que ayuda a mejorar el rendimiento de las aplicaciones.

Otra solución ampliamente utilizada para ofrecer HA es la replicación (específicamente la replicación de datos) La replicación es el proceso mediante el cual una o más bases de datos (secundarias) se pueden mantener sincronizadas con una única base de datos principal (o maestra)

Para este artículo utilizaremos dos nodos, con los nombres:

  • Nodo 1: servnode1 con IP 192.168.0.150
  • Nodo 2: servnode2 con IP 192.168.0.151

Crearemos un clúster activo – pasivo, con una IP virtual y un servicio de web de Apache.

Pasos previos

Para evitar posibles problemas vamos a deshabilitar SELinux, editando su fichero de configuración:

  1. vi /etc/selinux/config

Y sustituir:

  1. SELINUX=enforcing

Por:

  1. SELINUX=disabled

Guardamos y salimos.

Para que se apliquen los cambios debemos reiniciar.

Además, deshabilitamos el cortafuegos para simplificar las cosas:

  1. systemctl disable firewalld
  2. systemctl stop firewalld

Configurar el DNS local

Para que las dos máquinas se puedan comunicar entre sí se debeconfigurar el DNS local, mediante la configuración del fichero “/etc/hosts”, en ambos nodos.

  1. vi /etc/hosts

Y añadimos:

  1. 192.168.0.150 servnode1.localdomain servnode1
  2. 192.168.0.151 servnode2.localdomain servnode2

Guardamos y salimos con : “:wq”

Instalar el servidor Web Apache

La instalación es bien sencilla, para instalar Apache:

  1. yum -y install httpd

Esto, al igual que el resto de los pasos, se tienen que hacer en ambos nodos.

Además vamos a crear un fichero de configuración que nos muestra el estado del servidor Apache:

  1. vi /etc/httpd/conf.d/status.conf

Con el contenido:

  1. <Location /server-status>
  2.    SetHandler server-status
  3.    Order Deny,Allow
  4.    Deny from all
  5.    Allow from 127.0.0.1
  6. </Location>

Estas directivas permiten el acceso a la página de estado solamente desde localhost del nodo activo.

Instalamos y configuramos Corosync y Pacemaker

Las piezas esenciales para el funcionamiento del clúster con Corosync, que nos provee del engine del clúster; con Pacemaker obtendremos las funciones básicas para que el grupo de nodos trabajen juntos en el clúster.

Instalación de Corosync, Pacemaker y pcs

Debemos ejecutar el siguiente comando:

  1. yum install corosync pacemaker pcs

Una vez instalados nos debemos asegurar que la pieza pcs este encendida y añadido al arranque:

  1. systemctl enable pcsd
  2. systemctl start pcsd
  3. systemctl status pcsd

Creamos el clúster

Durante la instalación se crea un usuario del sistema llamado “hacluster” Así que necesitamos asignarle una contraseña necesaria para la pieza “pcs” De la siguiente manera, en ambos nodos:

  1. passwd hacluster

Una vez hecho esto, desde el nodo 1, ejecutamos el siguiente comentado:

  1. [root@servnode1 ]# pcs cluster auth servnode1.localdomain servnode2.localdomain -u hacluster -p contrasea --force
  2. servnode2.localdomain: Authorized
  3. servnode1.localdomain: Authorized

Ahora ya podemos crear el clúster, con el nombre que deseemos, aunque no puede superar los 15 caracteres.

Con el comando:

  1. pcs cluster setup --name nombre-que-deseemos servnode1.localdomain servnode2.localdomain

En mi caso:

  1. [root@servnode1 /]# pcs cluster setup --name clusterweb servnode1.localdomain servnode2.localdomain
  2. Destroying cluster on nodes: servnode1.localdomain, servnode2.localdomain...
  3. servnode1.localdomain: Stopping Cluster (pacemaker)...
  4. servnode2.localdomain: Stopping Cluster (pacemaker)...
  5. servnode2.localdomain: Successfully destroyed cluster
  6. servnode1.localdomain: Successfully destroyed cluster
  7.  
  8. Sending 'pacemaker_remote authkey' to 'servnode1.localdomain', 'servnode2.localdomain'
  9. servnode2.localdomain: successful distribution of the file 'pacemaker_remote authkey'
  10. servnode1.localdomain: successful distribution of the file 'pacemaker_remote authkey'
  11. Sending cluster config files to the nodes...
  12. servnode1.localdomain: Succeeded
  13. servnode2.localdomain: Succeeded
  14.  
  15. Synchronizing pcsd certificates on nodes servnode1.localdomain, servnode2.localdomain...
  16. servnode2.localdomain: Success
  17. servnode1.localdomain: Success
  18. Restarting pcsd on the nodes in order to reload the certificates...
  19. servnode2.localdomain: Success
  20. servnode1.localdomain: Success

Ahora ya Podemos añadir el clúster al arranque y encenderlo:

  1. pcs cluster enable –all
  2. pcs cluster start –all

Tal como sigue:

  1. [root@servnode1 /]# pcs cluster start --all
  2. servnode1.localdomain: Starting Cluster (corosync)...
  3. servnode2.localdomain: Starting Cluster (corosync)...
  4. servnode1.localdomain: Starting Cluster (pacemaker)...
  5. servnode2.localdomain: Starting Cluster (pacemaker)...
  6. [root@servnode1 /]# pcs cluster enable --all
  7. servnode1.localdomain: Cluster Enabled
  8. servnode2.localdomain: Cluster Enabled

Podemos comprobar su estado, de las siguientes maneras:

  1. pcs status
  2. crm_mon -1

Una muestra en mi caso:

  1. [root@servnode1 /]# sudo pcs status
  2. Cluster name: clusterweb
  3.  
  4. WARNINGS:
  5. No stonith devices and stonith-enabled is not false
  6.  
  7. Stack: corosync
  8. Current DC: servnode1.localdomain (version 1.1.19-8.el7_6.2-c3c624ea3d) - partition with quorum
  9. Last updated: Thu Dec 20 10:37:37 2018
  10. Last change: Thu Dec 20 10:33:38 2018 by hacluster via crmd on servnode1.localdomain
  11.  
  12. 2 nodes configured
  13. 0 resources configured
  14.  
  15. Online: [ servnode1.localdomain servnode2.localdomain ]
  16.  
  17. No resources
  18.  
  19.  
  20. Daemon Status:
  21.   corosync: active/enabled
  22.   pacemaker: active/enabled
  23.   pcsd: active/enabled
  24. [root@servnode1 /]# crm_mon -1
  25. Stack: corosync
  26. Current DC: servnode1.localdomain (version 1.1.19-8.el7_6.2-c3c624ea3d) - partition with quorum
  27. Last updated: Thu Dec 20 10:37:48 2018
  28. Last change: Thu Dec 20 10:33:38 2018 by hacluster via crmd on servnode1.localdomain
  29.  
  30. 2 nodes configured
  31. 0 resources configured
  32.  
  33. Online: [ servnode1.localdomain servnode2.localdomain ]
  34.  
  35. No active resources

De esta manera observamos que los dos nodos están conectados, sin errores y en línea. Aún así se nos muestra la siguiente advertencia “No stonith devices and stonith-enabled is not false”, esto es debido a que no hemos definido el STONITH, que se encarga de realizar “fence”, también conocido como “te pego un tiro en la cabeza”, cuando uno de los nodos no funciona correctamente. Todavía nos queda más trabajo por delante, ya que tampoco hemos definido servicios.

Configurar las opciones del clúster

Como hemos dicho la pieza del STONITH esta habilitada por defecto, pero en esta guía no lo vamos a utilizar, por lo que lo vamos a deshabilitar.

Deshabilitamos STONITH :

  1. pcs property set stonith-enabled=false

Además, indicamos que vamos a ignorar la política de cuórum:

  1. pcs property set no-quorum-policy=ignore

Para asegurarnos que todo esta correcto, y que tanto el STONITH como la política de cuórum están deshabilitados:

  1. [root@servnode1 /]#  pcs property list
  2. Cluster Properties:
  3.  cluster-infrastructure: corosync
  4.  cluster-name: clusterweb
  5.  dc-version: 1.1.19-8.el7_6.2-c3c624ea3d
  6.  have-watchdog: false
  7.  no-quorum-policy: ignore
  8.  stonith-enabled: false

Añadir un nuevo servicio o recurso al clúster

En este apartado veremos como agregar un nuevo recurso a nuestro clúster. Una parte importante es configurar una IP virtual, llamada VIP, que se podrá mover de manera instánea de un nodo a otro dentro de la misma red o centro de datos. Necesitamos que esta VIP la utilice el nodo que en ese momento sea el activo.

Por lo que vamos a añadir dos recursos, uno será la VIP y el otro será el webserver con Apache.

Añadimos la siguiente la 192.168.0.160 como VIP, ejecutando la siguiente orden:

  1. pcs resource create vip ocf:heartbeat:IPaddr2 ip=192.168.0.160 cidr_netmask=24 op monitor interval=60s

Analicemos las partes del comando:

  • vip: Es el nombre del recurso
  • “ocf:heartbeat:IPaddr2”: Le indicamos a pacemaker que script debe utilizar, IPaddr2 en este caso. Además definimos en que espacio de nombre se encuentra (pacemaker) y que estandar utiliza, que ese «ocf»
  • “op monitor interval=60s”: Indica a pacemaker que verifique la salud del servicio cada minutos, esto es, 60 segundos.

Ahora que ya tenemos la IP de la VIP definida, pasamos a añadir el servicio web.

  1. pcs resource create servicio_http ocf:heartbeat:apache configfile=/etc/httpd/conf/httpd.conf \
  2. statusurl="http://127.0.0.1/server-status" op monitor interval=20s

Una vez añadidos ambos servicios. Los comprobamos:

  1. pcs status resources

En mi caso:

  1. [root@servnode1 conf]# pcs status resources
  2.  vip    (ocf::heartbeat:IPaddr2):       Started servnode1.localdomain
  3.  servicio_http  (ocf::heartbeat:apache):        Starting servnode2.localdomain

En cuanto a la salida del comando, se han enumerado los dos recursos agregados: «vip» y «servicio_http». Cada uno de los servicios están, en mi caso, en nodos diferentes.

A mi me interesa que tanto la VIP como al servicio de Apache estén en el mismo nodo.

Configuración de parámetros de INFINITY

Casi todas las decisiones en un grupo de pacemaker, como elegir dónde se debe ejecutar un recurso, se realizan comparando una serie de puntuaciones. Las puntuaciones se calculan por recurso, y el administrador de recursos de clúster elige el nodo con la puntuación más alta para un recurso en particular. (Si un nodo tiene una puntuación negativa para un recurso, el recurso no se puede ejecutar en ese nodo).

Podemos manipular las decisiones del clúster con restricciones. Las restricciones tienen una puntuación. Si una restricción tiene una puntuación inferior a INFINITY, es solo una recomendación. Una puntuación de INFINITY significa que es una necesidad.

Queremos asegurarnos de que ambos recursos se ejecuten en el mismo host, por lo que definiremos una restricción de colocación con una puntuación de INFINITY.

  1. pcs constraint colocation add servicio_http vip INFINITY

De esta manena ya tenemos ambos recursos en el mismo host:

  1. Full list of resources:
  2.  
  3.  vip    (ocf::heartbeat:IPaddr2):       Started servnode2.localdomain
  4.  servicio_http  (ocf::heartbeat:apache):        Started servnode2.localdomain

Pruebas de funcionamiento del clúster

Vale, todo esto está muy bien, ¿pero funciona? Desde la consola de comandos, mediante el prograna «Lynx«, consultaremos el estado:

Consulta de estado utilizando Lynx

Hay que anotar que el servicio web de Apache ahora está gestionado directamente por el clúster. Podemos comprobar que esto es así, en el nodo activo:

  1. [root@servnode2 conf.d]# lsof -i :80
  2. COMMAND  PID   USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
  3. httpd   5871   root    4u  IPv6  32431      0t0  TCP *:http (LISTEN)
  4. httpd   5872 apache    4u  IPv6  32431      0t0  TCP *:http (LISTEN)
  5. httpd   5873 apache    4u  IPv6  32431      0t0  TCP *:http (LISTEN)
  6. httpd   5874 apache    4u  IPv6  32431      0t0  TCP *:http (LISTEN)
  7. httpd   5875 apache    4u  IPv6  32431      0t0  TCP *:http (LISTEN)
  8. httpd   5876 apache    4u  IPv6  32431      0t0  TCP *:http (LISTEN)

NOTA: Es muy importante que no intentemos gestionar el servicio de httpd directamente, ya que todas las gestiones se tienen que realizar a través del propio clúster.

Y esto es todo por hoy. Espero que os haya parecido interesante. ¿Tenéis experiencia con la gestión de clústers? Podéis dejar vuestras opiniones en los comentarios.

Nos vamos leyendo.

Fuentes consultadas:

Tecmint – Setup High Availability clustering in Centos and Ubuntu
DigitalOcean – How to set up an Apache active passive cluster using pacemaker on Centos 7