Esta publicación de blog es una continuación de MariaDB MaxScale Load Balancing en Docker:Implementación - Parte 1. En esta parte, nos centraremos más en las operaciones de administración con casos de uso avanzados como el control de servicios, la administración de configuraciones, el procesamiento de consultas, la seguridad y la reconciliación de clústeres. Los pasos de ejemplo y las instrucciones que se muestran en esta publicación se basan en los entornos de ejecución que hemos configurado en la primera parte de esta serie de blogs.
Control de servicios
Para MaxScale, iniciar y detener el contenedor es la única forma de controlar el servicio. Siempre que se haya creado el contenedor, podemos usar el siguiente comando para administrar el servicio:
$ docker start maxscale
$ docker stop maxscale
$ docker restart maxscale
Ejecución sin privilegios de raíz
Los contenedores de Docker se ejecutan de forma predeterminada con el privilegio de raíz, al igual que la aplicación que se ejecuta dentro del contenedor. Esta es otra preocupación importante desde la perspectiva de la seguridad porque los piratas informáticos pueden obtener acceso de root al host de Docker al piratear la aplicación que se ejecuta dentro del contenedor.
Para ejecutar Docker como usuario no root, debe agregar su usuario al grupo docker. En primer lugar, cree un grupo de ventanas acoplables si no hay uno:
$ sudo groupadd docker
Luego, agregue su usuario al grupo docker. En este ejemplo nuestro usuario es "vagabundo":
$ sudo usermod -aG docker vagrant
Cierre sesión y vuelva a iniciar sesión para que se vuelva a evaluar la pertenencia a su grupo (o reinicie si no funciona). En este punto, puede ejecutar el contenedor MaxScale con el comando de ejecución estándar (no se requiere sudo) como usuario "vagabundo":
$ docker run -d \
--name maxscale-unprivileged \
-p 4006:4006 \
-p 4008:4008 \
-p 8989:8989 \
-v $PWD/maxscale.cnf:/etc/maxscale.cnf \
mariadb/maxscale
El proceso MaxScale lo ejecuta el usuario "maxscale" y no requiere privilegios especiales hasta el nivel raíz. Por lo tanto, ejecutar el contenedor en modo sin privilegios siempre es la mejor manera si le preocupa la seguridad.
Gestión de la configuración
Para el contenedor MaxScale independiente, la administración de la configuración requiere la modificación del archivo de configuración asignado y luego el reinicio del contenedor MaxScale. Sin embargo, si está ejecutando como un servicio Docker Swarm, la nueva configuración debe cargarse en Swarm Configs como una nueva versión, por ejemplo:
$ cat maxscale.cnf | docker config create maxscale_config_v2 -
Luego, actualice el servicio eliminando las configuraciones antiguas (maxscale_config) y agregue la nueva (maxscale_config_v2) al mismo destino:
$ docker service update \
--config-rm maxscale_config \
--config-add source=maxscale_config_v2,target=/etc/maxscale.cnf \
maxscale-cluster
Docker Swarm luego programará la eliminación de contenedores y los procedimientos de reemplazo de un contenedor a la vez hasta que se cumpla el requisito de réplicas.
Actualizar y degradar
Una de las ventajas de ejecutar sus aplicaciones en Docker es el procedimiento trivial de actualización y degradación. Cada contenedor en ejecución se basa en una imagen, y esta imagen se puede cambiar fácilmente con la etiqueta de imagen. Para obtener la lista de imágenes disponibles para MaxScale, consulte la sección Etiquetas en Docker Hub. Los siguientes ejemplos muestran el proceso para degradar MaxScale 2.3 a una versión menor anterior, 2.2:
$ docker run -d \
--name maxscale \
-p 4006:4006 \
-p 4008:4008 \
-v $PWD/maxscale.cnf:/etc/maxscale.cnf \
mariadb/maxscale:2.3
$ docker rm -f maxscale
$ docker run -d \
--name maxscale \
-p 4006:4006 \
-p 4008:4008 \
-v $PWD/maxscale.cnf:/etc/maxscale.cnf \
mariadb/maxscale:2.2
Asegúrese de que las opciones de configuración sean compatibles con la versión que desea ejecutar. Por ejemplo, la degradación anterior fallaría en la primera ejecución debido a los siguientes errores:
2019-06-19 05:29:04.301 error : (check_config_objects): Unexpected parameter 'master_reconnection' for object 'rw-service' of type 'service', or 'true' is an invalid value for parameter 'master_reconnection'.
2019-06-19 05:29:04.301 error : (check_config_objects): Unexpected parameter 'delayed_retry' for object 'rw-service' of type 'service', or 'true' is an invalid value for parameter 'delayed_retry'.
2019-06-19 05:29:04.301 error : (check_config_objects): Unexpected parameter 'transaction_replay_max_size' for object 'rw-service' of type 'service', or '1Mi' is an invalid value for parameter 'transaction_replay_max_size'.
2019-06-19 05:29:04.302 error : (check_config_objects): Unexpected parameter 'transaction_replay' for object 'rw-service' of type 'service', or 'true' is an invalid value for parameter 'transaction_replay'.
2019-06-19 05:29:04.302 error : (check_config_objects): Unexpected parameter 'causal_reads_timeout' for object 'rw-service' of type 'service', or '10' is an invalid value for parameter 'causal_reads_timeout'.
2019-06-19 05:29:04.302 error : (check_config_objects): Unexpected parameter 'causal_reads' for object 'rw-service' of type 'service', or 'true' is an invalid value for parameter 'causal_reads'.
Lo que debemos hacer es eliminar las opciones de configuración no admitidas como se muestra arriba en el archivo de configuración antes de degradar la imagen del contenedor:
- reconexión_maestra
- reintento_retrasado
- transacción_reproducción
- causal_reads_timeout
- causal_reads
Finalmente, inicie el contenedor nuevamente y debería estar bien. La actualización de la versión para MaxScale funciona de manera similar. Simplemente cambie la etiqueta que desea usar y listo.
Filtros de escala máxima
MaxScale usa un componente llamado filter para manipular o procesar las solicitudes a medida que pasan por él. Hay un montón de filtros que puede usar, como se enumeran en esta página, MaxScale 2.3 Filters. Por ejemplo, una consulta específica se puede registrar en un archivo si coincide con un criterio o puede volver a escribir la consulta entrante antes de que llegue a los servidores back-end.
Para activar un filtro, debe definir una sección e incluir el nombre de la definición en la definición del servicio correspondiente, como se muestra en los ejemplos más abajo.
Registro de consultas de todo (QLA)
Como su nombre lo explica, el filtro QLA registra todas las consultas que coinciden con el conjunto de reglas por sesión de cliente. Todas las consultas se registrarán siguiendo el formato de la base de archivos.
En primer lugar, defina el componente con type=filter y module=qlafilter:
## Query Log All (QLA) filter
## Filter module for MaxScale to log all query content on a per client session basis
[qla-sbtest-no-pk]
type = filter
module = qlafilter
filebase = /tmp/sbtest
match = select.*from.*
exclude = where.*id.*
user = sbtest
Luego agregue el componente de filtro a nuestros servicios:
[rw-service]
...
filters = qla-sbtest-no-pk
[rr-service]
...
filters = qla-sbtest-no-pk
También es una buena idea mapear /tmp del contenedor con el directorio real en el host de Docker, de modo que no tengamos que acceder al contenedor para recuperar los archivos de registro generados. En primer lugar, cree un directorio y otorgue permiso de escritura global:
$ mkdir qla
$ chmod 777 qla
Dado que necesitamos vincular el directorio anterior al contenedor, debemos detener y eliminar el contenedor en ejecución y volver a ejecutarlo con el siguiente comando:
$ docker stop maxscale
$ docker run -d \
--name maxscale \
--restart always \
-p 4006:4006 \
-p 4008:4008 \
-p 8989:8989 \
-v $PWD/maxscale.cnf:/etc/maxscale.cnf \
-v $PWD/qla:/tmp \
mariadb/maxscale
Luego puede recuperar el contenido de las consultas registradas dentro del directorio qla:
$ cat qla/*
Date,[email protected],Query
2019-06-18 08:25:13,[email protected]::ffff:192.168.0.19,select * from sbtest.sbtest1
Reescritura de consultas
La reescritura de consultas es una función que, dependiendo de las consultas que se ejecuten en el servidor de la base de datos, permite aislar y corregir rápidamente las consultas problemáticas y mejorar el rendimiento.
La reescritura de consultas se puede hacer a través de regexfilter. Este filtro puede hacer coincidir o excluir declaraciones entrantes usando expresiones regulares y reemplazarlas con otra declaración. Cada regla se define en su propia sección e incluye el nombre de la sección en el servicio correspondiente para activarla.
El siguiente filtro coincidirá con una serie de comandos SHOW que no queremos exponer a los clientes de solo lectura:
## Rewrite query based on regex match and replace
[block-show-commands]
type = filter
module = regexfilter
options = ignorecase
match = ^show (variables|global variables|global status|status|processlist|full processlist).*
replace = SELECT 'Not allowed'
Luego podemos agregar el filtro al servicio que queremos aplicar. Por ejemplo, todas las conexiones de solo lectura deben filtrarse por lo anterior:
[rr-service]
...
filters = qla-sbtest-no-pk | block-show-commands
Tenga en cuenta que se pueden definir varios filtros utilizando una sintaxis similar a la tubería de shell de Linux "|" sintaxis. Reinicie el contenedor para aplicar los cambios de configuración:
$ docker restart maxscale
Entonces podemos verificar con la siguiente consulta:
$ mysql -usbtest -p -h192.168.0.200 -P4006 -e 'SHOW VARIABLES LIKE "max_connections"'
+-------------+
| Not allowed |
+-------------+
| Not allowed |
+-------------+
Obtendrá el resultado esperado.
Recuperación de clúster
MaxScale 2.2.2 y versiones posteriores admiten la replicación automática o manual de MariaDB o la recuperación de clústeres para los siguientes eventos:
- conmutación por error
- cambio
- volver a unirse
- restablecer replicación
La conmutación por error para el clúster maestro-esclavo puede y, a menudo, debe configurarse para que se active automáticamente. El cambio debe activarse manualmente a través de MaxAdmin, MaxCtrl o la interfaz REST. La reincorporación se puede establecer en automático o activarse manualmente. Estas funciones se implementan en el módulo "mariadbmon".
Los siguientes eventos automáticos de conmutación por error ocurrieron si deliberadamente apagamos el maestro activo, 192.168.0.91:
$ docker logs -f maxscale
...
2019-06-19 03:53:02.348 error : (mon_log_connect_error): Monitor was unable to connect to server mariadb1[192.168.0.91:3306] : 'Can't connect to MySQL server on '192.168.0.91' (115)'
2019-06-19 03:53:02.351 notice : (mon_log_state_change): Server changed state: mariadb1[192.168.0.91:3306]: master_down. [Master, Running] -> [Down]
2019-06-19 03:53:02.351 warning: (handle_auto_failover): Master has failed. If master status does not change in 4 monitor passes, failover begins.
2019-06-19 03:53:16.710 notice : (select_promotion_target): Selecting a server to promote and replace 'mariadb1'. Candidates are: 'mariadb2', 'mariadb3'.
2019-06-19 03:53:16.710 warning: (warn_replication_settings): Slave 'mariadb2' has gtid_strict_mode disabled. Enabling this setting is recommended. For more information, see https://mariadb.com/kb/en/library/gtid/#gtid_strict_mode
2019-06-19 03:53:16.711 warning: (warn_replication_settings): Slave 'mariadb3' has gtid_strict_mode disabled. Enabling this setting is recommended. For more information, see https://mariadb.com/kb/en/library/gtid/#gtid_strict_mode
2019-06-19 03:53:16.711 notice : (select_promotion_target): Selected 'mariadb2'.
2019-06-19 03:53:16.711 notice : (handle_auto_failover): Performing automatic failover to replace failed master 'mariadb1'.
2019-06-19 03:53:16.723 notice : (redirect_slaves_ex): Redirecting 'mariadb3' to replicate from 'mariadb2' instead of 'mariadb1'.
2019-06-19 03:53:16.742 notice : (redirect_slaves_ex): All redirects successful.
2019-06-19 03:53:17.249 notice : (wait_cluster_stabilization): All redirected slaves successfully started replication from 'mariadb2'.
2019-06-19 03:53:17.249 notice : (handle_auto_failover): Failover 'mariadb1' -> 'mariadb2' performed.
2019-06-19 03:53:20.363 notice : (mon_log_state_change): Server changed state: mariadb2[192.168.0.92:3306]: new_master. [Slave, Running] -> [Master, Running]
Una vez completada la conmutación por error, nuestra topología ahora se ve así:
Para la operación de conmutación, se requiere intervención humana y una forma de hacerlo a través de la consola MaxCtrl. Digamos que el antiguo maestro vuelve a estar operativo y está listo para ser promovido como maestro, podemos realizar la operación de cambio enviando el siguiente comando:
$ docker exec -it maxscale maxctrl
maxctrl: call command mariadbmon switchover monitor mariadb1 mariadb2
OK
Donde, el formato es:
$ call command <monitoring module> <operation> <monitoring section name> <new master> <current master>
Luego, verifique la nueva topología enumerando los servidores:
maxctrl: list servers
┌──────────┬──────────────┬──────┬─────────────┬─────────────────┬──────────────┐
│ Server │ Address │ Port │ Connections │ State │ GTID │
├──────────┼──────────────┼──────┼─────────────┼─────────────────┼──────────────┤
│ mariadb1 │ 192.168.0.91 │ 3306 │ 0 │ Master, Running │ 0-5001-12144 │
├──────────┼──────────────┼──────┼─────────────┼─────────────────┼──────────────┤
│ mariadb2 │ 192.168.0.92 │ 3306 │ 0 │ Slave, Running │ 0-5001-12144 │
├──────────┼──────────────┼──────┼─────────────┼─────────────────┼──────────────┤
│ mariadb3 │ 192.168.0.93 │ 3306 │ 0 │ Slave, Running │ 0-5001-12144 │
└──────────┴──────────────┴──────┴─────────────┴─────────────────┴──────────────┘
Acabamos de promocionar nuestro antiguo maestro a su lugar original. Dato curioso:la función de recuperación automática de ClusterControl hace exactamente lo mismo si está habilitada.
Reflexiones finales
La ejecución de MariaDB MaxScale en Docker brinda beneficios adicionales como la agrupación en clústeres de MaxScale, fácil de actualizar y degradar, y también funcionalidades avanzadas de proxy para clústeres de MySQL y MariaDB.