MaxScale con Replicación de MariaDB en Contenedores Docker

Introducción

Cuando instalas un cluster de Replicación de MariaDB tendrás dos o más contenedores de base de datos que deben actuar como una sola unidad. Para las aplicaciones sólo hay una sola base y ellas deben poderse conectar y trabajar, independientemente de la arquitectura de la base de datos.
Para resolver esto necesitamos usar MaxScale, un software proxy que provee un único punto de acceso a la base de datos y que también incluye otros beneficios como el Balanceo de Carga y el Failover.
Vamos a configurar MaxScale en un contenedor de Docker y probar sus funcionalidades de Failover.

Prerequisites

Necesitamos un cluster de Replicación Master Esclavo de MariaDB funcionando en contenedores Docker. Para este ejercicio vamos a usar nuestra instalación en Google Cloud Platform para la Replicación MariaDB en contenedores Docker, favor de revisar el documento Replicación Master Esclavo de MariaDB en Contenedores Docker.

Contenedor de MaxScale

Construir una Imagen

Vamos a construir nuestra imagen de MaxScale usando una imagen de Ubuntu, actualizando el sistema operativo, bajando e instalando el software de MaxScale, exponiendo los puertos de escucha y levantando el servicio.
Primero creemos el archivo Dockerfile de esta forma:

FROM ubuntu
RUN apt update &&\
    apt upgrade -y &&\
    apt install -y vim nano net-tools iputils-ping wget
RUN wget https://downloads.mariadb.com/MaxScale/2.4.9/ubuntu/dists/bionic/main/binary-amd64/maxscale-2.4.9-1.ubuntu.bionic.x86_64.deb && \
    dpkg -i maxscale-2.4.9-1.ubuntu.bionic.x86_64.deb; exit 0
RUN apt --fix-broken install -y
EXPOSE 4006 4008
CMD service maxscale start & tail -F /var/log/maxscale/maxscale.log

Luego construyando nuestra imagen desde el directorio donde creamos el Dockerfile:

pato@patocontainer ~/maxscale $ docker build --tag patomx/patomaxscale .
...
Successfully built 35d1db931d60
Successfully tagged patomx/patomaxscale:latest

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

Crear el Contenedor

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

pato@patocontainer ~ $ docker run -d --name patomaxmsr --network pato-net patomx/patomaxscale
9c7cf7ee2093f84d38a653637f3da41a332eac84964e50f1ec94c1616a0ba058
pato@patocontainer ~ $

Configuración de MaxScale

Crear un Usuario de Base de Datos para MaxScale

Conéctate a la base de datos Master y crea el usuario de monitoreo de MaxScale maxpato con los siguientes privilegios:

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

MariaDB [mysql]> GRANT SUPER, REPLICATION CLIENT, REPLICATION SLAVE, RELOAD, PROCESS, SHOW DATABASES, EVENT ON *.* TO 'maxpato'@'%';
Query OK, 0 rows affected (0.003 sec)

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

Crear un Archivo de Configuración para Master-Esclavo

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

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

[Pato-Slave]
type=server
address=patomariarp
port=3306
protocol=MariaDBBackend
  • Designar el monitor de MaxScale, usando el módulo mariadbmon ya que ésta es una replicación Master-Esclavo.
    Configurar el usuario y contraseña para el usuario de monitoreo.
    Definir los parámetros para Failover y Rejoin automáticos
[Pato-Monitor]
type=monitor
module=mariadbmon
servers=Pato-Master,Pato-Slave
user=maxpato
password=xxxxxxxx
monitor_interval=2000
auto_failover=true
auto_rejoin=true
  • Definir el Servicio para la distribución lectura escritura entre el Master y Esclavo escuchando en el puerto 4006.
[RW-Service]
type=service
router=readwritesplit
servers=Pato-Master,Pato-Slave
user=maxpato
password=********

[RW-Listener]
type=listener
service=RW-Service
protocol=MariaDBClient
port=4006
  • 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 hacia el contenedor de MaxScale en /etc/maxscale.cnf y reinicia el contenedor para que se cargue la nueva configuración.

pato@patocontainer ~/maxscale $ docker cp maxscale-masterslave.cnf patomaxmsr:/etc/maxscale.cnf
pato@patocontainer ~/maxscale $ docker restart patomaxmsr
patomaxmsr
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 list servers:

pato@patocontainer ~/maxscale $ docker exec -it patomaxmsr bash
root@9c7cf7ee2093:/# maxadmin -pmariadb list servers
Servers.
-------------------+-----------------+-------+-------------+--------------------
Server             | Address         | Port  | Connections | Status
-------------------+-----------------+-------+-------------+--------------------
Pato-Master        | patomariadb     |  3306 |           0 | Master, Running
Pato-Slave         | patomariarp     |  3306 |           0 | Slave, Running
-------------------+-----------------+-------+-------------+--------------------

y valida que los servicios estén en ejecución y escuchando:

root@9c7cf7ee2093:/# maxadmin -pmariadb list listeners
Listeners.
---------------------+---------------------+--------------------+-----------------+-------+--------
Name                 | Service Name        | Protocol Module    | Address         | Port  | State
---------------------+---------------------+--------------------+-----------------+-------+--------
RW-Listener          | RW-Service          | MariaDBClient      | ::              |  4006 | Running
CLI-Listener         | CLI                 | maxscaled          | 127.0.0.1       |  6603 | Running
---------------------+---------------------+--------------------+-----------------+-------+--------

Conexión a la Base de Datos usando MaxScale

Ahora que nuestro MaxScale está funcionando ya no tenemos que conectarnos directamente a la base de datos Master.
Para las conexiones remotas debemos apuntar nuestro cliente o aplicación hacia el puerto 4006 de la instancia de MaxScale y así las actividades se balancearán entre el Master y el Esclavo:

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

MariaDB [(none)]>

Functionalidades Automáticas

En nuestro archivo de configuración de MaxScale configuramos las opciones de auto_failover y auto_rejoin:

auto_failover=true
auto_rejoin=true

Con estas opciones MaxScale ayuda a nuestro Cluster de MariaDB a automatizar las actividades del failover, rejoin y switchover en caso de que algunos de los nodos falle y se recupere. Probemos estas funcionalidades.

Failover

Vamos a detener la base de datos Master y probemos el failover automático:

pato@patocontainer ~/maxscale $ docker stop patomariadb

El Master se cae y el Esclavo es promovido al rol de Master automáticamente. Validemos esto ejecutando el comando maxctrl list servers:

pato@patocontainer ~/maxscale $ docker exec -it --user maxscale patomaxmsr bash
maxscale@9c7cf7ee2093:/$ maxctrl list servers
+----------------------------------------------------------------------------+
¦ Server      ¦ Address     ¦ Port ¦ Connections ¦ State           ¦ GTID    ¦
+-------------+-------------+------+-------------+-----------------+---------¦
¦ Pato-Master ¦ patomariadb ¦ 3306 ¦ 0           ¦ Down            ¦ 0-1-40  ¦
+-------------+-------------+------+-------------+-----------------+---------¦
¦ Pato-Slave  ¦ patomariarp ¦ 3306 ¦ 0           ¦ Master, Running ¦ 0-11-44 ¦
+-------------+-------------+------+-------------+-----------------+---------+

notar que el GTID se sigue moviendo en el nodo en ejecución ya que todas las actualizaciones se realizan ahora en el nuevo Master.

Availability

Como usamos el MaxScale para conectarnos a la base de datos, aun cuando la instancia patomariadb Pato-master ha fallado, los usuarios aún pueden trabajar ya que las conexiones se redireccionan transparentemente a la instancia patomariarp Pato-Slave:

$ mysql -u remoto -p -h patomaxmsr -P 4006
Enter password:
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 5

MariaDB [(none)]> select @@hostname;
+--------------+
| @@hostname   |
+--------------+
| 4287cdea4dab |
+--------------+
1 row in set (0.000 sec)

Rejoin

Cuando el servidor patomariadb se recupere éste se unirá automáticamente al cluster de replicación pero esta vez en el rol de Esclavo. Validemos esto ejecutando el comando maxctrl list servers:

pato@patocontainer ~/maxscale $ docker start patomariadb
patomariadb
pato@patocontainer ~/maxscale $ docker exec -it patomaxmsr maxctrl list servers
+----------------------------------------------------------------------------+
¦ Server      ¦ Address     ¦ Port ¦ Connections ¦ State           ¦ GTID    ¦
+-------------+-------------+------+-------------+-----------------+---------¦
¦ Pato-Master ¦ patomariadb ¦ 3306 ¦ 0           ¦ Slave, Running  ¦ 0-11-46 ¦
+-------------+-------------+------+-------------+-----------------+---------¦
¦ Pato-Slave  ¦ patomariarp ¦ 3306 ¦ 0           ¦ Master, Running ¦ 0-11-46 ¦
+-------------+-------------+------+-------------+-----------------+---------+

También podemos ver que el identificador global de transacciones GTID es de nuevo el mismo en ambas instancias, es decir que se han sincronizado después del Rejoin.

Switchover

Si todo está bien con el servidor Master original, tal vez querramos cambiar los roles Master-Esclavo a los que eran originalmente. Para esto tenemos que ejecutar manualmente el comando mariadbmon switchover:

pato@patocontainer ~/maxscale $ docker exec -it --user maxscale patomaxmsr bash
maxscale@9c7cf7ee2093:/$ maxctrl call command mariadbmon switchover Pato-Monitor Pato-Master Pato-Slave -t 600000
OK

maxscale@9c7cf7ee2093:/$ maxctrl list servers
+---------------------------------------------------------------------------+
¦ Server      ¦ Address     ¦ Port ¦ Connections ¦ State           ¦ GTID   ¦
+-------------+-------------+------+-------------+-----------------+--------¦
¦ Pato-Master ¦ patomariadb ¦ 3306 ¦ 0           ¦ Master, Running ¦ 0-1-48 ¦
+-------------+-------------+------+-------------+-----------------+--------¦
¦ Pato-Slave  ¦ patomariarp ¦ 3306 ¦ 0           ¦ Slave, Running  ¦ 0-1-48 ¦
+-------------+-------------+------+-------------+-----------------+--------+

Después del intercambio de roles podemos ver que el GTID ha cambiado de 0-11-# a 0-1-# (ya que el serverid de patomariadb es 1 y el de patomariarp es 11).

Conclusión

Hemos instalado exitosamente MaxScale en un contenedor Docker y y lo hemos configurado para monitorear y controlar a nuestro cluster Master Esclavo de MariaDB.

Al conectarnos a MariaDB a través de MaxScale aseguramos la Disponibilidad por la automatización de las actividades de Failover cuando algun nodo falla, y también nos ayuda con el Balanceo de Carga cuando todos los nodos están disponibles.