Sauvegarde et restauration de volume Docker

23

J'utilise Docker pour déployer certains services sur un serveur CentOS 6.4, et j'essaie de comprendre comment sauvegarder correctement les données qu'ils génèrent.

Par exemple, l'un des services est une application Web où les utilisateurs peuvent télécharger des fichiers. Pour ce conteneur, j'ai un /filesvolume que je veux sauvegarder. Les supports d'hôte semblent être quelque peu désapprouvés, car un tel support n'est en aucun cas portable - comme dit dans ce billet de blog et dans la documentation du docker pour les volumes .

Je sais du même article de blog que je n'ai pas besoin d' un montage hôte pour accéder aux fichiers d'un volume, je peux utiliser docker inspectpour savoir où se trouvent les fichiers.

Mais voici mon problème: je pensais à sauvegarder uniquement les fichiers dockerfiles nécessaires pour créer les conteneurs et les volumes qui leur sont associés. Dans le cas probable où je devrais tout restaurer à partir de la sauvegarde, comment pourrais-je savoir quel répertoire de volume correspond à quel conteneur? La reconstruction du conteneur entraîne la modification de l'ID et du chemin du volume, j'ai donc besoin d'informations supplémentaires pour les faire correspondre. Quoi d'autre, le cas échéant, dois-je sauvegarder pour pouvoir tout restaurer?

fcoelho
la source

Réponses:

24

Tu as raison. Étant donné que vous pouvez avoir plusieurs conteneurs avec des volumes à eux seuls, vous devez garder une trace du volume correspondant à quel conteneur. La façon de procéder dépend de votre configuration: j'utilise le nom -data pour le conteneur de données, il est donc évident à quel conteneur appartient une image. De cette façon, il peut être sauvegardé comme ceci:

VOLUME=`docker inspect $NAME-data | jq '.[0].Volumes["/path/in/container"]'`
tar -C $VOLUME . -czvf $NAME.tar.gz

Il ne vous reste plus qu'à reconstruire votre image et recréer votre conteneur de données:

cat $NAME.tar.gz | docker run -name $NAME-data -v /path/in/container \
                              -i busybox tar -C /path/int/container -xzf -

Cela signifie donc que vous devez sauvegarder:

  • Dockerfile
  • le volume
  • chemin de volume dans le conteneur
  • nom du conteneur auquel appartient le volume

Mise à jour: En attendant, j'ai créé un outil pour sauvegarder les conteneurs et leurs volumes (conteneur (s)): https://github.com/discordianfish/docker-backup et une image de sauvegarde qui peut créer des sauvegardes et les pousser vers s3: https://github.com/discordianfish/docker-lloyd

Johannes 'fish' Ziemke
la source
C'est un juste compromis, merci. Y a-t-il un avantage évident à utiliser un conteneur séparé pour les données?
fcoelho
Cela dépend encore une fois de votre configuration. Il est logique d'utiliser un conteneur de données, car vous pouvez facilement vous y référer en utilisant `` volumes-from '' et avoir tous les éléments internes abstraits: vous attachez simplement les volumes du conteneur à d'autres conteneurs au lieu de penser en termes de chemin et de points de montage.
Johannes 'fish' Ziemke
J'ai cette option non valide d'erreur - z. Il semble que le tar par défaut dans busybox ne le supporte pas.
Dzung Nguyen
6
JQ est très cool, mais plutôt que d' introduire une dépendance, pourquoi ne pas utiliser docker inspects construit en Templating comme ceci: VOLUME=$( docker inspect -f '{{index .Volumes "/path/in/container"}}' "${NAME}-data" ). Il est probablement également judicieux de rappeler aux gens de ne pas s'attendre à sauvegarder des fichiers de cette manière lorsqu'ils sont activement utilisés (par exemple, des bases de données).
mc0e
2
Dans Docker 1.8, le format a changé - Volumesont disparu et il existe à la Mountsplace avec une structure différente. Nous devons travailler un peu plus rangepour trouver le point de montage qui nous intéresseVOLUME=$(docker inspect --format '{{ range .Mounts }}{{ if eq .Destination "/path/in/container" }}{{ .Source }}{{ end }}{{ end }}' "${NAME}-data")
Jarek Przygódzki
5

Dans Docker plus récent (testé dans 1.9.1, build 9894698), vous pouvez utiliser la cpcommande .

Voici un exemple de copie d'un répertoire du conteneur vers l'hôte:

docker cp wordpress:/var/www/html backups/wordpress.`date +"%Y%m%d"`/

Voici un exemple de copie d'un répertoire du conteneur vers un tarfichier:

docker cp wordpress:/var/www/html - > backups/wordpress.`date +"%Y%m%d"`.tar

Dernier exemple mais non le moindre, comment copier un répertoire du conteneur vers un tar.gzfichier:

docker cp wordpress:/var/www/html - | gzip > backups/wordpress.`date +"%Y%m%d"`.tar.gz
czerasz
la source
2
docker cpenvoie tout sur le réseau. C'est quelque chose que vous voulez éviter, surtout si votre volume Docker est déjà un volume btrfs.
Jarek Przygódzki
2
La question mentionne la sauvegarde et la restauration . Un exemple de restauration dans cette réponse en utilisant docker cpserait bien.
MadMike