MariaDB MaxScale est un proxy de base de données plug-in avancé pour les serveurs de base de données MariaDB. Il se situe entre les applications clientes et les serveurs de base de données, acheminant les requêtes des clients et les réponses des serveurs. MaxScale surveille également les serveurs, de sorte qu'il remarquera rapidement tout changement dans l'état du serveur ou la topologie de réplication. Cela fait de MaxScale un choix naturel pour contrôler le basculement et les fonctionnalités similaires.
Dans cette série de blogs en deux parties, nous allons expliquer en détail comment exécuter MariaDB MaxScale sur Docker. Cette partie couvre le déploiement en tant que conteneur Docker autonome et le clustering MaxScale via Docker Swarm pour une haute disponibilité.
MariaDB MaxScale sur Docker
Il existe un certain nombre d'images MariaDB Docker disponibles dans Docker Hub. Dans ce blog, nous allons utiliser l'image officielle maintenue et publiée par MariaDB appelée "mariadb/maxscale" (tag :latest). L'image fait environ 71 Mo. Au moment de la rédaction, l'image est préinstallée avec MaxScale 2.3.4 dans le cadre de ses packages requis.
Généralement, les étapes suivantes sont nécessaires pour exécuter un MaxScale avec cette image sur un environnement de conteneur :
- Une réplication MariaDB (maître-esclave ou maître-maître)/Galera Cluster ou NDB Cluster en cours d'exécution
- Créer et attribuer un utilisateur de base de données dédié à la surveillance MaxScale
- Préparer le fichier de configuration MaxScale
- Mappez le fichier de configuration dans le conteneur ou chargez-le dans Kubernetes ConfigMap ou Docker Swarm Configs
- Démarrer le conteneur/pod/service/réplicaset
Notez que MaxScale est un produit de MariaDB, ce qui signifie qu'il est adapté au serveur MariaDB. La plupart des fonctionnalités sont toujours compatibles avec MySQL, à l'exception de certaines parties comme par exemple la gestion des GTID, la configuration de Galera Cluster et les fichiers de données internes. La version que nous allons utiliser est la 2.3.4, qui est publiée sous Business Source License (BSL). Il permet à tout le code d'être ouvert et l'utilisation sous TROIS serveurs est gratuite. Lorsque l'utilisation dépasse trois serveurs principaux, l'entreprise qui l'utilise doit payer un abonnement commercial. Après une période de temps spécifique (2 ans dans le cas de MaxScale), la version passe en GPL et toute utilisation est gratuite.
Juste pour être clair, puisqu'il s'agit d'un environnement de test, nous pouvons avoir plus de 2 nœuds. Comme indiqué dans la page FAQ de MariaDB BSL :
Q :Puis-je utiliser les produits MariaDB sous licence BSL dans un environnement de test et de développement ?
R :Oui, dans un environnement de test et de développement hors production, vous pouvez utiliser des produits sous licence BSL sans avoir besoin d'un abonnement auprès de MariaDB
Dans cette procédure pas à pas, nous avons déjà déployé une réplication MariaDB à trois nœuds à l'aide de ClusterControl. Le schéma suivant illustre la configuration que nous allons déployer :
Notre architecture système se compose de :
- mariadb1 - 192.168.0.91 (maître)
- mariadb2 - 192.168.0.92 (esclave)
- mariadb3 - 192.168.0.93 (esclave)
- docker1 - 192.168.0.200 (Hôte Docker pour conteneurs - maxscale, app)
Préparer l'utilisateur MaxScale
Tout d'abord, créez un utilisateur de base de données MySQL pour MaxScale et autorisez tous les hôtes du réseau 192.168.0.0/24 :
MariaDB> CREATE USER 'maxscale'@'192.168.0.%' IDENTIFIED BY 'my_s3cret';
Ensuite, accordez les privilèges requis. Si vous souhaitez simplement surveiller les serveurs principaux avec équilibrage de charge, les autorisations suivantes suffiraient :
MariaDB> GRANT SHOW DATABASES ON *.* TO 'maxscale'@'192.168.0.%';
MariaDB> GRANT SELECT ON `mysql`.* TO 'maxscale'@'192.168.0.%';
Cependant, MaxScale peut faire bien plus que router des requêtes. Il a la capacité d'effectuer un basculement et une commutation, par exemple la promotion d'un esclave en un nouveau maître. Cela nécessite les privilèges SUPER et REPLICATION CLIENT. Si vous souhaitez utiliser cette fonctionnalité, attribuez plutôt TOUS LES PRIVILÈGES à l'utilisateur :
mysql> GRANT ALL PRIVILEGES ON *.* TO [email protected]'192.168.0.%';
C'est tout pour la partie utilisateur.
Préparation du fichier de configuration MaxScale
L'image nécessite qu'un fichier de configuration fonctionnel soit mappé dans le conteneur avant son démarrage. Le fichier de configuration minimal fourni dans le conteneur ne va pas nous aider à construire le proxy inverse que nous voulons. Par conséquent, le fichier de configuration doit être préparé au préalable.
La liste suivante peut nous aider à collecter les informations de base requises pour construire notre fichier de configuration :
- Type de cluster - MaxScale prend en charge la réplication MariaDB (maître-esclave, maître-maître), Galera Cluster, Amazon Aurora, MariaDB ColumnStore et NDB Cluster (aka MySQL Cluster).
- Adresse IP et/ou nom d'hôte du backend :adresse IP ou nom d'hôte accessible pour tous les serveurs backend.
- Algorithme de routage :MaxScale prend en charge deux types de routage des requêtes :le fractionnement lecture-écriture et l'équilibrage de charge en tourniquet.
- Port d'écoute par MaxScale :par défaut, MaxScale utilise le port 4006 pour les connexions circulaires et le port 4008 pour les connexions fractionnées en lecture-écriture. Vous pouvez utiliser le socket UNIX si vous le souhaitez.
Dans le répertoire courant, créez un fichier texte appelé maxscale.cnf afin que nous puissions le mapper dans le conteneur au démarrage. Collez les lignes suivantes dans le fichier :
########################
## Server list
########################
[mariadb1]
type = server
address = 192.168.0.91
port = 3306
protocol = MariaDBBackend
serv_weight = 1
[mariadb2]
type = server
address = 192.168.0.92
port = 3306
protocol = MariaDBBackend
serv_weight = 1
[mariadb3]
type = server
address = 192.168.0.93
port = 3306
protocol = MariaDBBackend
serv_weight = 1
#########################
## MaxScale configuration
#########################
[maxscale]
threads = auto
log_augmentation = 1
ms_timestamp = 1
syslog = 1
#########################
# Monitor for the servers
#########################
[monitor]
type = monitor
module = mariadbmon
servers = mariadb1,mariadb2,mariadb3
user = maxscale
password = my_s3cret
auto_failover = true
auto_rejoin = true
enforce_read_only_slaves = 1
#########################
## Service definitions for read/write splitting and read-only services.
#########################
[rw-service]
type = service
router = readwritesplit
servers = mariadb1,mariadb2,mariadb3
user = maxscale
password = my_s3cret
max_slave_connections = 100%
max_sescmd_history = 1500
causal_reads = true
causal_reads_timeout = 10
transaction_replay = true
transaction_replay_max_size = 1Mi
delayed_retry = true
master_reconnection = true
master_failure_mode = fail_on_write
max_slave_replication_lag = 3
[rr-service]
type = service
router = readconnroute
servers = mariadb1,mariadb2,mariadb3
router_options = slave
user = maxscale
password = my_s3cret
##########################
## Listener definitions for the service
## Listeners represent the ports the service will listen on.
##########################
[rw-listener]
type = listener
service = rw-service
protocol = MariaDBClient
port = 4008
[ro-listener]
type = listener
service = rr-service
protocol = MariaDBClient
port = 4006
Un peu d'explications pour chaque section :
- Liste des serveurs :les serveurs principaux. Définissez chaque serveur MariaDB de ce cluster dans sa propre strophe. Le nom de la strophe sera utilisé lorsque nous spécifierons la définition de service plus bas. Le type de composant doit être "serveur".
- Configuration MaxScale – Définissez-y toutes les configurations liées à MaxScale.
- Module de surveillance :comment MaxScale doit surveiller les serveurs principaux. Le type de composant doit être "moniteur" suivi de l'un ou l'autre des modules de surveillance. Pour la liste des moniteurs pris en charge, reportez-vous à MaxScale 2.3 Monitors.
- Service :où acheminer la requête. Le type de composant doit être "service". Pour la liste des routeurs pris en charge, reportez-vous à Routeurs MaxScale 2.3.
- Listener - Comment MaxScale doit écouter les connexions entrantes. Il peut s'agir d'un port ou d'un fichier socket. Le type de composant doit être "écouteur". Généralement, les auditeurs sont liés aux services.
Donc, fondamentalement, nous aimerions que MaxScale écoute sur deux ports, 4006 et 4008. Le port 4006 est spécifiquement destiné à la connexion circulaire, adapté aux charges de travail en lecture seule pour notre réplication MariaDB, tandis que le port 4008 est spécifiquement destiné aux charges de travail critiques de lecture et d'écriture. Nous souhaitons également utiliser MaxScale pour effectuer une action sur notre réplication en cas de basculement, de basculement ou de réintégration d'esclaves. Nous utilisons donc le module de surveillance appelé "mariadbmon".
Exécuter le conteneur
Nous sommes maintenant prêts à exécuter notre conteneur MaxScale autonome. Mappez le fichier de configuration avec -v et assurez-vous de publier les deux ports d'écoute 4006 et 4008. Vous pouvez éventuellement activer l'interface API REST MaxScale sur le port 8989 :
$ docker run -d \
--name maxscale \
--restart always \
-p 4006:4006 \
-p 4008:4008 \
-p 8989:8989 \
-v $PWD/maxscale.cnf:/etc/maxscale.cnf \
mariadb/maxscale
Vérifiez avec :
$ docker logs -f maxscale
...
2019-06-14 07:15:41.060 notice : (main): Started REST API on [127.0.0.1]:8989
2019-06-14 07:15:41.060 notice : (main): MaxScale started with 8 worker threads, each with a stack size of 8388608 bytes.
Assurez-vous de ne voir aucune erreur lorsque vous consultez les journaux ci-dessus. Vérifiez si les processus docker-proxy écoutent sur les ports publiés - 4006, 4008 et 8989 :
$ netstat -tulpn | grep docker-proxy
tcp6 0 0 :::8989 :::* LISTEN 4064/docker-proxy
tcp6 0 0 :::4006 :::* LISTEN 4092/docker-proxy
tcp6 0 0 :::4008 :::* LISTEN 4078/docker-proxy
À ce stade, notre MaxScale est en cours d'exécution et capable de traiter les requêtes.
MaxCtrl
MaxCtrl est un client d'administration en ligne de commande pour MaxScale qui utilise l'API MaxScale REST pour la communication. Il est destiné à remplacer le logiciel de l'ancien client de ligne de commande MaxAdmin.
Pour entrer dans la console MaxCtrl, exécutez la commande "maxctrl" à l'intérieur du conteneur :
$ docker exec -it maxscale maxctrl
maxctrl: list servers
┌──────────┬──────────────┬──────┬─────────────┬─────────────────┬─────────────┐
│ Server │ Address │ Port │ Connections │ State │ GTID │
├──────────┼──────────────┼──────┼─────────────┼─────────────────┼─────────────┤
│ mariadb1 │ 192.168.0.91 │ 3306 │ 0 │ Master, Running │ 0-5001-1012 │
├──────────┼──────────────┼──────┼─────────────┼─────────────────┼─────────────┤
│ mariadb2 │ 192.168.0.92 │ 3306 │ 0 │ Slave, Running │ 0-5001-1012 │
├──────────┼──────────────┼──────┼─────────────┼─────────────────┼─────────────┤
│ mariadb3 │ 192.168.0.93 │ 3306 │ 0 │ Slave, Running │ 0-5001-1012 │
└──────────┴──────────────┴──────┴─────────────┴─────────────────┴─────────────┘
Pour vérifier si tout va bien, exécutez simplement les commandes suivantes :
maxctrl: list servers
maxctrl: list services
maxctrl: list filters
maxctrl: list sessions
Pour obtenir plus d'informations sur chaque composant, préfixez plutôt la commande "show", par exemple :
maxctrl: show servers
┌──────────────────┬──────────────────────────────────────────┐
│ Server │ mariadb3 │
├──────────────────┼──────────────────────────────────────────┤
│ Address │ 192.168.0.93 │
├──────────────────┼──────────────────────────────────────────┤
│ Port │ 3306 │
├──────────────────┼──────────────────────────────────────────┤
│ State │ Slave, Running │
├──────────────────┼──────────────────────────────────────────┤
│ Last Event │ new_slave │
├──────────────────┼──────────────────────────────────────────┤
│ Triggered At │ Mon, 17 Jun 2019 08:57:59 GMT │
├──────────────────┼──────────────────────────────────────────┤
│ Services │ rw-service │
│ │ rr-service │
├──────────────────┼──────────────────────────────────────────┤
│ Monitors │ monitor │
├──────────────────┼──────────────────────────────────────────┤
│ Master ID │ 5001 │
├──────────────────┼──────────────────────────────────────────┤
│ Node ID │ 5003 │
├──────────────────┼──────────────────────────────────────────┤
│ Slave Server IDs │ │
├──────────────────┼──────────────────────────────────────────┤
│ Statistics │ { │
│ │ "connections": 0, │
│ │ "total_connections": 0, │
│ │ "persistent_connections": 0, │
│ │ "active_operations": 0, │
│ │ "routed_packets": 0, │
│ │ "adaptive_avg_select_time": "0ns" │
│ │ } │
├──────────────────┼──────────────────────────────────────────┤
│ Parameters │ { │
│ │ "address": "192.168.0.93", │
│ │ "protocol": "MariaDBBackend", │
│ │ "port": 3306, │
│ │ "extra_port": 0, │
│ │ "authenticator": null, │
│ │ "monitoruser": null, │
│ │ "monitorpw": null, │
│ │ "persistpoolmax": 0, │
│ │ "persistmaxtime": 0, │
│ │ "proxy_protocol": false, │
│ │ "ssl": "false", │
│ │ "ssl_cert": null, │
│ │ "ssl_key": null, │
│ │ "ssl_ca_cert": null, │
│ │ "ssl_version": "MAX", │
│ │ "ssl_cert_verify_depth": 9, │
│ │ "ssl_verify_peer_certificate": true, │
│ │ "disk_space_threshold": null, │
│ │ "type": "server", │
│ │ "serv_weight": "1" │
│ │ } │
└──────────────────┴──────────────────────────────────────────┘
Connexion à la base de données
L'utilisateur de la base de données de l'application doit être autorisé avec l'hôte MaxScale puisque du point de vue du serveur MariaDB, il ne peut voir que l'hôte MaxScale. Considérez l'exemple suivant sans MaxScale dans l'image :
- Nom de la base de données :monapplication
- Utilisateur :myapp_user
- Hôte :192.168.0.133 (serveur d'applications)
Pour permettre à l'utilisateur d'accéder à la base de données à l'intérieur du serveur MariaDB, il faut exécuter l'instruction suivante :
MariaDB> CREATE USER 'myapp_user'@'192.168.0.133' IDENTIFIED BY 'mypassword';
MariaDB> GRANT ALL PRIVILEGES ON myapp.* to 'myapp_user'@'192.168.0.133';
Avec MaxScale dans l'image, il faut exécuter l'instruction suivante à la place (remplacez l'adresse IP du serveur d'applications par l'adresse IP MaxScale, 192.168.0.200) :
MariaDB> CREATE USER 'myapp_user'@'192.168.0.200' IDENTIFIED BY 'mypassword';
MariaDB> GRANT ALL PRIVILEGES ON myapp.* to 'myapp_user'@'192.168.0.200';
Depuis l'application, vous pouvez utiliser deux ports pour vous connecter à la base de données :
- 4006 :écouteur circulaire, adapté aux charges de travail en lecture seule.
- 4008 – Écouteur fractionné en lecture-écriture, adapté aux charges de travail d'écriture.
Si votre application est autorisée à spécifier un seul port MySQL (par exemple, Wordpress, Joomla, etc.), choisissez plutôt le port RW 4008. Il s'agit de la connexion de point de terminaison la plus sûre, quel que soit le type de cluster. Cependant, si votre application peut gérer les connexions à plusieurs ports MySQL, vous pouvez envoyer les lectures à l'écouteur round-robin. Cet écouteur a moins de temps système et est beaucoup plus rapide par rapport à l'écouteur divisé en lecture-écriture.
Pour notre configuration de réplication MariaDB, connectez-vous à l'un de ces points de terminaison en tant que combinaison hôte/port de base de données :
- 192.168.0.200 port 4008 - MaxScale - lecture/écriture ou écriture seule
- 192.168.0.200 port 4006 - MaxScale - lecture seule équilibrée
- 192.168.0.91 port 3306 - Serveur MariaDB (maître) - lecture/écriture
- 192.168.0.92 port 3306 - Serveur MariaDB (esclave) - lecture seule
- 192.168.0.93 port 3306 - Serveur MariaDB (esclave) - lecture seule
Remarque pour le type de cluster multi-maître comme Galera Cluster et NDB Cluster, le port 4006 peut être utilisé à la place comme connexions équilibrées multi-écritures. Avec MaxScale, vous avez le choix entre de nombreuses options lors de la connexion à la base de données, chacune d'entre elles offrant son propre ensemble d'avantages.
Clustering MaxScale avec Docker Swarm
Avec Docker Swarm, nous pouvons créer un groupe d'instances MaxScale via le service Swarm avec plus d'un réplica avec Swarm Configs. Tout d'abord, importez le fichier de configuration dans Swarm :
$ cat maxscale.conf | docker config create maxscale_config -
Vérifiez avec :
$ docker config inspect --pretty maxscale_config
Ensuite, autorisez l'utilisateur de la base de données MaxScale à se connecter depuis n'importe quel hôte Swarm du réseau :
MariaDB> CREATE USER 'maxscale'@'192.168.0.%' IDENTIFIED BY 'my_s3cret';
MariaDB> GRANT ALL PRIVILEGES ON *.* TO [email protected]'192.168.0.%';
Lors du démarrage du service Swarm pour MaxScale, nous pouvons créer plusieurs conteneurs (appelés répliques) mappés sur le même fichier de configuration comme ci-dessous :
$ docker service create \
--name maxscale-cluster \
--replicas=3 \
--publish published=4008,target=4008 \
--publish published=4006,target=4006 \
--config source=maxscale_config,target=/etc/maxscale.cnf \
mariadb/maxscale
Ce qui précède créera trois conteneurs MaxScale répartis sur les nœuds Swarm. Vérifiez avec :
$ docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
yj6u2xcdj7lo maxscale-cluster replicated 3/3 mariadb/maxscale:latest *:4006->4006/tcp, *:4008->4008/tcp
Si les applications s'exécutent sur le réseau Swarm, vous pouvez simplement utiliser le nom de service "maxscale-cluster" comme hôte de base de données pour vos applications. En externe, vous pouvez vous connecter à n'importe quel hôte Docker sur les ports publiés et le réseau Swarm acheminera et équilibrera les connexions vers les conteneurs appropriés de manière circulaire. À ce stade, notre architecture peut être illustrée comme suit :
Dans la deuxième partie, nous allons examiner des cas d'utilisation avancés de MaxScale sur Docker comme le contrôle des services, la gestion de la configuration, le traitement des requêtes, la sécurité et la réconciliation des clusters.