Installation d’un cluster MariaDB Galera avec Ansible

Mise en place d'un cluster MariaDB par automatisation avec Ansible

Un cluster MySQL multi-maître cohérent et à haute disponibilité !

MariaDB est le fork open-source de MySQL.
Nativement, MariaDB propose un système de réplication mais la réplication peut pauser quelques soucis de synchronisation et provoquer des base de données incohérentes.
Le système de Galera permet de résoudre ce problème (parmis d’autres) en gérant un système de « Quorum » entre les noeuds de sorte à ce que tous les noeuds soient cohérents. Il faut un minimum de 3 noeuds pour lancer le quorum, il est ensuite possible d’ajouter ou d’enlever autant de noeuds que nécessaire au bon fonctionnement de l’application.

Installation en 5 minutes grâce à Ansible

Ansible permet d’automatiser des tâches systèmes et de les « jouer » sur un groupe de machines. Il a pour avantage de ne dépendre d’aucun client/agent sur la machine cible et sa prise en main est assez simple. Ansible à été racheté par Red Hat en Octobre 2015

Ansible n’a pas besoin de client car fonctionne avec SSH. La première étape consiste donc à vérifier la connexion SSH vers nos machines fonctionne et si possible, à l’aide de clés. Ansible propose de faire un « ping » les hôtes avec une commande simple, en réalité il s’agit d’une connexion SSH vers le client.

ansible@deployment:~/.ssh$ ansible 10.0.0.51 -m ping -u root
10.0.0.51 | success >> {
    "changed": false, 
    "ping": "pong"
}

Ici, les machines sont de containers OpenVZ faisant tourner Debian 7 (Wheezy). On va « fixer » dans notre rôle, le repository de MariaDB à utiliser pour l’installation mais on peut aboutir à un rôle pour plusieurs version de Debian et/ou autres.
La mise en place du cluster est assez simple : on part du principe que la partie routing réseau et gestion des accès est faite. Il faut installer le paquet mariadb-galera-server sur les 3 machines et créer le fichier de configuration spécifique au cluster Galera.

Création du rôle et structure des dossiers

Dans Ansible, un rôle est une succession de tâches à faire sur un hôte. J’ai donc créé le rôle « mariadb-galera » avec l’arborescence suivante :

roles/
  mariadb-galera/
    defaults/
      main.yml  # Fichier contenant les variables propres au rôle
    tasks/
      main.yml  # Fichier listant les tâches à lancer sur les serveurs
    templates/
      etc/
        mysql/
          conf.d/
            galera.cnf.jd2  # Fichier de configuration spécifique à Galera.

La structure des dossiers de templates représente la structure attendu sur la machine cible mais c’est le tâches qui définissent où seront copiés les templates.

Définition du repository de MariaDB sur nos machines

Le fichier suivant sert de conteneur de variables. J’y ajoute les références pour le repository de MariaDB dans sa branche 5.5 :

---
mariadb_55_wheezy:
  repo : 'deb [arch=amd64,i386] http://ftp.igh.cnrs.fr/pub/mariadb/repo/5.5/debian wheezy main'
  keyserver : 'keyserver.ubuntu.com'
  key : '0xcbcb082a1bb943db'

Tâches d’installation de MariaDB Galera sur les noeuds

Le fichier suivant correspond aux tâches à effectuer pour installer le rôle « mariadb-galera » sur les machines. Il s’agit d’une succession de commandes, finalement très proche de ce que l’on retrouve dans un Dockerfile lorsque l’on créer un container Docker.

---
- name: Add MariaDB APT GPG key
  apt_key:
    state: 'present'
    id: '{{ mariadb_55_wheezy[key] }}'
    keyserver: '{{ mariadb_55_wheezy[keyserver] }}'

- name: Add MariaDB APT repository
  apt_repository:
    repo: '{{  mariadb_55_wheezy[repo] }}'
    state: 'present'
    update_cache: True

- name: Install mariadb galera server
  apt: pkg={{ item }} state=latest
  with_items:
    - python-software-properties
    - rsync
    - galera
    - mariadb-galera-server

- name: Setup galera default configuration
  template: 
    src: 'etc/mysql/conf.d/galera.cnf.j2'
    dest: '/etc/mysql/conf.d/galera.cnf'
    owner: 'root'
    group: 'root'
    mode: '0644'

Le template de configuration galera.cnf.j2 ci-dessous permet de configurer les clients, il ne restera plus qu’a initier le cluster

[mysqld]
#mysql settings
binlog_format=ROW
default-storage-engine=innodb
innodb_autoinc_lock_mode=2
query_cache_size=0
query_cache_type=0
bind-address={{ansible_default_ipv4.address}}

#galera settings
wsrep_provider=/usr/lib/galera/libgalera_smm.so
wsrep_cluster_name="nodelia_cluster"
wsrep_node_address={{ansible_default_ipv4.address}}
wsrep_node_name={{ansible_hostname}}-{{ansible_default_ipv4.address}}
wsrep_cluster_address="gcomm://{% for host in groups['cluster_db_servers'] %}{{ hostvars[host]['ansible_default_ipv4']['address'] }},{% endfor %}" # when setup first node have to be set like this. Then add ip list comma separated
wsrep_sst_method=rsync

Il faut ensuite créer un playbook, il sera simplifié au maximum. Il consiste à appliquer le rôle « mariadb-galera » sur tous les hôtes. Voici le fichier :

---
- hosts: all
  roles:
    - mariadb-galera


Lancez le playbook a l'aide de la commande "ansible-playbook", vous verrez alors les tâches défiler dans votre terminal :

PLAY ***************************************************************************

TASK [setup] *******************************************************************
ok: [10.0.0.204]
ok: [10.0.0.206]
ok: [10.0.0.205]

...
TASK [mariadb-galera : Install mariadb galera server] **************************
changed: [10.0.0.204] => (item=[u'python-software-properties', u'rsync', u'galera', u'mariadb-galera-server'])
changed: [10.0.0.206] => (item=[u'python-software-properties', u'rsync', u'galera', u'mariadb-galera-server'])
changed: [10.0.0.205] => (item=[u'python-software-properties', u'rsync', u'galera', u'mariadb-galera-server'])
...
PLAY RECAP *********************************************************************
10.0.0.204                 : ok=13   changed=2    unreachable=0    failed=0   
10.0.0.205                 : ok=13   changed=2    unreachable=0    failed=0   
10.0.0.206                 : ok=13   changed=2    unreachable=0    failed=0 

Configuration du cluster

La dernière étape est de lancer le cluster. Tout d'abord, assurez vous que le service mysql est stoppé sur toutes les machines.
Ensuite, sur la première machine et de lancer la commande :

root@test-01$ service mysql stop && service mysql start --wsrep-new-cluster

Sous Debian, vous aurez des problèmes lorsque vous essayerez de démarrer le service sur les autres machines. Le "workaround" trouvé par MariaDB est de copier le contenu du fichier /etc/mysql/debian.cnf du premier nœud sur les autres : https://mariadb.org/installing-mariadb-galera-cluster-on-debian-ubuntu/

Vous voilà maintenant armé d'un système à haute disponibilité en très peu de temps. L'avantage de ce script est que l'ajout de client sera simplifié et ne nécéssite que peu d'intervention humaine. Encore une fois, le playbook est simplifié à son maximum. On peut imaginer que les actions humaines peuvent être remplacées par des tâches du rôle.

Nodelia

Consultant spécialisée dans le développement de sites e-commerce.

Devops / Freelance Magento / Optimisation


Zend Certified Engineer Magento Certified Developer