Introducción
Docker es una herramienta popular de creación de contenedores que se utiliza para proporcionar aplicaciones de software con un sistema de archivos que contiene todo lo que necesitan para ejecutarse. El uso de contenedores Docker garantiza que el software se comportará de la misma manera independientemente de dónde se implemente porque su entorno de tiempo de ejecución es coherente.
En general, los contenedores de Docker son efímeros y se ejecutan el tiempo que tarda en completarse el comando emitido en el contenedor. A veces, sin embargo, las aplicaciones necesitan compartir el acceso a los datos o conservar los datos después de eliminar un contenedor. Las bases de datos, el contenido generado por el usuario para un sitio web y los archivos de registro son solo algunos ejemplos de datos que no son prácticos o son imposibles de incluir en una imagen de Docker, pero a los que las aplicaciones deben acceder. El acceso persistente a los datos se proporciona con Docker Volumes.
Los volúmenes de Docker se pueden crear y adjuntar en el mismo comando que crea un contenedor, o se pueden crear independientemente de cualquier contenedor y adjuntarse más tarde. En este artículo, verá cuatro formas diferentes de compartir datos entre contenedores.
Requisitos
Para seguir este artículo, necesitará un servidor Ubuntu 22.04 con lo siguiente:
- Un usuario no root con privilegios sudo. La guía Configuración inicial del servidor con Ubuntu 22.04 explica cómo configurarlo.
- Docker instalado con las instrucciones del Paso 1 y Paso 2 de Cómo instalar y usar Docker en Ubuntu 22.04
docker
los comandos para los volúmenes de datos de Docker en este artículo deberían funcionar en otros sistemas operativos siempre que Docker esté instalado y el usuario sudo se haya agregado a docker
grupo.
Paso 1:creación de un volumen independiente
Introducido en la versión 1.9 de Docker, docker volume create
El comando le permite crear un volumen sin relacionarlo con ningún contenedor en particular. Usará este comando para agregar un volumen llamado DataVolume1
:
- docker volume create --name DataVolume1
Se muestra el nombre, lo que indica que el comando fue exitoso:
OutputDataVolume1
Para hacer uso del volumen, creará un nuevo contenedor a partir de la imagen de Ubuntu, usando --rm
marca para eliminarlo automáticamente cuando salga. También usará -v
para montar el nuevo volumen. -v
requiere el nombre del volumen, dos puntos, luego la ruta absoluta a donde debe aparecer el volumen dentro del contenedor. Si los directorios de la ruta no existen como parte de la imagen, se crearán cuando se ejecute el comando. Si lo hacen existe, el volumen montado ocultará el contenido existente:
- docker run -ti --rm -v DataVolume1:/datavolume1 ubuntu
Mientras esté en el contenedor, escriba algunos datos en el volumen:
- echo "Example1" > /datavolume1/Example1.txt
Porque usaste el --rm
marca, su contenedor se eliminará automáticamente cuando salga. Su volumen, sin embargo, seguirá siendo accesible.
- exit
Puede verificar que el volumen está presente en su sistema con docker volume inspect
:
- docker volume inspect DataVolume1
Output[
{
"CreatedAt": "2018-07-11T16:57:54Z",
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/DataVolume1/_data",
"Name": "DataVolume1",
"Options": {},
"Scope": "local"
}
]
Mountpoint
. Sin embargo, debe evitar modificarlo, ya que puede dañar los datos si las aplicaciones o los contenedores desconocen los cambios.
A continuación, inicie un nuevo contenedor y adjunte DataVolume1
:
- docker run --rm -ti -v DataVolume1:/datavolume1 ubuntu
Verifica el contenido:
- cat /datavolume1/Example1.txt
OutputExample1
Salga del contenedor:
- exit
En este ejemplo, creó un volumen, lo adjuntó a un contenedor y verificó su persistencia.
Paso 2:Creación de un volumen que persiste cuando se quita el contenedor
En el siguiente ejemplo, creará un volumen al mismo tiempo que el contenedor, eliminará el contenedor y luego adjuntará el volumen a un nuevo contenedor.
Usarás el docker run
comando para crear un nuevo contenedor usando la imagen base de Ubuntu. -t
nos dará una terminal, y -i
nos permitirá interactuar con él. Para mayor claridad, utilizará --name
para identificar el contenedor.
El -v
flag nos permitirá crear un nuevo volumen, al que llamarás DataVolume2
. Utilizará dos puntos para separar este nombre de la ruta donde se debe montar el volumen en el contenedor. Finalmente, especificará la imagen base de Ubuntu y confiará en el comando predeterminado en el archivo Docker de la imagen base de Ubuntu, bash
, para dejarnos caer en un caparazón:
- docker run -ti --name=Container2 -v DataVolume2:/datavolume2 ubuntu
-v
La bandera es muy flexible. Puede enlazar, montar o nombrar un volumen con solo un ligero ajuste en la sintaxis. Si el primer argumento comienza con un /
o ~/
estás creando un bindmount. Quita eso, y estás nombrando el volumen. Por ejemplo:
-v /path:/path/in/container
monta el directorio host,/path
en el/path/in/container
-v path:/path/in/container
crea un volumen llamadopath
sin relación con el anfitrión.
Para obtener más información sobre el montaje de un directorio desde el host, consulte Cómo compartir datos entre un contenedor Docker y el host
Mientras esté en el contenedor, escribirá algunos datos en el volumen:
- echo "Example2" > /datavolume2/Example2.txt
- cat /datavolume2/Example2.txt
OutputExample2
Salga del contenedor:
- exit
Cuando reinicie el contenedor, el volumen se montará automáticamente:
- docker start -ai Container2
Verifique que el volumen se haya montado y que sus datos aún estén en su lugar:
- cat /datavolume2/Example2.txt
OutputExample2
Finalmente, salga y limpie:
- exit
Docker no nos permitirá eliminar un volumen si un contenedor hace referencia a él. Para ver qué sucede, intente:
- docker volume rm DataVolume2
El mensaje nos dice que el volumen todavía está en uso y proporciona la versión larga del ID del contenedor:
OutputError response from daemon: unable to remove volume: remove DataVolume2: volume is in use - [d0d2233b668eddad4986313c7a4a1bc0d2edaf0c7e1c02a6a6256de27db17a63]
Puede utilizar el ID del mensaje de error anterior para eliminar el contenedor:
- docker rm d0d2233b668eddad4986313c7a4a1bc0d2edaf0c7e1c02a6a6256de27db17a63
Outputd0d2233b668eddad4986313c7a4a1bc0d2edaf0c7e1c02a6a6256de27db17a63
Quitar el contenedor no afectará el volumen. Puede ver que todavía está presente en el sistema enumerando los volúmenes con docker volume ls
:
- docker volume ls
OutputDRIVER VOLUME NAME
local DataVolume2
Y puedes usar docker volume rm
para eliminarlo:
- docker volume rm DataVolume2
En este ejemplo, creó un volumen de datos vacío al mismo tiempo que creó un contenedor. En su próximo ejemplo, explorará lo que sucede cuando crea un volumen con un directorio contenedor que ya contiene datos.
Paso 3:Creación de un volumen a partir de un directorio existente con datos
En general, crear un volumen de forma independiente con docker volume create
y crear uno mientras se crea un contenedor son equivalentes, con una excepción. Si crea un volumen al mismo tiempo que crea un contenedor y proporciona la ruta a un directorio que contiene datos en la imagen base, esos datos se copiarán en el volumen.
Como ejemplo, creará un contenedor y agregará el volumen de datos en /var
, un directorio que contiene datos en la imagen base:
- docker run -ti --rm -v DataVolume3:/var ubuntu
Todo el contenido del /var
de la imagen base El directorio se copia en el volumen y puede montar ese volumen en un nuevo contenedor.
Salga del contenedor actual:
- exit
Esta vez, en lugar de confiar en el bash
predeterminado de la imagen base comando, emitirá su propio ls
comando, que mostrará el contenido del volumen sin ingresar al shell:
- docker run --rm -v DataVolume3:/datavolume3 ubuntu ls datavolume3
El directorio datavolume3
ahora tiene una copia del contenido de /var
de la imagen base directorio:
Outputbackups
cache
lib
local
lock
log
mail
opt
run
spool
tmp
Es poco probable que desee montar /var/
de esta manera, pero esto puede ser útil si ha creado su propia imagen y desea una manera fácil de conservar los datos. En su siguiente ejemplo, demostrará cómo se puede compartir un volumen entre varios contenedores.
Paso 4:compartir datos entre varios contenedores Docker
Hasta ahora, ha adjuntado un volumen a un contenedor a la vez. A menudo, querrá adjuntar varios contenedores al mismo volumen de datos. Esto es relativamente sencillo de lograr, pero hay una advertencia crítica:en este momento, Docker no maneja el bloqueo de archivos. Si necesita que varios contenedores escriban en el volumen, las aplicaciones que se ejecutan en esos contenedores deben estar diseñado para escribir en almacenes de datos compartidos para evitar la corrupción de datos.
Crear Container4 y DataVolume4
Usar docker run
para crear un nuevo contenedor llamado Container4
con un volumen de datos adjunto:
- docker run -ti --name=Container4 -v DataVolume4:/datavolume4 ubuntu
A continuación, creará un archivo y agregará algo de texto:
- echo "This file is shared between containers" > /datavolume4/Example4.txt
Luego, saldrá del contenedor:
- exit
Esto nos devuelve al símbolo del sistema del host, donde creará un nuevo contenedor que monte el volumen de datos desde Container4
.
Crear Container5 y montar volúmenes desde Container4
Vas a crear Container5
y monte los volúmenes desde Container4
:
- docker run -ti --name=Container5 --volumes-from Container4 ubuntu
Compruebe la persistencia de datos:
- cat /datavolume4/Example4.txt
OutputThis file is shared between containers
Ahora, agregue algo de texto de Container5
:
- echo "Both containers can write to DataVolume4" >> /datavolume4/Example4.txt
Finalmente, saldrá del contenedor:
- exit
A continuación, verificará que sus datos aún estén presentes en Container4
.
Ver cambios realizados en Container5
Ahora, verifique los cambios que fueron escritos en el volumen de datos por Container5
reiniciando Container4
:
- docker start -ai Container4
Compruebe los cambios:
- cat /datavolume4/Example4.txt
OutputThis file is shared between containers
Both containers can write to DataVolume4
Ahora que ha verificado que ambos contenedores pudieron leer y escribir desde el volumen de datos, saldrá del contenedor:
- exit
Nuevamente, Docker no maneja ningún bloqueo de archivos, por lo que las aplicaciones deben cuenta para el bloqueo de archivos a sí mismos. Es posible montar un volumen de Docker como de solo lectura para garantizar que la corrupción de datos no ocurra por accidente cuando un contenedor requiere acceso de solo lectura agregando :ro
. Ahora verá cómo funciona esto.
Iniciar contenedor 6 y montar el volumen de solo lectura
Una vez que se ha montado un volumen en un contenedor, en lugar de desmontarlo como lo haría con un sistema de archivos típico de Linux, puede crear un nuevo contenedor montado de la manera que desee y, si es necesario, eliminar el contenedor anterior. Para hacer que el volumen sea de solo lectura, agregue :ro
al final del nombre del contenedor:
- docker run -ti --name=Container6 --volumes-from Container4:ro ubuntu
Verificará el estado de solo lectura al intentar eliminar su archivo de ejemplo:
- rm /datavolume4/Example4.txt
Outputrm: cannot remove '/datavolume4/Example4.txt': Read-only file system
Finalmente, saldrá del contenedor y limpiará sus contenedores y volúmenes de prueba:
- exit
Ahora que ha terminado, limpie sus contenedores y volumen:
- docker rm Container4 Container5 Container6
- docker volume rm DataVolume4
En este ejemplo, mostró cómo compartir datos entre dos contenedores utilizando un volumen de datos y cómo montar un volumen de datos como de solo lectura.
Conclusión
En este tutorial, creó un volumen de datos que permitió que los datos persistieran a través de la eliminación de un contenedor. Compartió volúmenes de datos entre contenedores, con la advertencia de que las aplicaciones deberán diseñarse para manejar el bloqueo de archivos para evitar la corrupción de datos. Finalmente, mostró cómo montar un volumen compartido en modo de solo lectura. Si está interesado en aprender a compartir datos entre contenedores y el sistema host, consulte Cómo compartir datos entre Docker Container y Host.