TX Printemps 2018 : Sauvegarde des bases de données et rotation

Les bases de données des services hébergés par l’association Picasoft constituent des ressources critiques dont il faut avoir des copies sur plusieurs jours en cas de corruption des données. Cette page de wiki explique les solutions techniques retenues afin de mettre en place un point de configuration unique en se basant sur le travail de la TX précédente, ainsi que l’implémentation d’un système de rotation des sauvegardes efficace favorisant la rétention des backups récentes au détriment des backups plus vieilles dont on gardera moins de copies.

Les conteneurs chargés d’effectuer la sauvegarde des services et la rotation des sauvegardes se nomment respectivement : pica-backup et backup-rotation. Un système de configuration centralisé entre les deux conteneurs a été écrit, afin de pouvoir en même temps définir un service à sauvegarder et configurer les rotations. Le fichier backupdata.json permet d’écrire cette configuration. Il se situe dans le dossier /DATA/docker/backupconfig de la VM hôte, que l’on monte ensuite comme volume au sein du conteneur accessible à /config/. On spécifie ce volume dans le fichier docker-compose.yml.

Voici un exemple de configuration pour le conteneur backup-rotation :

docker-compose.yml
backup-rotation:
    image: registry.picasoft.net:5000/backup-rotation
    container_name: backup-rotation
    volumes:
      - /DATA/BACKUP/:/backup
      - /DATA/docker/backup_config:/config/
      - /etc/localtime:/etc/localtime:ro
    restart: always

La configuration des conteneurs consiste à définir les services installés et les fréquences de rotation de leurs sauvegardes.

Exemple de fichier JSON :

backup_data.json
{
  "wekan":
    {
      "Host": "wekan-db",
      "Port": "27017",
      "Database": "wekan",
      "Type": "mongo",
      "Folder": "wekan",
      "Cron" : "0 * * * *",
      "Init-Backup" : "0",
      "Backup-Rota":
          {
              "Hour" : 24,
              "Day" : 7,
              "Week" : 4,
              "Month" : 12
          }
    },
  "etherpad":
    {
      "Host": "etherpad-db",
      "Port": "3306",
      "User": "root",
      "Password": "mot_de_passe",
      "Database": "--all-databases",
      "Type": "mysql",
      "Folder": "etherpad",
      "Cron" : "0 * * * *",
      "Options" : "--single-transaction",
      "Init-Backup" : "0",
      "Backup-Rota":
          {
              "Hour" : 24,
              "Day" : 7,
              "Week" : 4,
              "Month" : 12
          }
    }
}

Cette configuration indique que l’on souhaite effectuer la sauvegarde et de la rotation de sauvegarde pour deux services : wekan-db et etherpad-db. Chaque service peut définir un certain nombre d’attributs :

  • “Host”: nom du service indiqué dans le fichier docker-compose.yml ;
  • “Port”: port utilisé par le serveur de base de données ;
  • “User” : nom d’utilisateur pour se connecter à la base de données ;
    • “Password” : mot de passe de la base de données ;
    • “Database”: nom de la base de données ;
    • “Type”: type de la base de données (mongo, mysql, postgre);
    • “Folder”: nom du dossier de sauvegarde du service ;
    • “Cron” : indicateur de temps cron indiquant à quelle fréquence sont enregistrées les backups ;
    • “Backup-rota”: période de rotation voulue, il est possible de définir 4 paramètres Hour, Day, Week, Month.

    Sur les VM de production, le fichier de configuration se trouve dans le dossier /DATA/docker/backup_config.

Le conteneur de rotation des sauvegardes utilise le module Python rotate-backups. Ce module s’installe par l’intermédiaire de pip et s’utilise en ligne de commande. rotate-backups permet de définir des périodes de rotations selon les dernières minutes, heures, jours, semaines, mois et années par rapport à la date d’exécution de la commande. Par exemple, si on spécifie uniquement le paramètre heure -H :

rotate-backups -H 24

On indique alors à rotate-backups que l’on souhaite conserver la sauvegarde la plus récente (par défaut) sur chaque heure pendant les dernières 24h. Le module Python reconnaît le format de date dans le nom des fichiers de sauvegarde et les convertit automatiquement en objet Python datetime pour déterminer les sauvegardes à conserver.

Voici un autre exemple utilisant tous les paramètres de temps (sauf minutes) de la commande rotate-backups :

rotate-backups -H 24 -d 7 -w 4 -Y 2

L’interprétation de la commande est la suivante : on souhaite conserver la sauvegarde la plus récente effectuée sur chaque heure pendant les dernières 24h (on conserve 24 backups si on en a au moins une par heure) , la sauvegarde la plus récente effectuée chaque jour pendant les 7 derniers jours (on conserve 7 backups si on en a au moins une par jour), la sauvegarde la plus récente effectuée sur chaque semaine pendant les 4 dernières semaines (on conserve 4 backups si on en a au moins une par semaine), et enfin la sauvegarde la plus récente effectuée chaque année pendant les 2 dernières années (on en a au moins deux si on a réalisé au moins une sauvegarde par année).

Le rôle du conteneur backup-rotation est de créer une tâche cron horaire pour chaque service défini dans le fichier de configuration JSON avec les périodes de rotation spécifiées.

Le script fake_backups.py permet de générer des fichiers vides, ayant leurs noms formatés comme suit : AAAA-MM-JJHHmmSS et comportant l’extension .tar.gz. Ces fichiers permettent de simuler des sauvegardes effectuées par le conteneur backup-rotation sans utiliser inutilement de l’espace disque. Le script reçoit deux paramètres : -f pour indiquer le chemin absolu du dossier dans lequel générer les fichiers et -n afin d’indiquer le nombre de fichiers que l’on souhaite créer. À partir du paramètre -n le script crée le premier fichier en le nommant selon la date actuelle, puis remonte d’une heure dans le temps afin de nommer le reste des fichiers jusqu’à arriver au nombre de fichiers spécifié par le paramètre -n.

Exemple :

./fake_backups.py -f /root -n 4

Si le script est lancé le lundi 26 mars à 20h43 et 18s alors les fichiers suivants seront créés dans le dossier /root :

2018-03-26204318.tar.gz
2018-03-26194318.tar.gz
2018-03-26184318.tar.gz
2018-03-26174318.tar.gz

Pour tester ensuite le conteneur de rotation, il suffit d’indiquer le dossier dans lequel ont été générées les fausses backups dans le fichier backup_data.json en spécifiant les périodes de rotations voulues.

Exemple de configuration de test :

backup_data.json
{
"test_rotation":
    {
      "Folder": "test_rotation", # Dossier /DATA/BACKUP/test_rotation/
      "Backup-Rota":
          {
              "Hour" : 24,
              "Day" : 7,
              "Week" : 4,
              "Month" : 12
          }
    }
}      

Les instructions permettant de restaurer une base de données pour un service se situent ici.

/!\ Le conteneur réalisant les sauvegardes des bases de données se nomme désormais : db-backup.

  • txs/infra/backups_p18/backup-bdd.txt
  • de 127.0.0.1