Il peut parfois être nécessaire d’avoir un proxy devant un ou plusieurs serveurs de bases de données. Même si la configuration ne comporte qu’un seul serveur, ce proxy peut alors être utilisé pour faire du cache de requêtes, du monitoring ou encore du routage.
Dans cette série d’article je vais parler de ProxySQL que j’ai découvert il y a quelques semaines, pourquoi je trouve que c’est un outil puissant pour beaucoup de cas d’usages et pourquoi – si vous cherchez un “routeur de requêtes” – il est intéressant d’y jeter un oeil.
Pour commencer, un lien vers [la documentation] plutôt bien faite de ProxySQL
Si vous utilisez un serveur Debian, l’outil est très facile à installer et tombe en marche à la fin de l’installation. Un grand merci aux développeurs de fournir un repo apt.
Installation sur un système Debian 11
Pour les besoin de cet article, je vais déployer ProxySQL sur un seul serveur. Comme c’est le premier d’une série, il y a fort à parier qu’une mise en cluster sera abordée tôt ou tard.
Hostname | IP |
---|---|
psql01 | 192.168.56.1 |
En suivant cette documentation, l’installation est rapide :
Copied!apt install -y --no-install-recommends lsb-release wget apt-transport-https ca-certificates gnupg wget -O - 'https://repo.proxysql.com/ProxySQL/proxysql-2.4.x/repo_pub_key' | apt-key add - echo deb https://repo.proxysql.com/ProxySQL/proxysql-2.4.x/$(lsb_release -sc)/ ./ | tee /etc/apt/sources.list.d/proxysql.list apt update apt install proxysql
Par défaut ProxySQL écoute sur 127.0.0.1:6032
pour son shell d’administration et sur 0.0.0.1:6033
pour les connexions MySQL entrantes. Il est possible de configurer ProxySQL à l’aide de fichiers de configuration situées dans /etc/proxysql
ou directement depuis le shell d’administration qui stockera la configuration en base de données.
Je préfère cette dernière possibilité, entre autres car elle permet de configurer l’outil, de charger la configuration dans le runtime et si tout est ok, de sauvegarder la configuration sur disque. Cette fonctionnalité est super intéressante car en cas de mauvaise configuration (sans avoir sauvegardé sur disque) il est tout à fait possible de restaurer une configuration fonctionnelle très rapidement.
Donc pour résumer, il y a 3 étapes pendant la configuration :
- Ecrire les règles et paramètres dans le shell d’administration.
- Charger ces règles dans le runtime.
- Sauvegarder ces règles sur disque pour les rendre permanente.
Première configuration
Comme vu précédemment, ProxySQL écoute sur deux ports différents :
- 6032 : Le shell d’administration
- 6033 : A lire de droite à gauche, c’est le port d’écoute pour les requêtes MySQL entrantes.
Comment se connecter à cette chose ?
Pour avoir accès au shell d’administration, il faut install le paquet mysql/mariadb client. Sur Debian 11 :
Copied!apt update apt install mariadb-client --no-install-recommends
Pour tester la connexion :
Copied!mysql -u admin -padmin -h localhost -P6032
Vous devriez être dans un shell type MySQL. Ctrl + C
pour sortir.
J’ai pour habitude d’ajouter un alias pour faciliter la connexion :
Copied!alias proxysqlshell='mysql -u admin -padmin -h 127.0.0.1 -P6032 --prompt ProxySQL\> '
Maintenant il suffit de taper proxysqlshell
dans le terminal pour avoir directement accès. Nous verrons sûrement plus tard comment “sécuriser” cet accès.
Et après ?
Une des première choses à faire, selon la doc ProxySQL, c’est de créer un utilisateur “monitoring” sur le noeud ProxySQL. Cet utilisateur servira à monitorer les serveurs de bases de données auxquels le proxy pourra se connecter. Cela lui permettra de garder un état des serveurs “backend”. Cet utilisateur devra donc exister sur tous les noeuds MySQL, avec ses propres privilèges.
Ci-dessous les commandes pour ajouter l’utilisateur à ProxySQL :
Copied!root@psql01:~# proxysqlshell
Copied!ProxySQL>UPDATE global_variables SET variable_value='psql-monitoring' WHERE variable_name='mysql-monitor_username'; ProxySQL>UPDATE global_variables SET variable_value='psql_monitoring-password' WHERE variable_name='mysql-monitor_password'; ProxySQL>LOAD MYSQL VARIABLES TO RUNTIME; ProxySQL>SAVE MYSQL VARIABLES TO DISK;
Ici nous avons configuré le compte monitoring psql-monitoring
et psql-monitoring-password
en mot de passe. On peut noter le LOAD TO RUNTIME
et SAVE TO DISK
qui sont deux commandes différentes mais toutes aussi importantes l’une que l’autre.
Maintenant il faut se connecter à tous les serveurs MySQL et ajouter cet utilisateur monitoring. Dans le cadre d’un setup master / slave, ne créer cet utilisateur que sur le master, la réplication se chargera de faire le reste 😉
Ci-dessous un exemple :
Copied!mysql> create user 'psql-monitoring'@'192.168.56.%' identified by 'psql-monitoring-password'; mysql> grant usage on *.* to 'psql-monitoring'@'192.168.56.%'; mysql> flush privileges;
Ici j’ai utilisé le %
wildcard MySQL. L’utilisation de ce wildcard est ok dans le cadre d’un lab. Dans un environnement de production, j’aurais probablement durci la configuration en spécifiant seulement les ip des ProxySQL.
Et mes applications là dedans ?
Pour ce premier article, on la joue KISS.
Nous avons deux serveurs MySQL distincts :
App | Db name | Ip | MySQL user | MySQL Password |
---|---|---|---|---|
Nextcloud | nextcloud_db | 192.168.56.3 | nextcloud_sql_admin | nextcloud_sql_pass |
GLPI | glpi_db | 192.168.56.4 | glpi_sql_admin | glpi_sql_pass |
La première chose à faire est d’ajouter ces serveurs à notre configuration ProxySQL :
Copied!insert into mysql_servers (hostgroup_id,hostname,port,comment) values (20,'192.168.56.3',3306,'Nextcloud db server'); insert into mysql_servers (hostgroup_id,hostname,port,comment) values (30,'192.168.56.4',3306,'Glpi db server'); load mysql servers to runtime; save mysql servers to disk;
Une nouvelle notion abordée : les hostgroups. Ces derniers sont très importants dans ProxySQL. Il s’agit d’un paramètre central de l’outil et en particulier du “système de routage” de ProxySQL. Dans le cadre d’un déploiement master / slave, un usage très basic mais qui fonctionne très très bien est d’ajouter le serveur dans un hostgroup spécifique, et tous les slaves dans un autre. Ainsi on pourra très facilement, basé sur le nom d’utilisateur, router du trafic à destination des slaves ou du master.
Pour l’instant j’ai simplement ajouté chaque serveur dans un hostgroup dédié.
Maintenant il faut ajouter les utilisateurs qui seront autorisés à se connecter depuis les applications clientes vers les serveurs de bases de données, au travers de ProxySQL. Ces utilisateur doivent donc exister sur les serveurs de base de données.
Il doit être possible de mapper des comptes frontend différents de comptes backend, pour ne pas avoir à toucher l’existant. Je n’ai pas l’usage mais à vérifier si nécessaire.
Copied!insert into mysql_users (username,password,active,default_hostgroup) values ('nextcloud_sql_admin','nextcloud_sql_pass',1,20); insert into mysql_users (username,password,active,default_hostgroup) values ('glpi_sql_admin','glpi_sql_pass',1,30); load mysql users to runtime; save mysql users to disk;
Maintenant, toutes les requêtes envoyées à ProxySQL avec les utilisateurs :
-
nextcloud_sql_admin
seront routées vers le hostgroup 20 : 192.168.56.3 : nextcloud_db -
glpi_sql_admin
seront routées vers le hostgroup 30 : 192.168.56.4 : glpi_db
Ok mais mes applicatifs parlent sur le port destination tcp/3306 et non pas 6033
La configuration par défaut de ProxySQL est d’écouter sur le port tcp/6033, tandis que MySQL écoute par défaut sur tcp/3306. Il est parfois impossible de changer ce port destination (certains applicatifs sont très rigides..). La meilleure solution est alors de modifier le port d’écoute de ProxSQL par le biais de la variable mysql-interfaces
en modifiant 0.0.0.0:6033
en 0.0.0.0:3306
Copied!update global_variables set variable_value='0.0.0.0:3306' where variable_name='mysql-interfaces'; save mysql variables to disk;
Vous pouvez maintenant vous connecter à votre ProxySQL directement avec les identifiants crées précédemment, sans avoir à préciser le port de destination :
Copied!mysql -u nextcloud_sql_admin -p -h 192.168.56.1
ProxySQL peut maintenant router vos requêtes en fonction du nom d’utilisateur présenté.
Enjoy 😄
Laisser un commentaire