Fundamentos y usos prácticos de Docker

Clase 5 : Persistencia de datos

Temas de clase 5:

Persistencia de datos

Laboratorios

Exportar clase

Persistencia de datos

Volúmenes y bind mounts

Persistencia de datos

En Docker, el manejo del almacenamiento es crucial para persistir datos más allá del ciclo de vida de un contenedor. Dado que los contenedores son efímeros y todos los cambios de archivos dentro de un contenedor se pierden cuando el contenedor se elimina, Docker ofrece varias opciones para persistir estos datos de manera segura. La Doc los llama de forma abarcativa como mounts.

Tipos de Mounts

Docker soporta tres tipos de mounts:

  • Volumes
  • Bind Mounts
  • tmpfs mounts

Docker Docs: Manage data in Docker

Volumes

Los volúmenes son el mecanismo preferido para conservar los datos generados y utilizados por los contenedores Docker *[1].

  • Son gestionados completamente por Docker
  • Se almacenan en una ubicación específica en el host /var/lib/docker/volumes/
  • Pueden ser creados explícitamente o al momento de crear un contenedor o mediante un archivo compose.

Volumes: Ventajas

  • Podemos administrar volúmenes utilizando los comandos de Docker CLI o la API de Docker.
  • Funciona en contenedores Linux y Windows
  • Los volúmenes se pueden compartir de forma más segura entre varios contenedores.
  • Los volumes permiten almacenarse en hosts remotos o proveedores de nube, cifrar el contenido de los volúmenes o agregar otras funciones. (AWS S3, CIFS/Samba, NFS, Block devices, etc)
  • Buena performance I/O
  • Los volumes en Docker Desktop tiene una mejor performance en host Windows y Mac.
  • Tienen diversas opciones de configuración como permisos, conectar a comparticiones de red y servicios en la nube, etc.
  • Fácil de realizar backups, restores y migraciones. [1]
  • Es posible montar una parte de volumen (subdirectorio) a un contenedor. [2]

Docker Docs: Volumes

Bind Mounts

  • Montan un directorio específico del host en un contenedor.
  • Se definen con rutas absolutas (o relativas) del sistema de archivos del host.
  • Ofrecen más flexibilidad pero menos aislamiento, ya que exponen directorios específicos del host al contenedor.
  • Datos fácilmente accesible, pero menor seguridad.
  • No hace falta crear volumenes, simplemente toma los datos del filesystem del host.

Docker Docs: Bind mounts

tmpfs Mounts

  • Montan un sistema de archivos en memoria.
  • Son útiles para datos temporales que no deben persistir entre reinicios del contenedor.

Limitaciones:

  • No es posible compartir tmpfs mounts entre contenedores
  • Solo está disponible en host Linux

Docker Docs: tmpfs mounts

Consultas

Gestión de volumenes Docker

Comandos básicos

Crear volumenes

Docker nos provee mecanismos desde la Docker CLI para gestionar volúmenes. Vamos a crear un volumen llamado "my_volume".


                        docker volume create my_volume
                    

Listar volumenes


                        docker volume ls
                    

Docker Docs: volume create

Docker Docs: volume ls

Montar volumenes

Si usamos el comando docker run, podemos elegir entre los flags --mount y --volume.


                        docker run --mount type=volume,src=<volume-name>,dst=<mount-path>
                        docker run --volume <volume-name>:<mount-path>
                    

Docker Docs: volume syntax

Montar volumenes, readonly

Diferencias entre --mount y --volume


                        docker run -d \
                          -v ng-vol:/usr/share/nginx/html:ro \
                          nginx:latest
                    

                        docker run -d \
                          --mount source=ng-vol,destination=/usr/share/nginx/html,readonly \
                          nginx:latest
                    

El flag ro es un alias de readonly. Con esas opciones indicamos que el contenedor no podrá modificar el contenido del volumen.

Docker Docs: mount options

Docker Docs: volume options

Docker Docs: use a read-only volume

Montar volumenes en contenedores

Vamos a montar el volumen my_volume en un contenedor.

                            docker run --rm -it -v my_volume:/home alpine sh
                        
Ahora hagamos un cambio en el volumen y salimos del contenedor

                        touch /home/mensaje.txt # Creamos un archivo vacío mensaje.txt
                        exit # Salimos del contenedor. Se borrará --rm
                    
Ejecutamos un contenedor completamente diferente con el mismo volumen montado.

                        docker run --rm -it -v my_volume:/home ubuntu bash
                        ls -l /home
                    
¿Qué ha ocurrido? Hemos logrado persistir datos y montar el volumen en otro contenedor completamente diferente.

Docker Docs: mount

Volumes: Datos pre-existentes

Los volumes se montan sobre un path o directorio (punto de montaje) de Linux. Ese lugar en el filesystem del contenedor puede tener datos pre-existentes o no.

  • Si montamos un volumen vacío sobre un punto de montaje con datos pre-existentes, los datos se copiarán automáticamente al volumen.
  • Si montamos un volumen con datos sobre un punto de con datos pre-existentes, los datos pre-existentes se "enmascaran" por los datos del volumen. (Los datos que son enmascarados no se borran).
  • En Docker no hay una forma sencilla de desmontar un volumen. Si queremos acceder a esos datos que fueron "enmascarados" por el volumen, lo mejor es recrear el contenedor sin montar el volumen.
  • Si al iniciar un contenedor especificamos un volumen que no existe, Docker lo creará automáticamente.

Docker Docs: Mounting a volume over existing data

Montar bind mounts

Podemos montar directorios del host en el contenedor.


                        docker run --rm -v ./carpeta:/app -it alpine sh
                    

Si estamos en Windows el comando es diferente:.


                        docker run --rm -v "${PWD}/carpeta:/app" -it alpine sh
                    

En ambos casos, el directorio carpeta se monta en el contenedor en la ruta /app. Y los cambios que hagamos en la carpeta del host se verán reflejados en el contenedor.

Docker Docs: bind mounts

eliminar volumen

No debe haber ningún contenedor utilizando el volumen. Antes de eliminar el volumen, probablemente tengamos que eliminar los contenedores que lo tengan montado aunque no estén corriendo.


                        docker volume rm VOLUME_NAME
                    

Docker Docs: volume rm

Eliminar volumenes utilizados


                        docker volume prune
                    

Docker Docs: volume prune

Inspeccionar volumen


                        docker volume inspect VOLUME_NAME
                    
Info brindada:

                                "CreatedAt": "2024-08-23T09:49:48-03:00",
                                "Driver": "local",
                                "Labels": null,
                                "Mountpoint": "/var/lib/docker/volumes/my_volume/_data",
                                "Name": "my_volume",
                                "Options": null,
                                "Scope": "local"
                    

Docker Docs: volume inspect

Copiar archivos a contenedores

Podemos copiar contenido de nuestro host hacia un contenedor con el comando docker cp [OPTIONS] [PATH] CONTAINER:/[DESTINATION]


                        docker cp config.json contenedor_prueba:/mnt
                    

O a la inversa, copiar desde el contenedor hacia el host invirtiendo los paths


                        docker cp contenedor_prueba:/mnt/config.json .
                    

Esto no es exclusivo de los volúmenes. Se pueden copiar a cualquier path del contenedor por mas que no tenga un volumen montado.

Docker Docs: container cp

Consultas

Actividad de práctica:

  • Lab 5.1 Persistencia de datos en Docker
  • Lab 5.2 Backup y Migración de Volúmenes