← Tous les projets

Étude de cas

db-backup : plateforme de sauvegarde Redis & MySQL

Contribution à un projet existant, mise en production, puis responsabilité principale du service

2021 - 2025

Plateforme interne automatisant la sauvegarde, le stockage, la rétention, la validation et la restauration de bases MySQL et Redis sur Kubernetes.

Le contexte

Sauvegarder une base de données est un problème résolu. Sauvegarder des centaines de bases, de deux moteurs différents, réparties sur autant de serveurs, avec des politiques de rétention distinctes et l’obligation de prouver qu’une restauration fonctionne : c’est un problème d’architecture.

Avant db-backup, chaque équipe poussait ses sauvegardes par rsync vers des NAS partagés, chacun mutualisant plusieurs bases du même moteur (Redis ou MySQL) ; les NAS eux-mêmes étaient ensuite sauvegardés par NetBackup. Le système tenait, au prix d’environ 400 To répartis sur l’ensemble des NAS. Le problème ne se limitait pas au stockage. Il restait difficile de répondre à une question simple : Est-ce que la base de l’équipe X a été sauvegardée cette nuit, et sait-on la restaurer ? Quand la réponse dépend de qui est joignable, ce n’est plus une sauvegarde, c’est un espoir.

La décision : une API pour centraliser le service

Le réflexe naturel face à ce problème est d’écrire un script et de le déployer partout. Mais un ensemble de scripts distribués ne fournit pas à lui seul un état centralisé, cohérent et interrogeable des sauvegardes.

Pour savoir quelles sauvegardes existent, lesquelles ont échoué, quel espace de stockage elles occupent et si la rétention a bien été appliquée, il fallait centraliser le contrôle, les statuts et les opérations dans un service accessible aux équipes.

Le choix structurant retenu pour la plateforme était d’en faire un service, pas un simple outil. Une API REST constituait le point d’entrée unique ; playbooks, CLI, rotation et nettoyage s’appuyaient sur ce même contrat.

Ce que permet un contrat API commun

Le choix d’un contrat API commun évitait de dupliquer la logique de pilotage dans chaque interface. La CLI en Go consomme la même API que le tableau de bord. Le service a démarré avec Redis ; une fois stabilisé, la prise en charge de MySQL a réutilisé ce contrat, avec un playbook propre au moteur.

Comment ça marche

L’architecture sépare les interfaces, l’orchestration, l’exécution et le stockage avec son observabilité. Cette séparation a permis de migrer le stockage d’OpenStack vers Azure, puis le cluster vers AKS, en adaptant les composants concernés plutôt qu’en réécrivant toute la plateforme.

  1. Interfaces

    • API REST
    • CLI Go
    • Tableau de bord web
    • Swagger UI
  2. Orchestration

    • Kubernetes CronJobs
    • GitLab CI/CD
    • Sidecar monitor
  3. Exécution

    • Ansible Playbooks
    • Percona XtraBackup
    • RDB Redis
    • AzCopy
  4. Stockage & observabilité

    • Azure Blob Storage
    • Prometheus
    • Grafana
    • Kibana

Le déroulé d’une sauvegarde nocturne :

  1. Planification : un CronJob Kubernetes déclenche l’opération à l’heure prévue

  2. L’API reçoit la demande et enregistre l’intention avant toute exécution : c’est ce qui permet de diagnostiquer une panne plutôt que de la laisser passer inaperçue

  3. Lancement du conteneur Ansible, avec deux choses qui se déroulent en parallèle :

    • le sidecar surveille le job Kubernetes et notifie Slack/Teams
    • la sauvegarde s’exécute : XtraBackup pour MySQL, RDB pour Redis
  4. Upload vers Azure Blob Storage, accompagné d’un rapport YAML décrivant ce qui a réellement été produit

  5. Prometheus collecte les métriques exposées par les exporteurs

  6. Grafana et Kibana rendent l’état lisible sans se connecter à un serveur

Le pattern sidecar mérite un mot. Un job Kubernetes expose son statut, ses événements et ses logs, mais ces signaux ne suffisent pas à indiquer aux équipes à quelle étape l’opération a échoué. Le sidecar est un second conteneur, dans le même pod, qui observe le job et envoie des notifications Slack/Teams pendant son exécution. On peut ainsi passer de « le backup de cette nuit a échoué » à « le backup a échoué à l’étape d’upload, à 3 h 12, avec cette erreur ».

La plateforme que j’ai fait évoluer

J’ai rejoint db-backup alors que le projet existait déjà et était en cours de développement. J’ai contribué à la construction et à la mise en production de ses composants, puis pris la responsabilité principale du service après sa mise en production.

Les principaux composants se lisent par responsabilité dans le service, plutôt que comme un inventaire :

Contrôle et état : API REST

Python Django

Point d'entrée commun à la CLI et au tableau de bord : reçoit les demandes, déclenche les opérations et rend l'état des sauvegardes consultable.

Exécution et suivi : playbooks et sidecar

Ansible Python

Les playbooks exécutent les sauvegardes MySQL et Redis ; le sidecar suit les jobs Kubernetes et notifie les équipes en cas d'échec.

Cycle de vie des sauvegardes

Python Azure SDK

La rotation applique la rétention et retire les sauvegardes invalides ; le cleaner archive et supprime celles des serveurs décommissionnés.

Outils pour les équipes

Go

La CLI permet aux équipes infra et dev d'agir via l'API ; Usage Report donne une vue web en temps réel de l'état du stockage.

Déploiement et secrets

Helm Terraform GitLab CI

Déploiement multi-environnements et rotation automatique des secrets Azure et Vault.

Observabilité

Prometheus Grafana Kibana

Quatre exporteurs sur mesure et des tableaux de bord suivent la consommation de stockage et l'état des sauvegardes.

Deux choix méritent d’être soulignés parce qu’ils ne se voient pas dans une liste de technologies.

Les exporteurs Prometheus sont écrits sur mesure. Les métriques système seules ne répondaient pas à la question utile : non pas « le processus tourne », mais « la dernière sauvegarde valide de cette base date de moins de N heures ». Une métrique utile décrit l’état des sauvegardes, pas seulement celui du programme.

Les tests des playbooks utilisent de vraies machines, pas des simulations. Un pipeline GitLab CI/CD dédié, déclenché automatiquement chaque jour et chaque semaine, provisionne via Terraform des instances MySQL et Redis réelles, y restaure une sauvegarde existante avec la CLI db-backup, vérifie que la restauration a réellement fonctionné, puis relance une sauvegarde sur cette instance restaurée, avant de détruire l’infrastructure. Le cycle quotidien tourne sur une base de test ; le cycle hebdomadaire rejoue le même scénario à partir d’une sauvegarde de production, pour une validation plus proche des conditions réelles sans supporter ce coût tous les jours. Ces tests sur de vraies machines couvrent notamment l’état des machines cibles, que des playbooks simulés ne permettraient pas de valider.

Résultats

Le service, lancé sur OpenStack (stockage Swift), a éliminé NetBackup et les NAS qu’il remplaçait, pour une économie de l’ordre de 200 000 $ US par an au niveau du service. Plusieurs années plus tard, une fois en poste SRE, j’ai piloté en autonomie la migration du stockage vers Azure Blob Storage puis du cluster vers AKS, avec automatisation du processus via pipeline GitLab.

Sur la durée du service, j’ai traité plus de 300 incidents d’exploitation liés à la plateforme (échecs de sauvegarde, rotation de credentials, capacité stockage, alertes de configuration) couvrant les trois régions NCSA, EMEA et APAC. Ce volume d’incidents est aussi ce qui a permis d’améliorer continuellement la fiabilité du service et d’en affiner l’observabilité.

Mais le résultat dont je suis le plus satisfait n’est pas chiffrable : le service a survécu à mon départ de l’équipe. La passation s’est faite par une documentation technique, des runbooks, des procédures d’exploitation, des guides de diagnostic et des cours vidéo couvrant les opérations courantes et le débogage d’incidents. La documentation et la formation ont permis à l’équipe reprenante d’opérer ensuite le service en autonomie.

Ce que j’en retiens

Un système de sauvegarde n’est pas jugé sur sa capacité à sauvegarder. Il est jugé sur trois choses, dans cet ordre : sa capacité à restaurer, sa capacité à dire s’il va bien, et sa capacité à être exploité par quelqu’un d’autre que son auteur.

Le premier point est évident et pourtant régulièrement négligé : une sauvegarde jamais restaurée est une hypothèse, pas une garantie. Le deuxième explique pourquoi l’observabilité n’était pas une couche ajoutée à la fin. Le troisième ne se vérifie pleinement que dans la durée : il montre si l’on a construit un service transmissible ou une dépendance à la présence de son auteur.

← Tous les projets