docker - run - acoplador de volúmenes de montaje en el host
download docker image (5)
Pude compartir con éxito carpetas 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 comando VOLUME
en el Dockerfile
VOLUME /path
Estoy usando una imagen que tiene un comando de VOLUME
, y me gustaría saber cómo compartirlo con mi anfitrión. Lo hice usando el comando -v
anterior, pero no sabía si necesitaba tanto el -v
como el VOLUME
.
Básicamente VOLUME
y la opción -v
son casi iguales. Esto significa ''montar un directorio específico en su contenedor''. Por ejemplo, VOLUME /data
y -v /data
tienen exactamente el mismo significado. Si ejecuta la imagen que tiene VOLUME /data
o con -v /data
opción -v /data
, /data
directorio de /data
está montado en su contenedor. Este directorio no pertenece a su contenedor.
Imagine que agrega algunos archivos a /data
en el contenedor y luego asigna el contenedor a una nueva imagen. No hay ningún archivo en el directorio de datos porque el directorio montado /data
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 como /data
montado se usa para almacenar datos que no pertenecen a su aplicación. Y puede predefinir el directorio de datos que no pertenece al contenedor utilizando VOLUME
.
Una diferencia entre la opción Volume
y -v
es que puede usar la opción -v
dinámicamente en el contenedor de inicio. Significa que puedes montar un directorio dinámicamente. Y otra diferencia es que puede montar su directorio de host en su contenedor utilizando -v
El comando VOLUME
montará un directorio dentro de su contenedor y almacenará cualquier archivo creado o editado dentro de ese directorio en el disco de su host fuera de la estructura del archivo del contenedor , sin pasar por el sistema de archivos de la unión.
La idea es que los volúmenes se puedan compartir entre los contenedores de docker y se mantendrán mientras haya un contenedor (en ejecución o detenido) que haga referencia a ellos.
Puede hacer que otros contenedores monten volúmenes existentes (compartiéndolos efectivamente entre contenedores) utilizando el --volumes-from
cuando ejecuta un contenedor.
La diferencia fundamental entre VOLUME
y -v
es la siguiente: -v
montará los archivos existentes de su sistema operativo dentro de su contenedor de docker y VOLUME
creará un nuevo volumen vacío en su host y lo montará dentro de su contenedor.
Ejemplo:
- Tienes un Dockerfile que define un
VOLUME /var/lib/mysql
. - Usted construye la imagen del acoplador y la etiqueta con un
some-volume
- Usted ejecuta el contenedor
Y entonces,
- Tiene otra imagen acoplable que desea usar este volumen
- Ejecuta el contenedor docker con lo siguiente:
docker run --volumes-from some-volume docker-image-name:tag
- Ahora tiene un contenedor acoplable que tendrá el volumen de
some-volume
montado en/var/lib/mysql
Nota: El uso de --volumes-from
montará el volumen sobre cualquier cosa que exista en la ubicación del volumen. Es decir, si tuviera cosas en /var/lib/mysql
, se reemplazará con el contenido del volumen.
Esto es de la documentación de Docker en sí misma, 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 creadas deberían ser portátiles. directorio no estaría disponible en todos los hosts potenciales ".
Permítanme agregar mi propia respuesta, porque creo que a los demás les falta el sentido de Docker.
Usar VOLUME
en el archivo Docker es el Right Way ™, porque le informa a Docker que un determinado directorio contiene datos permanentes. Docker creará un volumen para esa información y nunca la eliminará, incluso si elimina todos los contenedores que la usan.
También pasa por alto 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 suelo hacer es crear enlaces simbólicos en algún lugar estándar como / srv , de modo 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
VOLUME se usa en Dockerfile
para exponer el volumen que otros contenedores usarán. Ejemplo, crea Dockerfile
como:
DESDE 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 de volúmenes desde (como-contenedor2)
$ docker run -it --volumes-from <id-of-above-container> ubuntu:14.04 bash
Obtendrá todos los datos del directorio container1 /myvol
en container2 en la misma ubicación.
-v
opción -v
se proporciona en el tiempo de ejecución del contenedor que se usa para montar el directorio del contenedor en el host. Es simple de usar, solo proporciona la opción -v
con argumento como <host-path>:<container-path>
. El comando completo puede ser como $ docker run -v <host-path>:<container-path> <image-id>