Sauvegardes de ZdS

a marqué ce sujet comme résolu.

Bonsoir à tous,

Le sujet est sur la table depuis un moment au sein de l’équipe qui gère l’infrastructure de ZdS : il est temps d’améliorer notre système de sauvegardes.

La situation actuelle

Actuellement, les données du serveur de production sont sauvegardées sur le serveur de bêta.

Le serveur de production dispose d’un disque dur de 50 Go, dont 30 Go sont actuellement occupés. On sauvegarde deux choses :

  • les données du site qui sont directement sur le disque (images et dépôts Git des contenus, principalement). En brut, cela représente actuellement 14 Go. À l’aide de Borg Backup, on fait des sauvegardes incrémentales vers le serveur de bêta toutes les 2 heures. Borg parvient à réduire le poids de toutes les sauvegardes à 7 Go. On conserve les sauvegardes des 60 deniers jours.
  • la base de données MySQL. On fait une sauvegarde complète par jour, puis des sauvegardes incrémentales toutes les 2 heures. Sur le serveur de production, on ne conserve que deux jours de sauvegardes, mais on utilise rsync pour envoyer les sauvegardes vers le serveur de bêta, où là on conserve 60 jours de sauvegardes. Il faut compter environ 0,5 Go de sauvegarde par jour (~ 400 Mo pour la sauvegarde complète, puis autour de 10 Mo pour les sauvegardes incrémentales). Sur la bêta, les sauvegardes des bases de données représentent donc 31 Go.

Vous trouverez les détails techniques ici.

Le serveur de bêta dispose de deux disque durs :

  • le disque système (qui contient aussi la version bêta de ZdS, qui est un clône de la version de production en terme de données, donc aussi en terme de volume) a une capacité de 46 Go, dont 32 sont occupés ;
  • un disque de 46 Go qui sert à stocker les sauvegardes venant du serveur de production.

Si vous faîtes un petit calcul, vous vous rendez compte que le disque dédié aux sauvegardes est quasiment plein (37 Go sur 46). C’est pourquoi il faut agir !

Un autre problème est que, actuellement, il n’y a pas d’autres sauvegardes, hors des serveurs de ZdS. L’idéal serait d’avoir aussi une sauvegarde chez un des membres, "au cas où". Bien-sûr, cette sauvegarde externe doit être chiffrée, depuis les serveurs de ZdS.

On a donc deux problèmes :

  • avec la configuration actuelle, on atteint nos capacités de stockage,
  • il n’y a pas de sauvegarde externe.

Solutions envisagées

Puisque ce sont les sauvegardes de la base de données qui prennent le plus de place, autant s’attaquer à elles. Une première solution plutôt facile est de les sauvegarder aussi avec Borg, et voir à quel point il arrive à dédupliquer et gagner en place (si c’est comme pour les données du site, la sauvegarde totale des bases de données peut peut-être peser moins d’un Go !).

Deuxième chose : a-t-on besoin de 60 jours de sauvegardes, avec une granularité de 2h entre chaque sauvegarde ? On pourrait par exemple garder la granularité de 2h pour les deux dernière semaines, puis une sauvegarde par semaine pour les 6 semaines précédentes (par exemple, je ne sais pas vraiment quelles sont les valeurs adaptées, c’est surtout une histoire de risque…).

Sauvegardes externes

Concernant les sauvegardes externes, borg permet de chiffrer le dépôt où il stocke les sauvegardes ; donc ceux qui le souhaitent pourraient juste faire un rsync entre les serveurs de ZdS et leur stockage pour récupérer les sauvegardes chiffrées de ZdS.

La question qui se pose ici, c’est depuis quel serveur récupérer la sauvegarde. En l’état actuel des choses, le plus simple (et le plus faisable en terme de stockage…) et de récupérer la sauvegarde située sur le serveur de bêta. Cependant, dans ce cas, le lien serveur de production -> serveur de bêta est un single point of failure : si le transfert entre le serveur de production et le serveur de bêta est buggué, on récupérera une sauvegarde bugguée…

L’idéal serait de faire la sauvegarde du serveur de production sur le serveur de production (laisser borg stocker ses sauvegardes dans un coin du serveur de production), faire un rsync du dépôt de borg vers le serveur de bêta, et laisser ceux qui le souhaitent faire des rsync entre la production et leur espace de stockage. Malheureusement, j’ai bien peur que l’espace de stockage disponible sur le serveur de production ne nous permette pas cette solution… Je viens de regarder et, apparement, rajouter un disque de 50 Go au serveur de production coûterait 2,16€ / mois. Est-ce qu’on peut se le permettre, est-ce qu’on veut se le permettre ?

Des avis, suggestions, remarques ? N’hésitez pas à demander si vous souhaitez que je précise un point.

Merci pour cet état des lieux.

Le point névralgique pour moi se situe au niveau de la sauvegarde de la base MySQL. Et donc je me pose une question:

EDIT (après lecture du script de backup).

D’autre part, 1 sauvegarde full tous les jour, pour en stocker 60, me parait overkill.

  • Déjà je ne vois pas pourquoi on aurait besoin de revenir à 2 mois de données (peut-être qu’il y a des contraintes de la CNIL qui nous impose des choses, vu qu’il y a du stockage d’adresse IP quelque part).
  • Ensuite, logiquement, une fois qu’on a fait une full, un on est censé supprimer les incrémentales entre deux full (mais comme je vois passer du rsync, j’ai un peu peur, d’ou ma première question sur l’outil de sauvegarde)
  • Enfin, j’aurai tendance à faire comme la plupart des sites, c’est à dire, une full par semaine, et entre deux full, on fait des incrémentales (toutes les 2h why not si ça peut nous éviter un RPO trop élevé).

Quand j’ai mis en place le système de sauvegarde sur la bêta, j’ai choisi de mettre en place un système « bête mais qui fonctionne » avec l’idée plus tard de rendre ça un peu plus intelligent, sauf que ce jour n’est jamais arrivé. Je te remercie donc @philippemilink de la création de ce sujet !

Concernant la stratégie des sauvegardes, je pense qu’il faut réfléchir à l’objectif recherché. Le premier objectif est, je pense, de se prémunir contre une défaillante du serveur de production qui entraîne une perte des données (arrêt brutal du serveur qui corrompt la base de données, soucis logiciel ou matériel chez Gandi, chiffrement du disque par un rançongiciel, etc.) Il faut répondre à deux questions :

  • « à combien de temps en arrière souhaite-t-on pouvoir revenir ? » (actuellement, 60 jours) ;
  • « quelle quantité maximale de données acceptons-nous de perdre ? » (actuellement, 2 heures d’utilisation du site).

Pour la première question, je dirais qu’on peut redescendre à 30 jours si on le souhaite sans trop de soucis. Le minimum me semble être de l’ordre d’une ou deux semaines, car il est déjà arrivé que la base de données semble être saine mais qu’une petite partie soit corrompue et que ça ait des conséquences un peu plus tard quand MySQL tente d’accéder à cette partie.

N’oublions pas le passé

En plus de ça, une tuile nous est tombée dessus cet après-midi. Vers 14 h 30, une baie de disques (c.-à-d. un serveur responsable du stockage de données) a crashé chez Gandi. Pas de bol, un des clients impactés était Zeste de Savoir. Nous avons pu rétablir le service rapidement vers 15 heures et sommes retournés à nos tâches respectives. Tout semblait être revenu à la normale.

Le mot-clé est « semblait », car sous des dehors calmes paisibles, une terrible catastrophe couvait. Le fichier de données de la base MySQL avait été subtilement corrompu lors du crash de 14 h 30. Tout s’est donc passé normalement, jusqu’au moment où le serveur a tenté d’utiliser la partie endommagée du fichier… ce qui l’a définitivement abimé. Devant l’étendue des dégâts, le serveur MySQL a préféré rendre l’âme et cesser de fonctionner tant qu’on ne lui fournirait une version corrigée des données. Las ! Le problème était tel que, malgré quatre heures d’efforts conjointement menés par SpaceFox, gustavi et victor, rien ne put être sauvé.

Retour dans le passé pour ZDS

Pour la deuxième question, la durée de 2 heures me semble très acceptable. On pourrait probablement réduire à une heure, mais je ne pense pas qu’il y ait grand intérêt pour les utilisateurs et il faudrait vérifier qu’on en demande pas trop au serveur de production, sans parler de la question de l’espace disque.

Un deuxième objectif des sauvegardes peut être de se prémunir contre une perte non pas de toutes les données mais d’un élément des données (un contenu, une galerie d’images, etc.) Je pense notamment à un cas où un auteur ne se serait pas connecté depuis plusieurs semaines et découvrirait qu’un de ses contenus à disparu. Dans ce cas, il peut être utile d’avoir des sauvegardes qui remontent à quelques mois mais sans avoir une granularité de deux heures.

On pourrait donc imaginer le système suivant :

  • sauvegarde toutes les 2 heures pendant 30 jours ;
  • sauvegarde une fois par semaine pendant deux mois supplémentaires ;
  • sauvegarde une fois par mois pendant trois mois supplémentaires.

Concernant la redondance des sauvegardes, je pense qu’il faut nécessaire avoir au moins deux sauvegardes indépendantes l’une de l’autre : une sauvegarde depuis la prod vers la bêta et une sauvegarde depuis la prod vers un autre endroit. Je ne pense pas qu’il soit intéressant d’avoir une sauvegarde depuis la bêta vers un autre endroit.

Concernant les solutions techniques, actuellement les données du disque sont compressées et dédupliquées mais les sauvegardes de la base de données ne sont que compressées. Pour ne pas gâcher de l’espace disque, il faudrait les dédupliquer. Étant donné qu’on utilise BorgBackup pour les données du disque, il serait intéressant de l’utiliser aussi pour les sauvegardes de la base de données.

Comme d’habitude j’ai procrastiné un peu l’écriture de ma réponse, mais c’est maintenant chose faite !

+1 -0

Juste un message rapide pour vous dire que j’ai plutôt bien avancé. Je ferai plus tard un message un peu plus étoffé qui détaille ce que j’ai changé, et quels sont les impacts.

Ce qui est fait

  • Développement d’un script pour restaurer en une commande sur la bêta les sauvegardes de la prod. Cela facilite énormément la synchronisation de la bêta avec le prod, et permet en même de temps de s’assurer que les sauvegardes sont exploitables !
  • Utilisation de gzip pour compresser les sauvegardes de la base de données ; la façon de faire en place jusqu’alors étant maintenant dépréciée par MariaDB. Non seulement on est à jour, mais cela fait des sauvegardes plus petites !
  • Mise à jour de BorgBackup
  • Utilisation de Borg aussi pour les sauvegardes de la base de données, au lieu d’un simple rsync. La déduplication devrait permettre de gagner pas mal en espace de stockage, et les changements dans le nombres de sauvegardes incrémentales qu’on garde seront faciles à appliquer.
  • Grosse réécriture de la documentation des sauvegardes pour prendre en compte les modifications ci-dessus et essayer de réorganiser un peu mieux tout ce qui a été ajouté au fil du temps.

Ce qui est en cours

  • Avoir un utilisateur dédié à la réception des sauvegardes sur le serveur de bêta. C’est bon pour les sauvegardes de la base de données, ça reste à faire pour les sauvegardes des contenus. L’objectif à terme est d’interdire la connexion en SSH avec l’utilisateur root au serveur de bêta (sans doute une des règles n°1 des bonnes pratiques en terme de sécurité).
  • Mise en place des sauvegardes externes (vers les serveurs des membres volontaires). Il y a déjà des sauvegardes qui sont faites avec Borg depuis le serveur de prod vers mon propre serveur (je me suis rendu compte depuis la création de ce sujet que je pouvais finalement faire ça assez facilement sur mon infra perso). Bien entendu, Borg chiffre les sauvegardes avant qu’elles ne sortent du serveur de prod. Par contre, je pensais que les borg prune (effacer au fur et à mesure les vieilles sauvegardes) seraient faits depuis les serveurs externes (à la convenance de leurs propriétaires), mais je suis tombé sur un petit problème, que je n’ai pas encore réglé…

Ce qu’il reste à faire

  • Sauvegarder aussi les données de Matomo (il faut je regarde un peu la doc pour voir précisément ce qu’il est possible de sauvegarder).
  • Mieux logguer l’exécution des scripts de sauvegarde. Actuellement, leur sortie se retrouve mélangée dans des logs systèmes, on pourrait avoir des fichiers dédiés pour y voir plus clair.
  • Je me dis qu’il serait sans doute pratique d’avoir un unique script qui fait tout le boulot (sauvegarde de la base de données, sauvegardes avec borg vers le serveur de bêta), plutôt que d’avoir toutes ces tâches éparpillées dans différents scripts, lancés par différentes crons…

Dans l’idéal

Comprendre : ce qui va se retrouver tout en bas d’une TODO-liste et/ou devenir une issue délaissée sur un dépôt GitHub.

  • Automatiser la mise en place du système de sauvegarde, en complétant nos scripts Ansible pour le déploiement de nos serveurs.
Connectez-vous pour pouvoir poster un message.
Connexion

Pas encore membre ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte