Etiquetas

, , , , , , , , , , , , ,


Recientemente me toco crear un cluster con 3 equipos para correr mysql HA con pacemaker y corosync en redhat, por lo que estoy haciendo este pequeño howto el cual se puede adaptar a cualquier distro, así que vamos al grano.

Lo primero que debemos instalar son los paquetes necesarios pacemaker, corosync mysql en los 3 nodos

[root@nodox]# yum -y install corosync pcs pacemaker mysql-server mysql-common mysql-client

Iniciamos el servicio pacemaker en los 3 nodos

[root@nodox]# systemctl start pcsd

Debemos crear una clave y el usuario para la autenticación de los nodos en el cluster en todos los miembros del cluster.

[root@nodox]# passwd hacluster

En el nodo 1 vamos a iniciar o unir todos los nodos disponibles a nuestro cluster

[root@nodo1]# pcs host auth nodo1 nodo2 nodo3

Con el comando anterior nos pedirá la clave del hacluster, para autenticar el cluster en los 3 nodos.

Ahora crearemos el cluster para luego activarlo.

[root@nodo1]# pcs cluster setup --name cluster_mysql nodo1 nodo2 nodo3
[root@nodo1]# pcs cluster enable --all

Donde –name es el nombre del cluster que queremos darle, ya solo nos falta iniciar los servicios y tendremos nuestro cluster corriendo.

[root@nodo1]# systemctl start pacemaker; systemctl start corosync
[root@nodo1]# systemctl enable pacemaker; systemctl enable corosync

Iniciamos el cluster en todos los nodos

[root@nodo1]# pcs cluster start --all

Hasta aquí tendremos nuestro cluster corriendo y debemos iniciar con la configuración del cluster para mysql

Lo primero que debemos hacer es deshabilitar los stonith que es el método de seguridad del cluster y colocando el false le indicamos al cluster que no falle o no alerte si algunos de nuestros nodos se desconectan de manera no apropiada.

[root@nodo1 root]# pcs property set stonith-enabled=false

Para que el cluster funcione deben existir 2 servicios mysql-ser-clone y mysql-vip, el primero clona los servicios mysql en todos los nodos y el segundo asigna una ip virtual flotante la cual será utilizada por el nodo que asuma el master en ese momento, por lo que debemos configurar el cluster con una ip del mismo segmento de los 3 nodos.

[root@nodo1 root]# pcs resource create virtual_ip ocf:heartbeat:IPaddr2 ip=10.10.1.104 cidr_netmask=29 --group mysql

Ahora definiremos los contraints y esto son las preferencias para asumir el master del cluster, dichas preferencias van del 100 al 0, 100 como la mayor prioridad y 0 como la de menor prioridad, de tal modo que si tenemos más de 3 nodos podemos darle las siguientes prioridades Ejemplo: nodo1=100, nodo2=75, nodo3=50, nodo4=25, nodo6=0

[root@nodo1 root]# pcs constraint location mysql_vip prefers nodo01=100
[root@nodo1 root]# pcs constraint location mysql_vip prefers nodo02=50
[root@nodo1 root]# pcs constraint location mysql_vip prefers nodo03=0
[root@nodo1 root]# pcs resource create mysql_ser systemd:mysqld --group mysql
[root@nodo1 root]# pcs resource clone mysql_ser

Ya con todo esto tendremos configurado nuestro cluster con 3 nodos y podemos verificar con el sigueinte comando.

[root@nodo1 root]# pcs status
Cluster name: mysql_cluster
Cluster Summary:
  * Stack: corosync
  * Current DC: nodo03  (version 2.0.X) - partition with quorum
  * Last updated: Mon Feb 21 17:21:29 2022
  * Last change:  Mon Feb 21 15:31:15 2022 by hacluster via crmd on nodo03
  * 3 nodes configured
  * 4 resource instances configured

Node List:
  * Online: [ nodo01  nodo02  nodo03  ]

Full List of Resources:
  * Resource Group: mysql:
    * mysql_vip (ocf::heartbeat:IPaddr2):        Started nodo01
  * Clone Set: mysql_ser-clone [mysql_ser]:
    * Started: [ nodo01  nodo02  nodo03  ]

Daemon Status:
  corosync: active/enabled
  pacemaker: active/enabled
  pcsd: active/enabled
[root@nodo01 root]#

Si todo ha salido bien nos debe salir algo parecido a lo anterior, que nos indicara quien está como master y quienes son los esclavos.

Para que mysql tenga alta disponibilidad debemos configurar a nivel de DB para que se repliquen entre los nodos independientemente del cluster y para ello debemos habilitar 2 opciones en mysql.

Lo primero es loguearnos desde la consola o manejador de DB de nuestra preferencia apuntando al nodo1.

Configuraremos nuestro cluster para que sea HA, lo que quiere decir que independientemente del nodo que este activo, los datos se replicaran en todos los nodos y para ello es importante crear un usuario para la réplica y su password a nivel de mysql en todos los nodos ya que este es el encargado de realizar la replicación de los datos y con el comando grant replication indicamos que es el usuario encargado de realizar la replicación en mi caso use replicauser, ustedes pueden usar el que gusten.

[root@nodo01 root]# mysql -u root -p
mysql> create user replicauser; 
mysql> ALTER USER 'replicauser'@'%' IDENTIFIED BY 'new_passowrd'; 
mysql> grant all on *.* to 'replicauser'@'%'; mysql> grant replication slave on *.* to 'replicauser'@'%';

Para configurar mysql HA realizaremos el siguiente procedimiento.

[root@nodo01 root]# mysql -u root -p
mysql> show master status;
+---------------+----------+--------------+------------------+-------------------+
| File          | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000008 |     5490 |              |                  |                   |
+---------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
mysql>

Estos nos los datos de nuestro servidor master de mysql y que debemos configurar en el servidor esclavo para que se realicen las réplicas, ahora sabiendo los parámetros del File y Position nos vamos al servidor esclavo nodo2

[root@nodo01 root]#mysql -u root -p
mysql> show slave status\G; 
*************************** 1. row ***************************
               Slave_IO_State: Waiting for source to send event
                  Master_Host: 10.10.1.101
                  Master_User: replicauser
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: binlog.000012
          Read_Master_Log_Pos: 2414
               Relay_Log_File: nodo3-relay-bin.000023
                Relay_Log_Pos: 1766
        Relay_Master_Log_File: binlog.000012
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB:
          Replicate_Ignore_DB:
           Replicate_Do_Table:
       Replicate_Ignore_Table:
      Replicate_Wild_Do_Table:
  Replicate_Wild_Ignore_Table:
                   Last_Errno: 0
                   Last_Error:
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 2414
              Relay_Log_Space: 2148
              Until_Condition: None
               Until_Log_File:
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File:
           Master_SSL_CA_Path:
              Master_SSL_Cert:
            Master_SSL_Cipher:
               Master_SSL_Key:
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error:
               Last_SQL_Errno: 0
               Last_SQL_Error:
  Replicate_Ignore_Server_Ids:
             Master_Server_Id: 2
                  Master_UUID: 00b69db0-8ffe-11ec-97fd-005056969d78
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates
           Master_Retry_Count: 86400
                  Master_Bind:
      Last_IO_Error_Timestamp:
     Last_SQL_Error_Timestamp:
               Master_SSL_Crl:
           Master_SSL_Crlpath:
           Retrieved_Gtid_Set:
            Executed_Gtid_Set:
                Auto_Position: 0
         Replicate_Rewrite_DB:
                 Channel_Name:
           Master_TLS_Version:
       Master_public_key_path:
        Get_master_public_key: 0
            Network_Namespace:
1 row in set, 1 warning (0.01 sec)

Vemos la salida anterior del comando slave en mi caso ya está configurado, pero si quisiera cambiar algún parámetro o en caso de que sea la primera configuración ejecutaríamos el siguiente comando dentro de la consola mysql.

mysql> CHANGE MASTER TO MASTER_HOST='ipdelmaster', Master_Port='3306' MASTER_USER='replicauser', MASTER_PASSWORD='password', MASTER_LOG_FILE='binlog.000012 ', MASTER_LOG_POS= 5094;

Iniciamos el esclavo con start slave desde la consola mysql y deberíamos ver una línea como estas: Slave_SQL_Running_State: Replica has read all relay log; waiting for more updates

Lo que nos indica que se está ejecutando la replica de DB en mysql, para probar basta con crear una db o una tabla o hacer un insert en alguna tabla existente y podremos ver los datos replicados.

En nuestro caso como queremos que se replique en todos los nodos, debemos realizar el procedimiento de master y slave en cada uno para lograr nuestro objetivo, esto porque mysql puede ser master y esclavo al mismo tiempo.

Nuestro escenario es:

nodo1 ip 10.10.1.101, nodo2 ip 10.10.1.102, nodo3 ip 10.10.1.103

nodo 1 es master del nodo2 y esclavo del nodo3.

nodo2 es master del nodo3 pero esclavo del nodo1.

nodo3 es master del nodo1 pero esclavo del nodo2

por lo que se cumple el ciclo que andamos buscando de alta disponibilidad de los datos.

Algunos comandos para administración de nuestro cluster

pcs status para saber el estado de nuestro nodo y del cluster

pcs resource restart/enable/disable servicio(mysql_vip, mysql-ser-clone)

pcs config para saber la configuración del cluster

pcs cluster stop para para el cluster en un nodo en especifico

pcs cluster stop –all para para todos los nodos del cluster y los servicios de mysql

pcs node standby nodo1 para mover los servicios al nodo2.

pcs node unstanby nodo1 para regresar los servicios al nodo1

A mi particularmente me gusta utilizar mas pcs cluster stop ya que esto baja tambien el servicio de mysql y para hacer cambios es ideal ya que no hay ningun servicio del cluster corriendo.

NOTA: Es necesario que el archivo /etc/hosts este correctamente configurado en caso de no tener un dns para que se pueda resolver los nombres de los nodos de forma correcta.

Éxitos.