volúmenes de montaje de la ventana acoplable en el host

135

He podido compartir carpetas con éxito entre un contenedor acoplable con volúmenes usando

docker run -v /host/path:/container/path ...

Pero mi pregunta es cuál es la diferencia entre esto y usar el VOLUMEcomando en el Dockerfile

VOLUME /path

Estoy usando una imagen que tiene un VOLUMEcomando, y me gustaría saber cómo compartirla con mi host. Lo hice usando el -vcomando anterior, pero no sabía si necesitaba tanto el -vy VOLUME.

Jeff Storey
fuente

Respuestas:

155

El VOLUMEcomando montará un directorio dentro de su contenedor y almacenará todos los archivos creados o editados dentro de ese directorio en su disco host fuera de la estructura de archivos del contenedor , sin pasar por el sistema de archivos de unión.

La idea es que sus volúmenes se puedan compartir entre los contenedores de la ventana acoplable y se mantendrán mientras exista un contenedor (en ejecución o detenido) que los haga referencia.

Puede hacer que otros contenedores monten volúmenes existentes (compartiéndolos efectivamente entre contenedores) mediante el --volumes-fromcomando cuando ejecuta un contenedor.

La diferencia fundamental entre VOLUMEy -ves la siguiente: -vse montará los archivos existentes de su sistema operativo dentro de su contenedor ventana acoplable y VOLUMEserá crear un nuevo volumen, vacío en su host y montarlo dentro de su contenedor.

Ejemplo:

  1. Tiene un Dockerfile que define a VOLUME /var/lib/mysql.
  2. Construye la imagen del acoplador y la etiqueta some-volume
  3. Ejecutas el contenedor

Y entonces,

  1. Tiene otra imagen acoplable que desea usar para este volumen.
  2. Ejecuta el contenedor acoplable con lo siguiente: docker run --volumes-from some-volume docker-image-name:tag
  3. Ahora tiene un contenedor acoplable en ejecución que tendrá el volumen some-volumemontado en/var/lib/mysql

Nota: El uso --volumes-frommontará el volumen sobre lo que exista en la ubicación del volumen. Es decir, si tenía cosas /var/lib/mysql, se reemplazará con el contenido del volumen.

Chris McKinnel
fuente
12
¿Qué sucede si uso -v en un directorio que ya se especificó en VOLUME?
Jeff Storey
66
--volumes-frommontará tu VOLUMEsobre la parte superior de todo lo que especifiques -v. Curiosamente, parece que se ejecuta el contenedor en modo privilegiado ( docker run --privileged) e umounting /var/lib/mysqldejará un directorio vacío para que su -vmontaje sea completamente ignorado cuando entre en conflicto con a VOLUME.
Chris McKinnel
2
Dices que los volúmenes se mantienen siempre que un contenedor los haga referencia, y eso lo he visto en otros lugares. docs.docker.com/userguide/dockervolumes dice "Los volúmenes de datos están diseñados para conservar datos, independientemente del ciclo de vida del contenedor. Por lo tanto, Docker nunca eliminará automáticamente los volúmenes cuando elimine un contenedor, ni" recolectará basura "volúmenes que ya no son referenciado por un contenedor ". Una de estas declaraciones debe estar equivocada.
mc0e
1
Los archivos que están en el volumen se guardan en el disco cuando un contenedor ya no hace referencia a él, pero el volumen en sí ya no se puede usar (a menos que sepa exactamente cómo conectar manualmente un volumen a un contenedor, pero aun así no lo hago ' No sé si esto es posible). Cuando digo que ya no se puede usar, quiero decir que no puedes usar --volumes-from para usarlo. Cuando dicen "recolección de basura" arriba, significan eliminar los archivos de su disco que estaban en el volumen.
Chris McKinnel
1
Se pueden usar usando -v, pero no --volumes-from. Volumes-from toma un nombre de contenedor para recuperar datos de volumen (creo que toma TODOS los puntos de volumen). Para -v, sin embargo, el manual menciona que puede proporcionar un volumen con nombre a -v en forma de named-volume:/path/in/container. Los volúmenes sin nombre reciben valores hash para nombres y esos valores hash se pueden proporcionar en lugar de una ruta de host para acceder a volúmenes huérfanos. :) Tenga en cuenta que volume lspuede no mostrarlos a todos, intente docker volume ls -f dangling=truetambién.
Jasmine Hegman
44

Permítanme agregar mi propia respuesta, porque creo que a los demás les falta el punto de Docker.

Usar VOLUMEen el Dockerfile es el Right Way ™, porque le informa a Docker que cierto directorio contiene datos permanentes. Docker creará un volumen para esos datos y nunca los eliminará, incluso si elimina todos los contenedores que los usan.

También omite el sistema de archivos de unión, de modo que el volumen es de hecho un directorio real que se monta (lectura-escritura o solo lectura) en el lugar correcto en todos los contenedores que lo comparten.

Ahora, para acceder a esos datos desde el host, solo necesita inspeccionar su contenedor:

# docker inspect myapp
[{
    .
    .
    .
    "Volumes": {
        "/var/www": "/var/lib/docker/vfs/dir/b3ef4bc28fb39034dd7a3aab00e086e6...",
        "/var/cache/nginx": "/var/lib/docker/vfs/dir/62499e6b31cb3f7f59bf00d8a16b48d2...",
        "/var/log/nginx": "/var/lib/docker/vfs/dir/71896ce364ef919592f4e99c6e22ce87..."
    },
    "VolumesRW": {
        "/var/www": false,
        "/var/cache/nginx": true,
        "/var/log/nginx": true
    }
}]

Lo que generalmente hago es crear enlaces simbólicos en algún lugar estándar, como / srv , para que pueda acceder fácilmente a los volúmenes y administrar los datos que contienen (solo para los volúmenes que le interesan):

ln -s /var/lib/docker/vfs/dir/b3ef4bc28fb39034dd7a3aab00e086e6... /srv/myapp-www
ln -s /var/lib/docker/vfs/dir/71896ce364ef919592f4e99c6e22ce87... /srv/myapp-log
Tobia
fuente
¿Qué sucede si el host de Docker se ejecuta en una máquina virtual? Por ejemplo, boot2docker en mac. Entonces estos volúmenes solo están disponibles de forma remota. Además, cuando utilice volúmenes en el Dockerfile como lo describió, el contenido de la imagen se copiará en el volumen. Sin embargo, cuando se monta en un directorio local, esta copia no ocurre. ¿Sabes por qué este es el caso? ¿Hay alguna manera de tener un volumen montado localmente pero todavía 'comenzar de nuevo' con los archivos de la imagen?
LostSalad
44
con docker-compose puede hacer exactamente eso, montar un volumen en una ubicación específica del sistema operativo host . No se necesitan enlaces simbólicos ...
Hugo Koopmans
@Tobia: ejemplo docker-compose ver los documentos docs.docker.com/compose/compose-file/…
Hugo Koopmans
11

VOLUME se utiliza Dockerfilepara exponer el volumen que otros contenedores utilizarán. Ejemplo, crear Dockerfilecomo:

DE ubuntu: 14.04

RUN mkdir /myvol  
RUN echo "hello world" > /myvol/greeting  
VOLUME /myvol

construir la imagen:

$ docker build -t testing_volume .

Ejecute el contenedor, diga container1:

$ docker run -it <image-id of above image> bash

Ahora ejecute otro contenedor con la opción volume-from como (say-container2)

$ docker run -it --volumes-from <id-of-above-container> ubuntu:14.04 bash

Obtendrá todos los datos del /myvoldirectorio contenedor1 en contenedor2 en la misma ubicación.

-vLa opción se proporciona en tiempo de ejecución del contenedor que se utiliza para montar el directorio del contenedor en el host. Es simple de usar, solo proporcione la -vopción con argumento como <host-path>:<container-path>. Todo el comando puede ser como$ docker run -v <host-path>:<container-path> <image-id>

Yogesh Jilhawar
fuente
8

Básicamente VOLUMEy la -vopción son casi iguales. Esto significa 'montar un directorio específico en su contenedor'. Por ejemplo, VOLUME /datay -v /dataes exactamente el mismo significado. Si ejecuta la imagen que tiene VOLUME /datao con -v /dataopción, el /datadirectorio se monta en su contenedor. Este directorio no pertenece a su contenedor.

Imagine que agrega algunos archivos al /datacontenedor y luego confirma el contenedor en una nueva imagen. No hay ningún archivo en el directorio de datos porque el /datadirectorio montado pertenece al contenedor original.

$ docker run -it -v /data --name volume ubuntu:14.04 bash
root@2b5e0f2d37cd:/# cd /data
root@2b5e0f2d37cd:/data# touch 1 2 3 4 5 6 7 8 9
root@2b5e0f2d37cd:/data# cd /tmp
root@2b5e0f2d37cd:/tmp# touch 1 2 3 4 5 6 7 8 9
root@2b5e0f2d37cd:/tmp# exit
exit

$ docker commit volume nacyot/volume  
835cfe3d8d159622507ba3256bb1c0b0d6e7c1419ae32751ad0f925c40378945
nacyot $ docker run -it nacyot/volume
root@dbe335c7e64d:/# cd /data
root@dbe335c7e64d:/data# ls
root@dbe335c7e64d:/data# cd /tmp
root@dbe335c7e64d:/tmp# ls
1  2  3  4  5  6  7  8  9
root@dbe335c7e64d:/tmp# 
root@dbe335c7e64d:/tmp# 

Este directorio montado como /datase utiliza para almacenar datos que no pertenecen a su aplicación. Y puede predefinir el directorio de datos que no pertenece al contenedor mediante el uso VOLUME.

Una diferencia entre Volumey -vopción es que puede usar la -vopción dinámicamente al iniciar el contenedor. Significa que puede montar algún directorio dinámicamente. Y otra diferencia es que puede montar su directorio de host en su contenedor utilizando-v

nacyot
fuente
8

Esto es de la documentación de Docker en sí, podría ser de ayuda, simple y simple:

"El directorio de host es, por su naturaleza, dependiente del host. Por esta razón, no puede montar un directorio de host desde Dockerfile, la instrucción VOLUME no admite pasar un host-dir, porque las imágenes compiladas deben ser portátiles. Un host directorio no estaría disponible en todos los hosts potenciales ".

Vennesa
fuente