Ansible automatise et simplifie les opérations répétitives, complexes et fastidieuses. Il s'agit d'un moteur d'automatisation informatique qui automatise le provisionnement du cloud, la gestion de la configuration, le déploiement d'applications, l'orchestration intra-service et de nombreux autres besoins informatiques. Il ne nécessite aucun agent, utilise uniquement SSH pour transférer les modifications d'une source unique vers plusieurs ressources distantes sans configuration d'infrastructure de sécurité personnalisée supplémentaire et utilise un format de langage simple (YAML) pour décrire les tâches d'automatisation.
L'installation d'un serveur MySQL autonome est une tâche simple et directe, mais cela peut être problématique si vous avez plusieurs serveurs de base de données, versions, plates-formes et environnements à prendre en charge. Ainsi, disposer d'un outil de gestion de configuration est la voie à suivre pour améliorer l'efficacité, supprimer la répétitivité et réduire les erreurs humaines.
Dans cet article de blog, nous allons vous présenter les bases de l'automatisation d'Ansible pour MySQL, ainsi que la gestion de la configuration avec des exemples et des explications. Nous commencerons par un simple déploiement autonome de MySQL, comme illustré dans le schéma de haut niveau suivant :
Installer Ansible
Pour cette procédure pas à pas, nous avons besoin d'au moins deux hôtes - Un hôte est pour Ansible (vous pouvez utiliser un poste de travail au lieu d'un serveur) et un autre est l'hôte cible sur lequel nous voulons déployer un Serveur MySQL.
Pour installer Ansible sur CentOS 7, exécutez simplement les commandes suivantes :
(ansible-host)$ yum install -y epel-release
(ansible-host)$ yum install -y ansible
Pour les autres distributions de système d'exploitation, consultez le guide d'installation d'Ansible.
Configurer SSH sans mot de passe
L'utilisation d'un mot de passe pendant SSH est prise en charge, mais les clés SSH sans mot de passe avec ssh-agent sont l'un des meilleurs moyens d'utiliser Ansible. La première étape consiste à configurer SSH sans mot de passe car Ansible effectuera le déploiement uniquement par ce canal. Tout d'abord, générez une clé SSH sur l'hôte Ansible :
(ansible-host)$ whoami
root
(ansible-host)$ ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa
Vous devriez obtenir au moins les fichiers suivants générés :
(ansible-host)$ ls -al ~/.ssh/
-rw-------. 1 root root 1679 Jan 14 03:40 id_rsa
-rw-r--r--. 1 root root 392 Jan 14 03:40 id_rsa.pub
Pour autoriser SSH sans mot de passe, nous devons copier la clé publique SSH (id_rsa.pub) sur l'hôte distant auquel nous voulons accéder. Nous pouvons utiliser un outil appelé ssh-copy-id pour effectuer cette tâche pour nous. Cependant, vous devez connaître le mot de passe de l'utilisateur de l'hôte cible et l'authentification par mot de passe est autorisée sur l'hôte cible :
(ansible-host)$ whoami
root
(ansible-host)$ ssh-copy-id [email protected]
La commande ci-dessus vous demandera le mot de passe root de 192.168.0.221, entrez simplement le mot de passe et la clé SSH de l'utilisateur actuel de l'hôte Ansible sera copiée sur l'hôte cible, 192.168.0.221 dans ~/.ssh/authorized_keys, ce qui signifie que nous autorisons cette clé particulière à accéder à distance à ce serveur. Pour tester, vous devriez pouvoir exécuter la commande à distance suivante sans mot de passe depuis l'hôte Ansible :
(ansible-host)$ ssh [email protected] "hostname -I"
192.168.0.221
Dans le cas où vous n'êtes pas autorisé à utiliser l'utilisateur root pour SSH (par exemple, "PermitRootLogin no" dans la configuration SSH), vous pouvez utiliser un utilisateur sudo à la place. Dans l'exemple suivant, nous avons configuré SSH sans mot de passe pour un utilisateur sudo appelé "vagrant" :
(ansible-host)$ whoami
vagrant
(ansible-host)$ ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa
(ansible-host)$ ls -al ~/.ssh/
-rw-------. 1 vagrant vagrant 1679 Jan 14 03:45 id_rsa
-rw-r--r--. 1 vagrant vagrant 392 Jan 14 03:45 id_rsa.pub
(ansible-host)$ ssh-copy-id [email protected]
Si le serveur cible n'autorise pas l'authentification par mot de passe via SSH, copiez simplement le contenu de la clé publique SSH à ~/.ssh/id_rsa.pub manuellement dans ~/.ssh/authorized_keys des hôtes cibles dossier. Par exemple, sur l'hébergeur Ansible, récupérez le contenu de la clé publique :
(ansible-host)$ cat ~/.ssh/id_rsa.pub
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC5MZjufN0OiKyKa2OG0EPBEF/w23FnOG2x8qpAaYYuqHlVc+ZyRugtGm+TdTJDfLA1Sr/rtZpXmPDuLUdlAvPmmwqIhgiatKiDw5t2adNUwME0sVgAlBv/KvbusTTdtpFQ1o+Z9CltGiENDCFytr2nVeBFxImoZu2H0ilZed/1OY2SZejUviXTQ0Dh0QYdIeiQHkMf1CiV2sNYs8j8+ULV26OOKCd8c1h1O9M5Dr4P6kt8E1lVSl9hbd4EOHQmeZ3R3va5zMesLk1A+iadIGJCJNCVOA2RpxDHmmaX28zQCwrpCliH00g9iCRixlK+cB39d1coUWVGy7SeaI8bzfv3 [email protected]
Connectez-vous à l'hôte cible et collez la clé publique de l'hôte Ansible dans ~/.ssh/authorized_keys :
(target-host)$ whoami
root
(target-host)$ vi ~/.ssh/authorized_keys
ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC5MZjufN0OiKyKa2OG0EPBEF/w23FnOG2x8qpAaYYuqHlVc+ZyRugtGm+TdTJDfLA1Sr/rtZpXmPDuLUdlAvPmmwqIhgiatKiDw5t2adNUwME0sVgAlBv/KvbusTTdtpFQ1o+Z9CltGiENDCFytr2nVeBFxImoZu2H0ilZed/1OY2SZejUviXTQ0Dh0QYdIeiQHkMf1CiV2sNYs8j8+ULV26OOKCd8c1h1O9M5Dr4P6kt8E1lVSl9hbd4EOHQmeZ3R3va5zMesLk1A+iadIGJCJNCVOA2RpxDHmmaX28zQCwrpCliH00g9iCRixlK+cB39d1coUWVGy7SeaI8bzfv3 [email protected]
Vous pouvez maintenant essayer d'exécuter une commande à distance depuis l'hôte Ansible pour vérifier et aucun mot de passe ne devrait vous être demandé. À ce stade, notre SSH sans mot de passe est configuré.
Définir l'hôte cible
Ensuite, nous devons définir l'hôte cible, l'hôte que nous voulons gérer à l'aide d'Ansible. Sur la base de notre architecture, nous allons déployer un seul serveur MySQL qui est 192.168.0.221. Ajoutez les lignes suivantes dans /etc/ansible/hosts :
[db-mysql]
192.168.0.221
Ce qui précède signifie simplement que nous avons défini un groupe appelé "db-mysql", qui sera l'identifiant lorsque nous nous référerons à l'hôte cible dans Ansible playbook. Nous pouvons également répertorier toutes les adresses IP ou noms d'hôte des hôtes cibles sous ce groupe. À ce stade, nous n'avons qu'un seul serveur MySQL à déployer, donc une seule entrée est là. Vous pouvez également spécifier une règle de correspondance quelconque pour faire correspondre les hôtes d'un groupe, par exemple :
[db-mysql]
192.168.0.[221:223]
La définition ci-dessus signifie que nous avons 3 hôtes sous ce même groupe avec les adresses IP suivantes :
- 192.168.0.221
- 192.168.0.222
- 192.168.0.223
Il existe de nombreuses façons et règles pour faire correspondre et regrouper les hôtes cibles, comme indiqué dans le guide d'inventaire Ansible.
Choisir un rôle Ansible
Pour dire à Ansible ce qu'il faut déployer, nous devons définir les étapes de déploiement dans un fichier au format YML appelé playbook. Comme vous le savez peut-être, l'installation d'un serveur MySQL complet nécessite plusieurs étapes pour satisfaire toutes les dépendances MySQL, la configuration post-installation, la création d'utilisateurs et de schémas, etc. Ansible a fourni un certain nombre de modules MySQL qui peuvent nous aider, mais nous devons encore écrire un playbook pour les étapes de déploiement.
Pour simplifier les étapes de déploiement, nous pouvons utiliser les rôles Ansible existants. Le rôle Ansible est un composant indépendant qui permet de réutiliser les étapes de configuration courantes. Un rôle Ansible doit être utilisé dans le playbook. Il existe un certain nombre de rôles MySQL Ansible disponibles dans Ansible Galaxy, un référentiel pour les rôles Ansible qui peuvent être déposés directement dans vos playbooks.
Si vous recherchez "mysql", vous obtiendrez de nombreux rôles Ansible pour MySQL :
Nous utiliserons le plus populaire nommé "mysql" par geerlingguy. Vous pouvez choisir d'utiliser d'autres rôles, mais la plupart du temps, le plus téléchargé a tendance à être à usage général, ce qui fonctionne généralement bien dans la plupart des cas.
Sur l'hôte Ansible, exécutez la commande suivante pour télécharger le rôle Ansible :
(ansible-host)$ ansible-galaxy install geerlingguy.mysql
Le rôle sera téléchargé dans ~/.ansible/roles/geerlingguy.mysql/ de l'utilisateur actuel.
Rédaction du Playbook Ansible
En consultant le fichier Lisez-moi du rôle Ansible, nous pouvons suivre l'exemple de playbook fourni. Tout d'abord, créez un fichier playbook appelé deploy-mysql.yml et ajoutez les lignes suivantes :
(ansible-host)$ vim ~/deploy-mysql.yml
- hosts: db-mysql
become: yes
vars_files:
- vars/main.yml
roles:
- { role: geerlingguy.mysql }
Dans les lignes ci-dessus, nous définissons l'hôte cible qui est tous les hôtes sous les entrées db-mysql dans /etc/ansible/hosts. La ligne suivante (become) indique à Ansible d'exécuter le playbook en tant qu'utilisateur root, ce qui est nécessaire pour le rôle (il y est indiqué dans le fichier Readme). Ensuite, nous définissons l'emplacement du fichier de variables (var_files) situé à vars/main.yml, par rapport au chemin du playbook.
Créons le répertoire et le fichier de variables et spécifions la ligne suivante :
(ansible-host)$ mkdir vars
(ansible-host)$ vim vars/main.yml
mysql_root_password: "theR00tP455w0rd"
Pour plus d'informations, consultez la section Variables de rôle dans le fichier Lisez-moi de ce rôle.
Démarrer le déploiement
Nous sommes maintenant prêts à démarrer le déploiement de MySQL. Utilisez la commande ansible-playbook pour exécuter nos définitions de playbook :
(ansible-host)$ ansible-playbook deploy-mysql.yml
Vous devriez voir un tas de lignes apparaître dans la sortie. Concentrez-vous sur la dernière ligne où elle résume le déploiement :
PLAY RECAP ***************************************************************************************************************************************
192.168.0.221 : ok=36 changed=8 unreachable=0 failed=0 skipped=16 rescued=0 ignored=0
Si tout devient vert et OK, vous pouvez vérifier sur l'hébergeur de la base de données que notre serveur MySQL est déjà installé et en cours d'exécution :
(mysql-host)$ rpm -qa | grep -i maria
mariadb-server-5.5.64-1.el7.x86_64
mariadb-libs-5.5.64-1.el7.x86_64
mariadb-5.5.64-1.el7.x86_64
(mysql-host)$ mysqladmin -uroot -p ping
Enter password:
mysqld is alive
Comme vous pouvez le voir ci-dessus, pour CentOS 7, l'installation par défaut de MySQL est MariaDB 5.5 dans le cadre du référentiel de packages standard. À ce stade, notre déploiement est considéré comme terminé, cependant, nous aimerions personnaliser davantage notre déploiement, comme indiqué dans les sections suivantes.
Personnalisation du déploiement
La définition la plus simple dans Playbook nous donne une installation très basique et utilise toutes les options de configuration par défaut. Nous pouvons personnaliser davantage l'installation de MySQL en étendant/modifiant/ajoutant le playbook pour effectuer les opérations suivantes :
- modifier les options de configuration de MySQL
- ajouter un utilisateur de base de données
- ajouter un schéma de base de données
- configurer les privilèges utilisateur
- configurer la réplication MySQL
- installer MySQL d'autres fournisseurs
- importer un fichier de configuration MySQL personnalisé
Installer MySQL à partir du référentiel Oracle
Par défaut, le rôle installe le package MySQL par défaut fourni avec la distribution du système d'exploitation. Quant à CentOS 7, vous obtiendrez MariaDB 5.5 installé par défaut. Supposons que nous souhaitions installer MySQL à partir d'un autre fournisseur, nous pouvons étendre le playbook avec des pré_tâches, une tâche qu'Ansible exécute avant d'exécuter les tâches mentionnées dans un fichier .yml, comme illustré dans l'exemple suivant :
(ansible-host)$ vim deploy-mysql.yml
- hosts: db-mysql
become: yes
vars_files:
- vars/main.yml
roles:
- { role: geerlingguy.mysql }
pre_tasks:
- name: Install the MySQL repo.
yum:
name: http://repo.mysql.com/mysql-community-release-el7-5.noarch.rpm
state: present
when: ansible_os_family == "RedHat"
- name: Override variables for MySQL (RedHat).
set_fact:
mysql_daemon: mysqld
mysql_packages: ['mysql-server']
mysql_log_error: /var/lib/mysql/error.log
mysql_syslog_tag: mysqld
mysql_pid_file: /var/run/mysqld/mysqld.pid
mysql_socket: /var/lib/mysql/mysql.sock
when: ansible_os_family == "RedHat"
Exécutez le playbook :
(ansible-host)$ ansible-playbook deploy-mysql.yml
Ce qui précède installera MySQL à partir du référentiel Oracle à la place. La version par défaut que vous obtiendrez est MySQL 5.6. L'exécution du playbook ci-dessus sur un hôte cible qui a déjà une ancienne version de MySQL/MariaDB en cours d'exécution échouerait probablement en raison de l'incompatibilité.
Créer des bases de données et des utilisateurs MySQL
Dans vars/main.yml, nous pouvons définir la base de données MySQL et les utilisateurs que nous voulons qu'Ansible configure sur notre serveur MySQL en utilisant les modules mysql_database et mysql_users, juste après notre définition précédente sur mysql_root_password :
(ansible-host)$ vim vars/main.yml
mysql_root_password: "theR00tP455w0rd"
mysql_databases:
- name: myshop
encoding: latin1
collation: latin1_general_ci
- name: sysbench
encoding: latin1
collation: latin1_general_ci
mysql_users:
- name: myshop_user
host: "%"
password: mySh0pPassw0rd
priv: "myshop.*:ALL"
- name: sysbench_user
host: "192.168.0.%"
password: sysBenchPassw0rd
priv: "sysbench.*:ALL"
La définition demande à Ansible de créer deux bases de données, "myshop" et "sysbench", suivi de son utilisateur MySQL respectif avec les privilèges appropriés, l'hôte autorisé et le mot de passe.
Réexécutez le playbook pour appliquer la modification à notre serveur MySQL :
(ansible-host)$ ansible-playbook deploy-mysql.yml
Cette fois, Ansible récupérera toutes les modifications que nous avons apportées à vars/main.yml pour les appliquer à notre serveur MySQL. Nous pouvons vérifier sur le serveur MySQL avec les commandes suivantes :
(mysql-host)$ mysql -uroot -p -e 'SHOW DATABASES'
Enter password:
+--------------------+
| Database |
+--------------------+
| information_schema |
| myshop |
| mysql |
| performance_schema |
| sysbench |
+--------------------+
(mysql-host)$ mysql -uroot -p -e 'SHOW GRANTS FOR [email protected]"192.168.0.%"'
Enter password:
+------------------------------------------------------------------------------------------------------------------------+
| Grants for [email protected]% |
+------------------------------------------------------------------------------------------------------------------------+
| GRANT USAGE ON *.* TO 'sysbench_user'@'192.168.0.%' IDENTIFIED BY PASSWORD '*4AC2E8AD02562E8FAAF5A958DC2AEA4C47451B5C' |
| GRANT ALL PRIVILEGES ON `sysbench`.* TO 'sysbench_user'@'192.168.0.%' |
+------------------------------------------------------------------------------------------------------------------------+
Activation du journal des requêtes lentes
Ce rôle prend en charge l'activation du journal des requêtes lentes MySQL, nous pouvons définir l'emplacement du fichier journal ainsi que le temps de requête lente. Ajoutez les variables nécessaires dans le fichier vars/main.yml :
mysql_root_password: "theR00tP455w0rd"
mysql_databases:
- name: example_db
encoding: latin1
collation: latin1_general_ci
- name: sysbench
encoding: latin1
collation: latin1_general_ci
mysql_users:
- name: example_user
host: "%"
password: similarly-secure-password
priv: "example_db.*:ALL"
- name: sysbench_user
host: "192.168.0.%"
password: sysBenchPassw0rd
priv: "sysbench.*:ALL"
mysql_slow_query_log_enabled: true
mysql_slow_query_log_file: 'slow_query.log'
mysql_slow_query_time: '5.000000'
Exécutez à nouveau le playbook pour appliquer les modifications :
(ansible-host)$ ansible-playbook deploy-mysql.yml
Le playbook apportera les modifications nécessaires aux options liées aux requêtes lentes MySQL et redémarrera automatiquement le serveur MySQL pour charger les nouvelles configurations. Nous pouvons alors vérifier si les nouvelles options de configuration sont correctement chargées sur le serveur MySQL :
(mysql-host)$ mysql -uroot -p -e 'SELECT @@slow_query_log, @@slow_query_log_file, @@long_query_time'
+------------------+-----------------------+-------------------+
| @@slow_query_log | @@slow_query_log_file | @@long_query_time |
+------------------+-----------------------+-------------------+
| 1 | slow_query.log | 5.000000 |
+------------------+-----------------------+-------------------+
Incluant un fichier de configuration MySQL personnalisé
Les variables de rôle Ansible et les variables MySQL sont deux choses différentes. L'auteur de ce rôle a créé un certain nombre de variables liées à MySQL qui peuvent être représentées avec des variables de rôle Ansible. Extraits du fichier Lisez-moi, en voici quelques-uns :
mysql_port: "3306"
mysql_bind_address: '0.0.0.0'
mysql_datadir: /var/lib/mysql
mysql_socket: *default value depends on OS*
mysql_pid_file: *default value depends on OS*
mysql_log_file_group: mysql *adm on Debian*
mysql_log: ""
mysql_log_error: *default value depends on OS*
mysql_syslog_tag: *default value depends on OS*
Si la configuration générée ne satisfait pas nos exigences MySQL, nous pouvons inclure des fichiers de configuration MySQL personnalisés dans le déploiement en utilisant la variable mysql_config_include_files. Il accepte un tableau de valeurs séparées par une virgule, avec un "src" comme préfixe pour le chemin réel sur l'hôte Ansible.
Tout d'abord, nous devons préparer les fichiers de configuration personnalisés sur l'hôte Ansible. Créez un répertoire et un simple fichier de configuration MySQL :
(ansible-host)$ mkdir /root/custom-config/
(ansible-host)$ vim /root/custom-config/my-severalnines.cnf
[mysqld]
max_connections=250
log_bin=binlog
expire_logs_days=7
Disons que nous avons un autre fichier de configuration spécifiquement pour la configuration de mysqldump :
(ansible-host)$ vim /root/custom-config/mysqldump.cnf
[mysqldump]
max_allowed_packet=128M
Pour importer ces fichiers de configuration dans notre déploiement, définissez-les dans le tableau mysql_config_include_files dans le fichier vars/main.yml :
mysql_root_password: "theR00tP455w0rd"
mysql_databases:
- name: example_db
encoding: latin1
collation: latin1_general_ci
- name: sysbench
encoding: latin1
collation: latin1_general_ci
mysql_users:
- name: example_user
host: "%"
password: similarly-secure-password
priv: "example_db.*:ALL"
- name: sysbench_user
host: "192.168.0.%"
password: sysBenchPassw0rd
priv: "sysbench.*:ALL"
mysql_slow_query_log_enabled: true
mysql_slow_query_log_file: slow_query.log
mysql_slow_query_time: 5
mysql_config_include_files: [
src: '/root/custom-config/my-severalnines.cnf',
src: '/root/custom-config/mysqldump.cnf'
]
Notez que /root/custom-config/mysqld-severalnines.cnf et /root/custom-config/mysqldump.cnf existent à l'intérieur de l'hôte Ansible.
Réexécutez le playbook :
(ansible-host)$ ansible-playbook deploy-mysql.yml
Le playbook importera ces fichiers de configuration et les placera dans le répertoire d'inclusion (selon le système d'exploitation) qui est /etc/my.cnf.d/ pour CentOS 7. Le playbook redémarrera automatiquement le Serveur MySQL pour charger les nouvelles options de configuration. Nous pouvons alors vérifier si les nouvelles options de configuration sont correctement chargées :
(mysql-host)$ mysql -uroot -p -e 'select @@max_connections'
250
(mysql-host)$ mysqldump --help | grep ^max-allowed-packet
max-allowed-packet 134217728
Conclusion
Ansible peut être utilisé pour automatiser le déploiement de la base de données et la gestion de la configuration avec une petite connaissance des scripts. Pendant ce temps, ClusterControl utilise une approche SSH sans mot de passe similaire pour déployer, surveiller, gérer et faire évoluer votre cluster de base de données de A à Z, avec une interface utilisateur et ne nécessite aucune compétence supplémentaire pour obtenir le même résultat.