Comment porter des volumes de données uniquement d'un hôte à un autre?

121

Comme décrit dans la documentation Docker sur l'utilisation des volumes, il existe le concept de conteneurs dits uniquement de données , qui fournissent un volume qui peut être monté dans plusieurs autres conteneurs, que le conteneur de données uniquement soit en cours d'exécution ou non.

En gros, cela semble génial. Mais il y a une chose que je ne comprends pas.

Ces volumes (qui ne sont pas explicitement mappés à un dossier sur l'hôte pour des raisons de portabilité, comme l'indique la documentation) sont créés et gérés par Docker dans un dossier interne sur l'hôte ( /var/docker/volumes/…).

Supposons que j'utilise un tel volume, puis que je doive le migrer d'un hôte à un autre - comment porter le volume? AFAICS, il a un ID unique - puis-je simplement copier le volume et son conteneur de données uniquement sur un nouvel hôte? Comment savoir quels fichiers copier? Ou existe-t-il un support intégré à Docker que je n'ai pas encore découvert?

Golo Roden
la source
12
Vous pouvez exporter le répertoire du conteneur de données: docker run --volumes-from <data container> ubuntu tar -cO <volume path> | gzip -c > volume.tgzcela ne dépend pas des détails d'implémentation des volumes. Et importez les données avec tar sur la deuxième machine.
Jiri
1
Wow, c'est génial, merci :-)))! Si vous écrivez ce commentaire comme réponse, je l'accepterai volontiers!
Golo Roden

Réponses:

136

La réponse officielle est disponible dans la section "Sauvegarder, restaurer ou migrer des volumes de données" :

SAUVEGARDE:

sudo docker run --rm --volumes-from DATA -v $(pwd):/backup busybox tar cvf /backup/backup.tar /data
  • --rm: retirer le conteneur à sa sortie
  • --volumes-from DATA: attacher aux volumes partagés par le conteneur DATA
  • -v $(pwd):/backup: bind monte le répertoire courant dans le conteneur; pour écrire le fichier tar dans
  • busybox: une petite image plus simple - bonne pour une maintenance rapide
  • tar cvf /backup/backup.tar /data: crée un fichier tar non compressé de tous les fichiers du répertoire / data

RESTAURER:

# create a new data container
$ sudo docker create -v /data --name DATA2 busybox true
# untar the backup files into the new container᾿s data volume
$ sudo docker run --rm --volumes-from DATA2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar
data/
data/sven.txt
# compare to the original container
$ sudo docker run --rm --volumes-from DATA -v `pwd`:/backup busybox ls /data
sven.txt
tommasop
la source
3
Pour l'instant, il est préférable d'utiliser docker createpour les conteneurs de données uniquement afin qu'ils ne soient pas démarrés. Voir l'exemple dans le off. documentation: docs.docker.com/userguide/dockervolumes/…
FelikZ
1
Alors ... Si je suis en train de sauvegarder une base de données Postgres, qu'aurais - je remplacer /dataavec /var/lib/postgresql/data, non ?
425nesp
6
La section «Sauvegarder, restaurer ou migrer les volumes de données» semble avoir été supprimée de la documentation Docker :-(
SteveC
2
@Datz c'est juste une commande appelée pour créer le conteneur de données, il peut s'agir de n'importe quelle commande qui ne fait rien. Le conteneur démarre et se ferme immédiatement, mais il est utilisé pour conserver les données.
tommasop le
1
@rszalski Si pour une raison quelconque, vous avez besoin que le conteneur reste en cours d'exécution (par exemple, vous voulez y docker execentrer), alors une simple commande est tail -f /dev/nullqui ne se terminera jamais, mais utilise des ressources minimales. Lorsque vous n'en aurez plus besoin, docker stop data-containerje le ferai pour vous. Les volumes restent pour les autres conteneurs.
Jesse Chisholm
16

Vous pouvez exporter le volume vers tar et le transférer vers une autre machine. Et importez les données avec tar sur la deuxième machine. Cela ne dépend pas des détails d'implémentation des volumes.

# you can list shared directories of the data container
docker inspect <data container> | grep "/vfs/dir/"

# you can export data container directory to tgz
docker run --cidfile=id.tmp --volumes-from <data container> ubuntu tar -cO <volume path> | gzip -c > volume.tgz

# clean up: remove exited container used for export and temporary file
docker rm `cat id.tmp` && rm -f id.tmp
Jiri
la source
Merci pour votre réponse. Comment puis-je déplacer le conteneur de données d'un hôte à un autre?
Dzung Nguyen
1
@nXqd Le conteneur de données est créé par docker run -v /data-volume -name datacointainer busybox true- vous pouvez l'exécuter n'importe où. Après avoir créé le conteneur de données, vous pouvez importer une archive tar comme expliqué dans la réponse.
Jiri
Merci pour votre réponse. Mais j'ai rencontré un autre problème dont nous avons besoin pour supprimer le conteneur zombie qui est utilisé pour la sauvegarde par la suite. Puisque cela ne renvoie pas id. Avez-vous un bon moyen: D
Dzung Nguyen
@nXqd Bien sûr - vous devez utiliser --cidfile=id.txtcomme paramètre d'exécution. L'ID du conteneur sera stocké dans le fichier id.txt. J'ai mis à jour la réponse.
Jiri
9
Vous pouvez simplement utiliser à la docker run --rmplace de docker run --cidfile ... ; docker rm.
Felix Rabe
16

En étendant la réponse officielle des documents Docker et la réponse principale ici , vous pouvez avoir les alias suivants dans votre .bashrc ou .zshrc

# backup files from a docker volume into /tmp/backup.tar.gz
function docker-volume-backup-compressed() {
  docker run --rm -v /tmp:/backup --volumes-from "$1" debian:jessie tar -czvf /backup/backup.tar.gz "${@:2}"
}
# restore files from /tmp/backup.tar.gz into a docker volume
function docker-volume-restore-compressed() {
  docker run --rm -v /tmp:/backup --volumes-from "$1" debian:jessie tar -xzvf /backup/backup.tar.gz "${@:2}"
  echo "Double checking files..."
  docker run --rm -v /tmp:/backup --volumes-from "$1" debian:jessie ls -lh "${@:2}"
}
# backup files from a docker volume into /tmp/backup.tar
function docker-volume-backup() {
  docker run --rm -v /tmp:/backup --volumes-from "$1" busybox tar -cvf /backup/backup.tar "${@:2}"
}
# restore files from /tmp/backup.tar into a docker volume
function docker-volume-restore() {
  docker run --rm -v /tmp:/backup --volumes-from "$1" busybox tar -xvf /backup/backup.tar "${@:2}"
  echo "Double checking files..."
  docker run --rm -v /tmp:/backup --volumes-from "$1" busybox ls -lh "${@:2}"
}

Notez que la sauvegarde est enregistrée dans /tmp, vous pouvez donc déplacer le fichier de sauvegarde qui y est enregistré entre les hôtes du docker.

Il existe également deux paires d'alias de sauvegarde / restauration. L'un utilisant la compression et debian: jessie et d'autres sans compression mais avec busybox. Privilégiez l'utilisation de la compression si les fichiers à sauvegarder sont volumineux.

Luís Bianchin
la source
3

Je vais ajouter ici un autre outil récent d'IBM qui est en fait conçu pour la migration de volume d'un hôte de conteneur à un autre. C'est un projet actuellement en cours. Ainsi, vous trouverez peut-être une version différente avec des fonctionnalités supplémentaires à l'avenir.

Cargo a été développé pour migrer les conteneurs d'un hôte à un autre avec leurs données avec un temps d'arrêt minimal. Cargo utilise les capacités de fédération de données du système de fichiers union pour créer une vue unifiée des données (principalement le système de fichiers racine) sur les hôtes source et cible. Cela permet à Cargo de démarrer un conteneur presque immédiatement (en quelques millisecondes) sur l'hôte cible lorsque les données du système de fichiers racine source sont copiées vers les hôtes cibles à la demande (en utilisant une partition de copie à l'écriture (COW) ) ou paresseux en arrière-plan (en utilisant rsync) .

Les points importants sont: - un centralizedserveur gère le processus de migration

Le lien vers le projet est donné ici:

https://github.com/nadgowdas/cargo
Arif A.
la source
3

Dans le cas où vos machines sont dans des VPC différents ou si vous souhaitez copier depuis / vers une machine locale (comme dans mon cas), vous pouvez utiliser dvsync que j'ai créé. C'est fondamentalement ngrok combiné avec rsyncplus de SSH emballé dans deux petites images (les deux ~ 25 Mo). Tout d'abord, vous démarrez le dvsync-serversur une machine à partir de laquelle vous souhaitez copier des données (vous aurez besoin du NGROK_AUTHTOKENqui peut être obtenu à partir du tableau de bord ngrok ):

$ docker run --rm -e NGROK_AUTHTOKEN="$NGROK_AUTHTOKEN" \
  --mount source=MY_VOLUME,target=/data,readonly \
  quay.io/suda/dvsync-server

Ensuite, vous pouvez démarrer le dvsync-clientsur la machine sur laquelle vous souhaitez copier les fichiers, en passant le DVSYNC_TOKENaffiché par le serveur:

docker run -e DVSYNC_TOKEN="$DVSYNC_TOKEN" \
  --mount source=MY_TARGET_VOLUME,target=/data \
  quay.io/suda/dvsync-client 

Une fois la copie terminée, le client quittera. Cela fonctionne également avec Docker CLI, Compose, Swarm et Kubernetes.

suda
la source