¿Cómo transferir volúmenes de solo datos de un host a otro?

121

Como se describe en la documentación de Docker sobre cómo trabajar con volúmenes, existe el concepto de los denominados contenedores de solo datos , que proporcionan un volumen que se puede montar en varios otros contenedores, sin importar si el contenedor de solo datos se está ejecutando o no.

Básicamente, esto suena genial. Pero hay una cosa que no entiendo.

Estos volúmenes (que no se asignan explícitamente a una carpeta en el host por razones de portabilidad, como indica la documentación) son creados y administrados por Docker en alguna carpeta interna en el host ( /var/docker/volumes/…).

Supongamos que utilizo un volumen de este tipo y luego necesito migrarlo de un host a otro, ¿cómo transfiero el volumen? AFAICS tiene una ID única: ¿puedo simplemente copiar el volumen y su contenedor de solo datos correspondiente a un nuevo host? ¿Cómo averiguo qué archivos copiar? ¿O hay algún soporte integrado en Docker que aún no descubrí?

Golo Roden
fuente
12
Puede exportar el directorio del contenedor de datos: docker run --volumes-from <data container> ubuntu tar -cO <volume path> | gzip -c > volume.tgzesto no depende de los detalles de implementación de los volúmenes. E importe los datos con alquitrán en la segunda máquina.
Jiri
1
¡Guau, eso es increíble, gracias :-)))! Si escribe este comentario como respuesta, ¡lo aceptaré con mucho gusto!
Golo Roden

Respuestas:

136

La respuesta oficial está disponible en la sección "Copia de seguridad, restauración o migración de volúmenes de datos" :

APOYO:

sudo docker run --rm --volumes-from DATA -v $(pwd):/backup busybox tar cvf /backup/backup.tar /data
  • --rm: retire el contenedor cuando salga
  • --volumes-from DATA: adjuntar a los volúmenes compartidos por el contenedor de DATOS
  • -v $(pwd):/backup: enlaza montar el directorio actual en el contenedor; para escribir el archivo tar en
  • busybox: una imagen pequeña más simple, buena para un mantenimiento rápido
  • tar cvf /backup/backup.tar /data: crea un archivo tar sin comprimir de todos los archivos en el directorio / data

RESTAURAR:

# 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
fuente
3
Por ahora, es mejor utilizar docker createcontenedores de solo datos para que no se inicien. Vea el ejemplo en el apagado. documentación: docs.docker.com/userguide/dockervolumes/…
FelikZ
1
Así que ... Si yo estoy tratando de copia de seguridad de una base de datos PostgreSQL, lo que iba a reemplazar /datacon /var/lib/postgresql/data, correcto?
425nesp
6
La sección "Copia de seguridad, restauración o migración de volúmenes de datos" parece que se ha eliminado de la documentación de Docker :-(
SteveC
2
@Datz es solo un comando llamado para crear el contenedor de datos, podría ser cualquier comando que en realidad no haga nada. El contenedor se inicia y sale inmediatamente, pero se utiliza para conservar los datos.
Tommasop
1
@rszalski Si, por alguna razón, necesita que el contenedor permanezca ejecutándose (digamos, quiere docker execentrar en él), entonces un comando simple es el tail -f /dev/nullque nunca saldrá, pero usa recursos mínimos. Cuando ya no lo necesite, docker stop data-containerlo hará por usted. Los volúmenes quedan para otros contenedores.
Jesse Chisholm
16

Puede exportar el volumen a alquitrán y transferirlo a otra máquina. E importe los datos con alquitrán en la segunda máquina. Esto no depende de los detalles de implementación de los volúmenes.

# 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
fuente
gracias por tu respuesta. ¿Cómo puedo mover el contenedor de datos de un host a otro?
Dzung Nguyen
1
@nXqd El contenedor de datos es creado por docker run -v /data-volume -name datacointainer busybox true: puede ejecutarlo en cualquier lugar. Después de crear el contenedor de datos, puede importar el archivo tar como se explica en la respuesta.
Jiri
Gracias por tu respuesta. Pero encontré otro problema que necesitamos para eliminar el contenedor zombie que se usa para hacer una copia de seguridad después. Dado que esto no devuelve id. ¿Tiene alguna buena manera: D
Dzung Nguyen
@nXqd Claro, tienes que usarlo --cidfile=id.txtcomo parámetro de ejecución. El ID del contenedor se almacenará en el archivo id.txt. He actualizado la respuesta.
Jiri
9
Podrías usar en docker run --rmlugar de docker run --cidfile ... ; docker rm.
Felix Rabe
16

Extendiendo la respuesta oficial de los documentos de Docker y la respuesta principal aquí , puede tener los siguientes alias en su .bashrc o .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}"
}

Tenga en cuenta que la copia de seguridad se guarda en /tmp, por lo que puede mover el archivo de copia de seguridad guardado allí entre los hosts de Docker.

También hay dos pares de alias de copia de seguridad / restauración. Uno usando compresión y debian: jessie y otro sin compresión pero con busybox. Favorezca el uso de compresión si los archivos de la copia de seguridad son grandes.

Luís Bianchin
fuente
3

Agregaré aquí otra herramienta reciente de IBM que en realidad está hecha para la migración de volumen de un host de contenedor a otro. Este es un proyecto actualmente en curso. Por lo tanto, puede encontrar una versión diferente con características adicionales en el futuro.

Cargo se desarrolló para migrar contenedores de un host a otro junto con sus datos con un tiempo de inactividad mínimo. Cargo utiliza las capacidades de federación de datos del sistema de archivos de unión para crear una vista unificada de los datos (principalmente el sistema de archivos raíz) en los hosts de origen y destino. Esto permite que Cargo inicie un contenedor casi de inmediato (en milisegundos) en el host de destino a medida que los datos del sistema de archivos raíz de origen se copian en los hosts de destino, ya sea a pedido (usando una partición de copia en escritura (COW) ) o de manera perezosa en segundo plano (usando rsync) .

Los puntos importantes son: - un centralizedservidor maneja el proceso de migración

El enlace al proyecto se proporciona aquí:

https://github.com/nadgowdas/cargo
Arif A.
fuente
3

En caso de que sus máquinas estén en diferentes VPC o si desea copiar desde / hacia una máquina local (como en mi caso), puede usar dvsync que he creado. Básicamente es ngrok combinado con rsyncmás de SSH empaquetado en dos imágenes pequeñas (ambas ~ 25 MB). Primero, inicie dvsync-serveren una máquina de la que desea copiar datos (necesitará el NGROK_AUTHTOKENque se puede obtener del panel de ngrok ):

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

Luego puede iniciar el dvsync-clienten la máquina en la que desea copiar los archivos, pasando lo que DVSYNC_TOKENmuestra el servidor:

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

Una vez que se haya realizado la copia, el cliente saldrá. Esto también funciona con Docker CLI, Compose, Swarm y Kubernetes.

suda
fuente