Je dispose de deux serveurs A et B qui exécutent Ubuntu 16.04 et un système de fichiers RAID1 ZFS pour LXD. Actuellement, quelques conteneurs sont en cours d'exécution sur le serveur A. Maintenant, mon idée est de réaliser des sauvegardes nocturnes de chaque conteneur sur le serveur A vers le serveur B. De cette manière, je veux être en mesure de démarrer un conteneur sur le serveur B si le serveur A tombe en panne. Je peux également utiliser les instantanés locaux sur le serveur A pour restaurer rapidement un conteneur si quelqu'un supprime des fichiers par accident, par exemple.
La manière la plus simple serait d'arrêter le conteneur C sur le serveur A, de créer un instantané Snap0 et de le redémarrer. Ensuite, utiliser lxc copy C/Snap0 serverB:C
pour copier l'instantané sur le serveur B, en supposant que j'ai déjà ajouté le serveur B en tant qu'hôte distant du serveur A. Le problème ici est que cela fonctionne seulement la première fois. Pour une autre sauvegarde, je devrais supprimer le conteneur C sur le serveur B avant de pouvoir le copier à nouveau. Et le second problème est que le conteneur augmente d'une sauvegarde à l'autre et finalement il y a tellement de données à transférer vers le serveur B que tous les services qui y fonctionnent auront une bande passante insuffisante.
La solution à cela devrait être de ne transférer que les différences entre les instantanés nocturnes. On peut y parvenir avec zfs send/receive
qui est capable, en conjonction avec SSH, d'envoyer les différences entre les instantanés sur le serveur A vers un serveur B via SSH, puis ajouter ces différences au système de fichiers du serveur B. Mais il y a encore un problème. Cela ne fonctionne pas si j'ai créé le système de fichiers initial du conteneur C en utilisant lxc copy
car cette commande n'utilise pas zfs send/receive
en interne mais crée un nouveau système de fichiers sur le serveur B qui a par conséquent un checksum différent du système de fichiers original sur le serveur A. Une sauvegarde différentielle n'est donc pas possible et zfs receive
renverra une erreur car il compare les checksums des systèmes de fichiers.
Mon idée suivante est d'utiliser uniquement zfs send/receive
pour transférer l'ensemble du système de fichiers du conteneur C du serveur A vers le serveur B sans créer de conteneur en utilisant lxc copy/init
. Après cela, il ne posera aucun problème d'envoyer les différences entre deux instantanés consécutifs chaque nuit car les checksums correspondent. Mais alors le problème c'est que je ne suis pas en mesure de démarrer le copie du conteneur C sur le serveur B en cas d'urgence car il n'y a pas d'entrée dans la base de données de LXD située à /var/lib/lxd/lxd.db
, donc lxc start C
ne fonctionnera pas. je pense que je peux simplement copier les entrées pertinentes de la base de données LXD du serveur A vers la base de données LXD du serveur B pour que cela fonctionne mais je n'en suis pas sûr. Peut-être pouvez-vous m'aider ici. Je ne veux rien détruire dans ces bases de données.
Quelques informations de fond : En fait, les deux serveurs A et B exécutent des conteneurs mais chaque serveur devrait contenir des sauvegardes des conteneurs de l'autre serveur.
Peut-être qu'il existe déjà une stratégie de sauvegarde fonctionnelle utilisant deux ou plusieurs hôtes LXD, mais je n'ai pas pu la trouver. Il y a seulement des stratégies de sauvegarde similaires à rsync
ou des copies de conteneurs entiers chaque nuit.
Mise à jour : Je viens de recevoir un indice sur ce commit GitHub qui implémente une nouvelle sous-commande pour la commande lxd, à savoir lxd import
. Donc j'ai dû mettre à jour lxd sur les deux serveurs en utilisant les backports d'Ubuntu en utilisant apt-get install -t xenial-backports lxd lxd-client
.
Personne ne devrait être en mesure d'importer un conteneur à partir d'un système de fichiers existant. J'ai essayé. Tout d'abord, allez sur le serveur A et faites un instantané
lxc snapshot C Snap0
Envoyez l'instantané sur le serveur B en utilisant zfs send/receive
en utilisant l'argument supplémentaire -p
sur le site de l'expéditeur pour inclure également les propriétés du système de fichiers.
zfs send -p lxd/containers/C@snapshot-Snap0 | ssh serverB zfs receive lxd/containers/C
Passez au serveur B et créez un lien symbolique :
ln -s /var/lib/lxd/containers/C.zfs /var/lib/lxd/containers/C
Et maintenant je devrais être en mesure d'importer :
lxd import C
Mais au lieu de cela, j'obtiens une erreur :
erreur : ouverture de /var/lib/lxd/containers/C/backup.yaml : aucun fichier ou dossier de ce type
Comme je ne sais pas d'où vient ce fichier backup.yaml
, j'ai essayé de copier le fichier metadata.yawl
existant vers backup.yaml
. Après un autre essai, j'obtiens cette erreur :
erreur : aucune réponse !
Et maintenant je ne sais pas quoi faire car il n'y a aucun conseil sur l'endroit d'où vient ce fichier backup.yaml
.
Mise à jour 2 : Comme l'a déjà mentionné bubble, on peut obtenir ce fichier backup.yaml
en arrêtant et en redémarrant un conteneur ou tout simplement en prenant un autre instantané après la mise à niveau vers LXC 2.7+.
Donc finalement, mon script fonctionne bien. Maintenant, il ne reste qu'un petit problème. Après avoir importé un conteneur avec lxc import
, je ne peux plus le supprimer sans détruire l'ensemble du système de fichiers du conteneur. Je réfléchis à une commande comme lxc import --update
ou lxc delete --keep-root-fs
ou similaire. J'ai déjà soumis une demande de fonctionnalité concernant cette idée.
Mise à jour 3 : Et ici, vous pouvez voir les progrès : Améliorer la gestion des sauvegardes LXD #3005