mise en miroir unidirectionnelle d'un pool zfs entier vers un autre pool zfs

15

J'ai un pool zfs contenant plusieurs zvols et jeux de données dont certains sont également imbriqués. Tous les jeux de données et zvols sont périodiquement instantanés par zfs-auto-snapshot. Tous les jeux de données et zvols ont également des instantanés créés manuellement.

J'ai configuré un pool distant sur lequel, en raison du manque de temps, la copie initiale sur le réseau local à grande vitesse via zfs send -R ne s'est pas terminée (certains ensembles de données sont manquants, certains ensembles de données ont des instantanés obsolètes ou manquants).

Maintenant, le pool est physiquement distant via une connexion à faible vitesse et je dois synchroniser périodiquement le pool distant avec le pool local, ce qui signifie que les données présentes dans le pool local doivent être copiées vers le pool distant, les données disparues du pool local doivent être supprimées du pool distant, et les données présentes dans le pool distant mais pas dans le pool local doivent être supprimées du pool distant, par données signifiant «zvols», «ensembles de données» ou «instantanés».

Si je faisais cela entre deux systèmes de fichiers normaux utilisant rsync, ce serait "-axPHAX --delete" (c'est ce que je fais pour sauvegarder certains systèmes).

Comment configurer une tâche de synchronisation pour que les zvols et ensembles de données du pool distant (y compris leurs instantanés) puissent être synchronisés avec les zvols, ensembles de données et instantanés locaux?

Je voudrais éviter de transférer sur ssh, en raison des faibles performances de ssh; Je préfère plutôt mbuffer ou iscsi.

Costin Gușă
la source
Comment avez-vous fait votre initiale zfs send -R ...? Si vous avez canalisé la sortie via ssh, avez-vous désactivé les caractères d'échappement avec zfs send -R ... | ssh -e none ...?
Andrew Henle
De plus, vous devez vous assurer que votre connexion lente dispose d'une bande passante suffisante pour maintenir la copie à distance à jour. Si vous apportez plus de modifications au système local que vous ne pouvez en envoyer au système distant, vous ne pourrez jamais garder la copie à distance à jour. Prenez un flux de réplication zfs incrémentiel et enregistrez-le dans un fichier. Si le fichier est plus volumineux que la quantité de données que vous pouvez envoyer au site distant dans l'intervalle de temps entre les instantanés, vous ne suivrez jamais. zfs send -R -i pool@snap1 pool@snap2 | gzip --fast > /output/file.gz
Andrew Henle
Vous pouvez également essayer d'utiliser ce script pour le faire automatiquement: github.com/psy0rz/zfs_autobackup/blob/master/README.md
edwin eefting

Réponses:

11

Avertissement: Comme je n'ai jamais utilisé de zvols, je ne peux pas dire s'ils sont différents dans la réplication des systèmes de fichiers ou des instantanés normaux. Je suppose que oui, mais ne me croyez pas sur parole.


Votre question est en fait plusieurs questions, j'essaie d'y répondre séparément:

Comment répliquer / mettre en miroir le pool complet vers un emplacement distant

Vous devez diviser la tâche en deux parties: tout d'abord, la réplication initiale doit être terminée, ensuite la réplication incrémentielle est possible, tant que vous ne dérangez pas avec vos instantanés de réplication . Pour activer la réplication incrémentielle, vous devez conserver les derniers instantanés de réplication, tout ce qui précède peut être supprimé. Si vous supprimez l'instantané précédent, vous vous zfs recvplaindrez et abandonnerez la réplication. Dans ce cas, vous devez tout recommencer, alors essayez de ne pas le faire.

Si vous avez juste besoin des bonnes options, ce sont:

  • zfs send:
    • -R: envoie tout sous le pool ou le jeu de données donné (réplication récursive, nécessaire tout le temps, inclut -p). De plus, lors de la réception, tous les instantanés source supprimés sont supprimés sur la destination.
    • -I: inclure tous les instantanés intermédiaires entre le dernier instantané de réplication et l'instantané de réplication actuel (nécessaire uniquement avec les envois incrémentiels)
  • zfs recv:
    • -F: étendre le pool cible, y compris la suppression des ensembles de données existants qui sont supprimés sur la source
    • -d: ignorer le nom du pool source et le remplacer par le nom du pool de destination (le reste des chemins du système de fichiers sera conservé et, si nécessaire, également créé)
    • -u: ne pas monter le système de fichiers sur la destination

Si vous préférez un exemple complet, voici un petit script:

#!/bin/sh

# Setup/variables:

# Each snapshot name must be unique, timestamp is a good choice.
# You can also use Solaris date, but I don't know the correct syntax.
snapshot_string=DO_NOT_DELETE_remote_replication_
timestamp=$(/usr/gnu/bin/date '+%Y%m%d%H%M%S')
source_pool=tank
destination_pool=tank
new_snap="$source_pool"@"$snapshot_string""$timestamp"
destination_host=remotehostname

# Initial send:

# Create first recursive snapshot of the whole pool.
zfs snapshot -r "$new_snap"
# Initial replication via SSH.
zfs send -R "$new_snap" | ssh "$destination_host" zfs recv -Fdu "$destination_pool"

# Incremental sends:

# Get old snapshot name.
old_snap=$(zfs list -H -o name -t snapshot -r "$source_pool" | grep "$source_pool"@"$snapshot_string" | tail --lines=1)
# Create new recursive snapshot of the whole pool.
zfs snapshot -r "$new_snap"
# Incremental replication via SSH.
zfs send -R -I "$old_snap" "$new_snap" | ssh "$destination_host" zfs recv -Fdu "$destination_pool"
# Delete older snaps on the local source (grep -v inverts the selection)
delete_from=$(zfs list -H -o name -t snapshot -r "$source_pool" | grep "$snapshot_string" | grep -v "$timestamp")
for snap in $delete_from; do
    zfs destroy "$snap"
done

Utilisez quelque chose de plus rapide que SSH

Si vous disposez d'une connexion suffisamment sécurisée, par exemple un tunnel IPSec ou OpenVPN et un VLAN distinct qui n'existe qu'entre l'expéditeur et le récepteur, vous pouvez passer de SSH à des alternatives non chiffrées comme mbuffer comme décrit ici , ou vous pouvez utiliser SSH avec un chiffrement faible / nul et la compression désactivée, qui est détaillée ici . Il y avait aussi un site Web sur la recompilation de SSH pour être beaucoup plus rapide, mais malheureusement je ne me souviens pas de l'URL - je le modifierai plus tard si je le trouve.

Pour les jeux de données très volumineux et les connexions lentes, il peut également être utile de procéder à la première transmission via le disque dur (utilisez un disque crypté pour stocker zpool et transmettez-le dans un emballage scellé via courrier, courrier ou en personne). Comme la méthode de transmission n'a pas d'importance pour l'envoi / recv, vous pouvez tout diriger vers le disque, exporter le pool, envoyer le disque vers sa destination, importer le pool, puis transmettre tous les envois incrémentiels via SSH.

Le problème avec les instantanés foirés

Comme indiqué précédemment, si vous supprimez / modifiez vos instantanés de réplication, vous recevrez le message d'erreur

cannot send 'pool/fs@name': not an earlier snapshot from the same fs

ce qui signifie que votre commande était incorrecte ou que vous êtes dans un état incohérent où vous devez supprimer les instantanés et recommencer à zéro.

Cela a plusieurs implications négatives:

  1. Vous ne pouvez pas supprimer un instantané de réplication tant que le nouvel instantané de réplication n'a pas été transféré avec succès. Comme ces instantanés de réplication incluent l'état de tous les autres instantanés (plus anciens), l'espace vide des fichiers supprimés et des instantanés ne sera récupéré que si la réplication se termine. Cela peut entraîner des problèmes d'espace temporaires ou permanents sur votre pool que vous ne pouvez résoudre qu'en redémarrant ou en terminant la procédure de réplication complète.
  2. Vous aurez de nombreux instantanés supplémentaires, ce qui ralentit la commande list (sauf sur Oracle Solaris 11, où cela a été corrigé).
  3. Vous devrez peut-être protéger les instantanés contre la suppression (accidentelle), sauf par le script lui-même.

Il existe une solution possible à ces problèmes, mais je ne l'ai pas essayée moi-même. Vous pouvez utiliser zfs bookmarkune nouvelle fonctionnalité d'OpenSolaris / illumos créée spécifiquement pour cette tâche. Cela vous libérerait de la gestion des instantanés. Le seul inconvénient est qu'à l'heure actuelle, cela ne fonctionne que pour des ensembles de données uniques, pas récursivement. Vous devez enregistrer une liste de tous vos anciens et nouveaux jeux de données, puis les parcourir, les mettre en signet, les envoyer et les recevoir, puis mettre à jour la liste (ou une petite base de données, si vous préférez).

Si vous essayez la route des signets, je serais intéressé de savoir comment cela a fonctionné pour vous!

user121391
la source
merci beaucoup pour cette réponse détaillée. je suis juste envoyer .. recevoir a zpool.
gigue
1
joli script. J'ajouterais -d 1aux deux zfs listcommandes pour limiter la profondeur de recherche (il n'est pas nécessaire de rechercher sous le nom du pool). Cela évite les longs retards sur les pools avec beaucoup d'instantanés (par exemple, mon pool de "sauvegarde" a 320000 instantanés et zfs list -r -t snapshot backupprend 13 minutes pour s'exécuter. Cela ne prend que 0,06 seconde avec -d 1). La zfs destroycommande dans la boucle for a alors besoin de l' -roption pour supprimer récursivement tous les instantanés avec le même nom d'instantané.
cas
5

Personnellement, je me ferais une liste de zvols, de jeux de données, etc. sur le serveur distant qui n'ont pas de snapshots à jour, puis je mettrais ces snapshots à jour avec zfs send, même si cela prend du temps et utilise beaucoup de bande passante.

Ensuite, je pourrais continuer à utiliser à zfs sendpartir de là et ne pas avoir à réinventer la roue en écrivant mon propre code de synchronisation. rsyncest agréable pour les anciens systèmes de fichiers mais zfs sendest beaucoup mieux pour zfs - il sait exactement quels blocs ont changé dans l'instantané et n'envoie que ceux-ci, tandis que rsync doit comparer les fichiers individuels et / ou les horodatages entre les serveurs locaux et distants. il en va de même btrfs sendpour les pools btrfs.

Si vous ne disposez que d'un petit nombre d'instantanés à mettre à jour, cela peut être fait manuellement. Sinon, pour le faire automatiquement, vous avez besoin d'une liste des derniers snapshots locaux vs snapshots distants, et d'un script pour comparer les versions, puis zfs senddes snapshots locaux qui sont obsolètes sur le serveur rmeote.

Cela suffira si vous ne vous souciez que du dernier instantané pour chaque ensemble de données. Si vous vous souciez de tous les instantanés précédents, votre script devra évidemment aussi les gérer .... et cela devient BEAUCOUP plus compliqué. Dans certains cas, vous devrez peut-être restaurer le serveur distant afin de pouvoir renvoyer les instantanés intermédiaires / manquants.

Si vous voulez une connexion sécurisée au serveur distant, vous n'avez vraiment pas d'autre choix que d'utiliser ssh- ou peut-être configurer un tunnel avec openvpnou quelque chose et utiliser netcat.

cas
la source
Et pour utiliser Zrep? bolthole.com/solaris/zrep
Xdg
ne sais pas, je ne l'ai jamais utilisé. semble que cela ferait une bonne réponse, bien que si quelqu'un devait faire un peu de recherche et de test et l'écrire (c'est un indice).
cas
Je l'ai testé sur Ubuntu (ZFS sur linux) et cela ne fonctionnait pas sur des ensembles de données plus profonds (tank / quelque chose / un autre). J'utilisais ce port pour shell - link . Le drapeau récursif export ZREP_R=-Rne fonctionnait pas du tout. :(
Xdg
1

Jetez un œil à `zrepl ', sur FreeBSD, qui pourrait vous faciliter la vie, et n'importe qui d'ailleurs, beaucoup plus facilement. Il a été présenté il y a quelques jours lors du BSDCan2018 à Ottawa. Cela semble prometteur et peut être une solution à vos problèmes

fd0
la source
La question de la question est: "Comment configurer une tâche de synchronisation pour que les zvols et les ensembles de données du pool distant (y compris leurs instantanés) puissent être synchronisés avec les zvols, les ensembles de données et les instantanés locaux?"
Jeff Schaller
0

zrep est une belle solution tout-en-un, ET a de la documentation + des crochets sur la façon d'obtenir des transferts plus rapides que les simples transferts SSH

https://github.com/bolthole/zrep

il est également multiplateforme: pris en charge sur linux, freebsd et solaris / illumos

Philip Brown
la source
1
La question de la question est: "Comment configurer une tâche de synchronisation pour que les zvols et les ensembles de données du pool distant (y compris leurs instantanés) puissent être synchronisés avec les zvols, les ensembles de données et les instantanés locaux?"
Jeff Schaller
Jeff, suggérez-vous que la meilleure "réponse" serait de couper-coller les bits de la documentation de zrep, plutôt que de simplement donner une référence à zrep?
Philip Brown
1
Je ne sais pas quelle serait la meilleure réponse, mais un lien vers un logiciel n'est pas une solution. C'est déjà mentionné, en fait. La question demande: «Comment configurer une tâche de synchronisation pour que les zvols et ensembles de données du pool distant (y compris leurs instantanés) puissent être synchronisés avec les zvols, ensembles de données et instantanés locaux?»
Jeff Schaller
oui c'est la question. Cependant, pour bien accomplir la tâche, il faut bien plus qu'un petit résumé sur une page Web ici. C'est pourquoi zrep est un shellscript de 2000 lignes. Même si l'on devait supprimer toutes les parties dont le problème d'origine n'a jamais eu besoin, il resterait encore quelques centaines de lignes de script pour le faire BIEN.
Philip Brown