MaxScale con MariaDB Galera Cluster en Contenedores Docker

Introducción

MaxScale tiene un módulo llamado galeramon que nos ayuda a monitorear e interactuar con un Cluster de Galera para MariaDB. En una nota previa instalamos y configuramos MaxScale con MariaDB Galera Cluster en Instancias Virtuales esta vez vamos a hacer lo mismo pero usando Contenedores de Docker.

Prerrequisitos

Necesitamos un Cluster de Galera para MariaDB funcionando en contenedores Docker. Para este ejercicio vamos a usar nuestra instalación en la Google Cloud Platform que realizamos con la nota MariaDB Galera Cluster en Contenedores Docker.

Contenedor de MaxScale

Vamos a crear nuestro contenedor usando la imagen de MaxScale que construimos previamente en MaxScale con Replicación de MariaDB en Contenedores Docker.

Crear el Contenedor

Crea el contenedor patomaxgalera usando la imagen previamente creada patomx/patomaxscale y conéctalo a nuestra red:

pato@patocontainer ~ $ docker image ls
REPOSITORY            TAG                 IMAGE ID            CREATED             SIZE
patomx/patomaxscale   latest              35d1db931d60        7 days ago          351MB
patomx/patomariadb    latest              143534ffe233        12 days ago         453MB

pato@patocontainer ~ $ docker run -d --name patomaxgalera --network pato-net patomx/patomaxscale
184d5e7bc769ef28d42770d85b2d0f33ffa6a2a9690aa747ad0b6e5f00b512c0
pato@patocontainer ~ $

Configuración de MaxScale

Crear un Usuario de Base de Datos para MaxScale

Accede a cualquiera de los nodos de Galera, conéctate a la base de datos y crea el usuario de monitoreo de MaxScale maxpato con los siguientes privilegios:

pato@patocontainer ~ $ docker exec -it patomariag1 mysql

MariaDB [(none)]> GRANT SELECT ON mysql.* TO 'maxpato'@'%' IDENTIFIED BY '********';
Query OK, 0 rows affected (0.399 sec)

MariaDB [(none)]> GRANT REPLICATION CLIENT, SHOW DATABASES ON *.* TO 'maxpato'@'%';
Query OK, 0 rows affected (0.012 sec)

MariaDB [(none)]> flush privileges ;
Query OK, 0 rows affected (0.014 sec)

Crear un Archivo de Configuración para Cluster de Galera

En el anfitrión de docker crea un nuevo archivo de configuración con los siguientes parámetros:

pato@patocontainer ~/maxscale $ nano maxscale-galera.cnf
  • Definir el host y puerto de los servidores en la replicación
[Pato-Node0]
type=server
address=patomariagm
port=3306
protocol=MariaDBBackend

[Pato-Node1]
type=server
address=patomariag1
port=3306
protocol=MariaDBBackend

[Pato-Node2]
type=server
address=patomariag2
port=3306
protocol=MariaDBBackend
  • Designar el monitor de MaxScale, usando el módulo galeramon ya que ésta es una replicación de Galera.
    Configurar el usuario y contraseña para el usuario de monitoreo.
[Pato-Monitor]
type=monitor
module=galeramon
servers=Pato-Node0,Pato-Node1,Pato-Node2
user=maxpato
password=********
monitor_interval=2000
  • Definir el Servicio para la distribución lectura escritura entre el Node0 y el Node1 escuchando en el puerto 4006.
[RW-Service]
type=service
router=readwritesplit
servers=Pato-Node0,Pato-Node1
user=maxpato
password=********

[RW-Listener]
type=listener
service=RW-Service
protocol=MariaDBClient
port=4006
  • Definir el Servicio para sólo lectura en el Node2 escuchando en el puerto 4008.
[RO-Service]
type=service
router=readconnroute
servers=Pato-Node2
user=maxpato
password=********
router_options=slave

[RO-Listener]
type=listener
service=RO-Service
protocol=MariaDBClient
port=4008
  • Definir el Servicio para la interface de Línea de Comandos maxadmin y maxctrl escuchando en el puerto 6603.
[CLI]
type=service
router=cli

[CLI-Listener]
type=listener
service=CLI
protocol=maxscaled
address=127.0.0.1
port=6603

Cargar la Nueva Configuración

Copia el archivo previamente creado a nuestro contenedor, hacia el archivo de configuración de MaxScale /etc/maxscale.cnf y reinicia el contenedor para que la nueva configuración se cargue:

pato@patocontainer ~/maxscale $ docker cp maxscale-galera.cnf patomaxgalera:/etc/maxscale.cnf
pato@patocontainer ~/maxscale $ docker restart patomaxgalera
patomaxgalera
pato@patocontainer ~/maxscale $

Validar que MaxScale está en Ejecución

Conéctate al contenedor de MaxScale y valida que esté monitoreando las bases de datos configuradas enviando el comando maxadmin -pmariadb list servers:

pato@patocontainer ~/maxscale $ docker exec -it patomaxgalera bash
root@184d5e7bc769:/# maxadmin -pmariadb list servers
Servers.
-------------------+-----------------+-------+-------------+--------------------
Server             | Address         | Port  | Connections | Status
-------------------+-----------------+-------+-------------+--------------------
Pato-Node0         | patomariagm     |  3306 |           0 | Master, Synced, Running
Pato-Node1         | patomariag1     |  3306 |           0 | Slave, Synced, Running
Pato-Node2         | patomariag2     |  3306 |           0 | Slave, Synced, Running
-------------------+-----------------+-------+-------------+--------------------

Funcionalidades de MaxScale

Punto Único de Acceso y Balanceo de Carga

Como ya tenemos nuestro MaxScale corriendo ya no necesitamos conectarnos directamente a alguna de las instancias de base de datos.
Para las conexiones remotas necesitamos apuntar nuestro cliente o aplicación hacia la instancia de MaxScale en el puerto 4006 para que las actividades de lectura escritura se balanceen entre el Node0 y el Node1:

$ mysql -u remoto -p -h patomaxgalera -P 4006
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.

MariaDB [(none)]> select @@hostname ;
+--------------+
| @@hostname   |
+--------------+
| 3f3ffc1505f6 |
+--------------+
1 row in set (0.001 sec)

o conectarnos al puerto 4008 para una conexión de sólo lectura fija en el Node2:

$ mysql -u remoto -p -h patomaxgalera -P 4008
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.

MariaDB [(none)]> select @@hostname ;
+--------------+
| @@hostname   |
+--------------+
| 282d806c486f |
+--------------+
1 row in set (0.001 sec)

Podemos ver que nos estamos conectando al servidor de MaxScale y que somos redireccionados hacia los nodos del cluster de acuerdo a nuestra configuración.

Monitorar que los Nodos están Sincronizados

Como se mencionó anteriormente, una particularidad del monitor galeramon es su capacidad de monitorear cuando los nodos del cluster están sincronizados:

pato@patocontainer ~/maxscale $ docker exec -it patomaxgalera bash
root@184d5e7bc769:/# maxadmin -pmariadb list servers
Servers.
-------------------+-----------------+-------+-------------+--------------------
Server             | Address         | Port  | Connections | Status
-------------------+-----------------+-------+-------------+--------------------
Pato-Node0         | patomariagm     |  3306 |           0 | Master, Synced, Running
Pato-Node1         | patomariag1     |  3306 |           0 | Slave, Synced, Running
Pato-Node2         | patomariag2     |  3306 |           0 | Slave, Synced, Running
-------------------+-----------------+-------+-------------+--------------------

Podemos ver que los nodos de Galera no solo están marcados en ejecución Running sino también sincronizados Synced.

Asignar Roles Master Esclavo

La otra funcionalidad es poder asignar roles Maestro y Esclavo dentro de MaxScale para que podamos ver cuál es el nodo bootstrap/donante.

Por defecto, el Monitor de Galera escogerá aquel nodo con el menor valor en wsrep_local_index como el Master.

Mandemos el comando maxctrl list servers:

pato@patocontainer ~ $ docker exec -it patomaxgalera maxctrl list servers
+----------------------------------------------------------------------------------+
¦ Server     ¦ Address     ¦ Port ¦ Connections ¦ State                   ¦ GTID   ¦
+------------+-------------+------+-------------+-------------------------+--------¦
¦ Pato-Node0 ¦ patomariagm ¦ 3306 ¦ 0           ¦ Master, Synced, Running ¦ 1-1-13 ¦
+------------+-------------+------+-------------+-------------------------+--------¦
¦ Pato-Node1 ¦ patomariag1 ¦ 3306 ¦ 0           ¦ Slave, Synced, Running  ¦ 1-1-13 ¦
+------------+-------------+------+-------------+-------------------------+--------+
¦ Pato-Node2 ¦ patomariag2 ¦ 3306 ¦ 0           ¦ Slave, Synced, Running  ¦ 1-1-13 ¦
+------------+-------------+------+-------------+-------------------------+--------+

Como podemos ver la columa State muestra los roles asignados y también se muestra el GTID compartido en el cluster.

Master FailBack

Ahora vamos a probar el comportamiento de los roles cuando el nodo Master falla y regresa.

Detengamos el servidor designado patomariagm:

pato@patocontainer ~ $ docker stop patomariagm
patomariagm

y validemos su estado mandando el comando maxctrl list servers:

pato@patocontainer ~ $ docker exec -it patomaxgalera maxctrl list servers
+----------------------------------------------------------------------------------+
¦ Server     ¦ Address     ¦ Port ¦ Connections ¦ State                   ¦ GTID   ¦
+------------+-------------+------+-------------+-------------------------+--------¦
¦ Pato-Node0 ¦ patomariagm ¦ 3306 ¦ 0           ¦ Down                    ¦        ¦
+------------+-------------+------+-------------+-------------------------+--------¦
¦ Pato-Node1 ¦ patomariag1 ¦ 3306 ¦ 0           ¦ Master, Synced, Running ¦ 1-1-15 ¦
+------------+-------------+------+-------------+-------------------------+--------¦
¦ Pato-Node2 ¦ patomariag2 ¦ 3306 ¦ 0           ¦ Slave, Synced, Running  ¦ 1-1-15 ¦
+------------+-------------+------+-------------+-------------------------+--------+

nuestro servidor queda marcado como Down y el siguiente servidor es promovido a Master. Podemos ver que el cambio de roles fue detectado en el registro de MaxScale:

pato@patocontainer ~ $ docker logs patomaxgalera | tail

2020-06-03 21:52:42   notice : Server changed state: Pato-Node0[patomariagm:3306]: master_down. [Master, Synced, Running] -> [Down]
2020-06-03 21:52:42   notice : Server changed state: Pato-Node1[patomariag1:3306]: new_master. [Slave, Synced, Running] -> [Master, Synced, Running]
2020-06-03 21:52:42   notice : Master switch detected: lost a master and gained a new one

Entonces si iniciamos el servidor patomariagm éste recobrará su estaus de Master:

pato@patocontainer ~ $ docker start patomariagm
patomariagm

y lo validamos mandando el comando maxctrl list servers:

pato@patomaxscale:~$ maxctrl list servers
+----------------------------------------------------------------------------------+
¦ Server     ¦ Address     ¦ Port ¦ Connections ¦ State                   ¦ GTID   ¦
+------------+-------------+------+-------------+-------------------------+--------¦
¦ Pato-Node0 ¦ patomariagm ¦ 3306 ¦ 0           ¦ Master, Synced, Running ¦ 1-1-16 ¦
+------------+-------------+------+-------------+-------------------------+--------¦
¦ Pato-Node1 ¦ patomariag1 ¦ 3306 ¦ 0           ¦ Slave, Synced, Running  ¦ 1-1-16 ¦
+------------+-------------+------+-------------+-------------------------+--------¦
¦ Pato-Node2 ¦ patomariag2 ¦ 3306 ¦ 0           ¦ Slave, Synced, Running  ¦ 1-1-16 ¦
+------------+-------------+------+-------------+-------------------------+--------+

Podemos ver que el cambio fue detectado en el registro de MaxScale:

pato@patocontainer ~ $ docker logs patomaxgalera | tail

2020-06-03 22:03:11   notice : Server changed state: Pato-Node0[patomariag1:3306]: master_up. [Down] -> [Master, Synced, Running]
2020-06-03 22:03:11   notice : Server changed state: Pato-Node1[patomariagm:3306]: new_slave. [Master, Synced, Running] -> [Slave, Synced, Running]

Hemos validado que el role Master fue reasignado al nodo original.

Conclusión

Hemos instalado exitosamente MaxScale en nuestro ambiente Docker corriendo en una máquina virtual de Google Cloud y lo hemos configurado para monitorear nuestro Cluster de Galera para MariaDB. Asimismo fuimos capaces de validar las funcionalidades descritas tales como detección de Sincronía, asignación de Roles y el Master Failback.