Sauvegarde vers Backblaze B2 avec duplicity

Étant donné les difficultés rencontrées lors de la dernière restauration de mon serveur à partir des données sauvegardées dans hubic, mais également lors de la tentative de restauration précédente, je suis parti à la recherche d’un second lieu de sauvegarde. Après quelques recherches, je me suis décidé à essayer le service fournit par la société Backblaze, en particulier avec sa solution B2 Cloud Storage.

Parmi les points qui m’ont orienté ma décision, on notera :

  • la compatibilité avec duplicity, outil que j’utilise actuellement pour réaliser mes sauvegardes.
  • 10 GB de stockage gratuit
  • Pas de nécessité de saisir des informations de paiement pour pouvoir tester.
  • Un coût de stockage de 0,005$ par GB et par mois.

Du côté tarification, nous sommes proches de ce qu’on retrouve du côté d’Amazon Glacier qui propose une tarification à 0,004$ par Go/mois pour le choix des régions de stockage les moins chers. Si les offres Amazon peuvent également être intéressantes, mais l’utilisation avec duplicity n’est pas disponible en l’état. De plus, il semble que la difficulté se situe au minimum du côté de l’option verify qu’il faudrait désactiver car comptant comme une demande de restauration. Une autre difficulté se situe du côté de la restauration des fichiers à proprement parlé, étant donné le temps nécessaire à Glacier pour rendre les fichiers disponibles après leur sauvegarde. Bref, à tester, mais dans un autre contexte.

Passons à la configuration de duplicity pour B2. Une version de duplicity v0.7.12 ou plus récente est nécessaire. La vérification s’effectue avec :

duplicity --version

La version installée sur mes serveurs depuis les dépôts de Debian était trop ancienne, j’ai donc compilé le programme à partir des sources du projet disponible sur le site du projet. Après récupération du dossier compressé des sources, petit tour dans le README pour prendre connaissance des pré-requis et des instructions de compilation. On procède donc à l’installation des dépendances demandées :

sudo aptitude install python-dev librsync-dev intltool python-fastener

Passage ensuite à l’étape de compilation, après décompression des sources :

python setup.py build

Puis désinstallation de la version en provenance du gestionnaire de paquet et installation de la version compilée à l’instant.

sudo aptitude remove duplicity
sudo python setup.py install

Enfin, vérification de la version de duplicity installée et vérification de l’emplacement de l’exécutable.

duplicity --version
which duplicity

Après mon premier test de sauvegarde, j’ai noté que les composants suivants sont également nécessaires au bon fonctionnement de duplicity avec B2 :

pip install b2
pip install backports.functools_lru_cache

À ce stade, on peut passer à un premier test de sauvegarde vers la solution de stockage de Backblaze. La commande duplicity reste des plus classiques et prends la forme suivante :

duplicity ~ b2://[applicationKeyId]:[application key]@[B2 bucket name]

Attention, la clé d’application doit être sauvegardée dans un endroit sûr, au hasard, dans son gestionnaire de mot de passe préféré. En effet, une fois la fenêtre contenant la clé fermée, il n’est plus possible d’afficher la clé et une nouvelle clé devra être générée en cas de perte de la première.

Autre point, la documentation Backblaze est en partie erronée dans la structure de la commande duplicity proposée, puisque y est fait mention d’un paramètre account_id en lieu et place du paramètre applicationKeyId ci-dessus. C’est bien ce dernier paramètre qu’il faut choisir, car utiliser l’account_id ne conduira qu’à des erreurs d’autorisation et à de la frustration

Quelques lignes encore pour terminer cet article. Je dispose désormais d’une double sauvegarde de mes serveurs vers hubic et maintenant B2. Le volume de données sauvegardées n’excède pas, pour l’instant, la tranche gratuite du service. Par la suite, j’envisage de tester d’autres outils de sauvegarde en particulier Restic et Borg. En outre le coût relativement faible du stockage m’encourage à envisager la sauvegarde externe de données froides comme mes photos numériques et ma bibliothèque de musique. La réflexion suit son cours.

Sauvegarde distante avec duplicity

Suite à la migration de la majorité de mon nuage de services vers mon réseau en passant à l’auto-hébergement, la question de la sauvegarde des données est devenue cruciale. Côté cahier des charges, les principaux critères retenus étaient les suivants :

  • Sauvegarde externe géographiquement
  • Automatique
  • Chiffrée

Après de nombreuses recherches, j’ai décidé d’utiliser duplicity pour réaliser la sauvegarde et le service hubiC d’OVH pour le stockage des données sauvegardées. Voici donc la procédure utilisée pour mettre en place une sauvegarde incrémentale quotidienne, avec sauvegarde complète à intervalle régulier.

Pour commencer, il convient d’installer les composants nécessaires:

sudo aptitude install duplicity python-pip python-dev gcc
sudo pip2 install pyrax

Ayant décidé d’envoyer les sauvegardes dans mon espace hubiC, et afin de permettre à duplicity de communiquer avec hubiC, il faut au préalable autoriser l’application dans l’interface web du service. On va donc créer une nouvelle application, renseigner un nom, duplicity par exemple, et un domaine de redirection valant http://localhost/. On note ensuite les paramètres « Client ID » et « Client secret » qui serviront pour paramétrer la connexion à hubiC sur la machine source.

Le paramétrage s’effectue dans le fichier ~/.hubic_credentials :

[hubic]
email = your_email
password = your_password
client_id = api_client_id
client_secret = api_secret_key
redirect_uri = http://localhost/

On limite ensuite les droits liés au fichier:

chown 600 ~/.hubic_credentials

A ce stade, on peut faire un premier test afin de valider la configuration, par exemple, sauvegarder le répertoire test dans le conteneur test qui sera accessible à l’adresse suivante: https://hubic.com/home/browser/#test.

duplicity test cf+hubic://test

Pour lister le contenu du répertoire distant, la commande dédiée est:

duplicity list-current-files cf+hubic://test

Continuer la lecture de « Sauvegarde distante avec duplicity »

Sauvegarde de base de données avec mysqldump et logrotate

Cela faisait plus d’un an que j’avais vaguement mentionné la question de la sauvegarde d’Unicoda et des autres services que j’héberge. Jusqu’à présent, je m’étais contenté de quelques sauvegardes manuelles effectuées de temps à autre, lorsque le contenu avait bien évolué ou que la sauvegarde précédente commençait à dater. Je me suis donc intéressé aux différentes solutions qu’on rencontre sur le net : rsync, rclone, duplicity, script bash, bacula, pour ne citer que quelque-uns des outils. Si l’automatisation de la sauvegarde ne m’avait jamais semblé essentielle, c’est que j’étais conscient des risques et me reposait sur la duplication RAID de l’hébergeur (pour le risque de défaut matériel), mais surtout, parce que la majorité des informations était généralement présente en local sur l’une ou l’autre de mes machines. Après les récents changements de serveurs et le passage à l’auto-hébergement de nombreux services, la sauvegarde devient critique. Commençons donc par nous pencher sur la sauvegarde des données du serveur SQL.

Pour exporter les données d’un serveur MySQL, la commande mysqldump est tout indiquée. Pour sauvegarder l’intégralité des bases du serveur avec l’utilisateur root, on pourra par exemple utiliser :

mysqldump -u root -p --all-databases > all_databases.sql

De la même manière, il est possible de n’extraire qu’une seule base de données :

mysqldump -u [user] -p maBase > maBDD.sql

Il est possible de spécifier le mot de passe de l’utilisateur directement dans la commande via -p[motDePasse] ou encore -p'[motDePasse]’.  Une fois en possession d’une copie de notre base, l’import s’effectue simplement en utilisant :

mysql -u [user] -p maNouvelleBase < maBDD.sql

J’ai eu l’occasion de mettre à l’épreuve cette méthode lors des différentes migrations d’Unicoda; toujours avec succès et sans jamais rencontrer de problème.

Maintenant que nous avons une façon de sauvegarder les données de MySQL, il est temps de s’intéresser à l’automatisation du processus.  Afin de régler la question de l’accumulation des fichiers de sauvegarde, j’ai décidé d’utiliser logrotate, en détournant quelque peu son usage pour l’appliquer à mes sauvegardes SQL et non à des fichiers de logs. Avant toutes choses, je crée un nouvel utilisateur au niveau de MySQL en le limitant aux droits Lock Tables et Select sur la base que je veux sauvegarder.

GRANT LOCK TABLES, SELECT ON maBase.* TO '<user>'@'localhost' IDENTIFIED BY '<password>';

On passe ensuite à la configuration de logrotate pour notre fichier de sauvegarde. J’ajoute donc un fichier dans /etc/logrotate.d/sauvegarde-base-sql avec le contenu suivant :

/var/backups/mysql/maBDD.sql.gz {
  daily
  dateext
  rotate 21
  nocompress
  create
  postrotate
  mysqldump --single-transaction --add-drop-table -u user -pmonMotDePasse baseASauvegarder > /var/backups/mysql/maBDD.sql
  gzip -9f /var/backups/mysql/maBDD.sql
  chown user:user /var/backups/mysql/maBDD.sql.gz
  chmod 640 /var/backups/mysql/maBDD.sql.gz
  endscript
}

Côté paramètres :

  • L’exécution est journalière.
  • La date est ajoutée au fichier lors de la rotation.
  • On conserve 21 fichiers.
  • Pas de compression
  • Le nouveau fichier est créé avec les mêmes permissions et le même propriétaire que le précédent (create).
  • On indique les commandes à exécuter après rotation (postrotate) à savoir :
    • Extraction des données de la base
    • Compression du fichier
    • Modification du propriétaire
    • Modification des droits

Enfin, on prépare l’état initial du script en ajoutant un fichier vide de départ :

sudo touch /var/backups/mysql/maBDD.sql.gz

Il est alors possible de tester l’exécution avec l’instruction suivante (débug avec -d et mode verbeux avec -v) :

sudo logrotate -f /etc/logrotate.d/sauvegarde-base-sql

La restauration de la base s’effectue avec la commande d’import décrite plus haut, il faudra bien sûr au préalable décompresser le fichier de sauvegarde :

gunzip maBDD.sql.gz

Grâce à cette configuration, je dispose désormais de 21 jours de sauvegarde de ma base SQL, le tout entièrement automatisé. Logrotate me permet de bénéficier simplement de la rotation de mes fichiers de sauvegarde. Il aurait été aussi possible d’utiliser un script bash et une tâche cron pour un résultat similaire, mais cela aurait nécessité de s’occuper de la partie gestion des anciens fichiers; ce que logrotate fait très bien pour moi. Dans le prochain article dédié à la sauvegarde, je décrirai la solution que j’ai retenue pour la sauvegarde distante des fichiers du serveur, dont ces exports SQL.

Par ailleurs, n’hésitez pas à partager votre manière de sauvegarder votre base de données dans les commentaires.

Source : scottlinux, LeaseWeb Labs, Linode.

Sauvegarde du contenu d’une carte SD

J’ai réalisé dernièrement quelques essais d’applications audio compatible Raspberry Pi. En cas de test non satisfaisant, je voulais être en mesure de redéployer aisément l’ancien système. Le site officiel du Raspberry Pi fournit pour ce cas précis de bonnes explications.

Je retiens donc les commandes suivantes permettant de copier le contenu d’une carte SD et de pouvoir le réécrire à l’identique, avec au passage, compression des données pour gagner en espace disque.

Pour sauvegarder :

sudo dd bs=4M if=/dev/mmcblk0 | gzip > pi.img.gz

Et pour déployer la sauvegarde :

gunzip --stdout pi.img.gz | sudo dd bs=4M of=/dev/mmcblk0

En remplaçant bien évidemment /dev/mmcblk0 par le chemin vers la carte SD sur le système hôte.

Échec de sauvegarde Gitlab et objets LFS

Lors d’une récente sauvegarde du contenu de mon Gitlab en vue d’une mise à jour, j’ai vu apparaître une erreur déjà rencontrée lors d’une précédente sauvegarde.

rake aborted!
Errno::ENOENT: No such file or directory @ realpath_rec - /home/git/gitlab/shared/lfs-objects

N’ayant pas à ma connaissance d’objets LFS à sauvegarder, j’ai donc ajouter un paramètre pour éviter la tentative de sauvegarde de ces objets avec SKIP=lfs. On obtient donc la commande suivante :

sudo -u git -H bundle exec rake gitlab:backup:create SKIP=lfs RAILS_ENV=production

Maj : Ce problème est résolu à partir de Gitlab 8.3.