Tema:
Utilizando Almacenamiento Persistente en Contenedores Docker
Introducción
El almacenamiento persistente en contenedores Docker es un tema crucial para garantizar la durabilidad de los datos generados y consumidos por las aplicaciones que se ejecutan en contenedores. Aunque los contenedores son efímeros por naturaleza, muchas aplicaciones requieren mantener datos más allá del ciclo de vida de un contenedor, como bases de datos, configuraciones, archivos de usuario, y más.
En este tema exploraremos cómo Docker maneja el almacenamiento, las opciones disponibles para configurar volúmenes persistentes y montajes, así como las mejores prácticas para garantizar la integridad, escalabilidad y seguridad de los datos. Esto permitirá a los participantes comprender y aplicar estrategias de almacenamiento para soportar aplicaciones más complejas y críticas en entornos de producción.
Objetivo
Objetivo General:
- Proveer a los participantes los conocimientos y habilidades necesarios para configurar y gestionar almacenamiento persistente en contenedores Docker, garantizando la durabilidad y disponibilidad de los datos en aplicaciones contenerizadas. Los participantes aprenderán a identificar las diferentes opciones de almacenamiento, implementar volúmenes y montajes en diversos escenarios, y aplicar las mejores prácticas para integrar almacenamiento persistente de manera efectiva en entornos de contenedores.
Opciones de Almacenamiento persistente
Existen dos formas de proporcionar almacenamiento persistente a los contenedores:
- Volumes
- Bind mounts
Los volúmenes son el mecanismo preferido para conservar los datos generados y utilizados por los contenedores de Docker. Si bien los Bind mounts dependen de la estructura de directorios y del sistema operativo de la máquina host, los volúmenes son completamente administrados por Docker. Los volúmenes tienen varias ventajas sobre los montajes de enlace:
- Es más fácil realizar copias de seguridad o migrar volúmenes que montajes enlazados.
- Puede administrar volúmenes mediante los comandos CLI de Docker o la API de Docker.
- Los volúmenes funcionan en contenedores de Linux y Windows.
- Los volúmenes se pueden compartir de forma más segura entre varios contenedores.
- Además, los volúmenes suelen ser una mejor opción que persistir los datos en la capa escribible de un contenedor, porque un volumen no aumenta el tamaño de los contenedores que lo utilizan y el contenido del volumen existe fuera del ciclo de vida de un contenedor determinado.
🚀 Diferencia entre docker run -v y docker run --mount
Las opciones -v y --mount en docker run se utilizan para adjuntar volúmenes o directorios a un contenedor, pero tienen diferencias clave en cuanto a sintaxis, flexibilidad y usabilidad.
🔹 Diferencias entre -v y --mount
| Opción | -v (o --volume) |
--mount |
|---|---|---|
| Sintaxis | -v <host_path>:<container_path>[:opciones] |
--mount type=<tipo>,source=<host_path>,target=<container_path>,<opciones> |
| Facilidad de uso | Más corta, útil para configuraciones rápidas. | Más descriptiva y flexible. |
| Soporte de opciones | Soporta ro (solo lectura), rw (lectura/escritura) y z/Z para SELinux. |
Soporta readonly, bind-propagation, tmpfs-size, etc. |
| Compatibilidad con Docker Compose | Se usa en docker-compose.yml pero con sintaxis diferente. |
Se prefiere en docker-compose para mayor claridad. |
| Mejor práctica | Útil para compatibilidad con versiones anteriores de Docker. | Se recomienda para nuevas implementaciones. |
🔹 Ejemplos de Uso
1️⃣ Usando -v (opción más antigua y compacta)
docker run -v /host/data:/container/data:ro ubuntu
- Monta el directorio
/host/datadel host en/container/datadentro del contenedor. ro(opcional) indica que el volumen es solo lectura.
2️⃣ Usando --mount (más descriptivo y flexible)
docker run --mount type=bind,source=/host/data,target=/container/data,readonly \
ubuntu
type=bindindica que se monta un directorio del host.source=/host/dataespecifica el directorio en el host.target=/container/dataindica dónde se montará en el contenedor.readonlyhace que el volumen sea de solo lectura.
3️⃣ Montando un volumen con -v
docker run -v my_volume:/container/data ubuntu
my_volumees un volumen administrado por Docker.- Se montará en
/container/dataen el contenedor.
4️⃣ Montando un volumen con --mount
docker run --mount type=volume,source=my_volume,target=/container/data ubuntu
type=volumeindica que se usa un volumen administrado por Docker.source=my_volumees el nombre del volumen.target=/container/dataes el destino dentro del contenedor.
📌 Cuál usar y cuándo
✅ Usa -v para configuraciones rápidas o compatibilidad con versiones antiguas.
✅ Usa --mount para configuraciones más claras y flexibles, especialmente en docker-compose y entornos de producción
Creación y Administración de Volumenes
Crear un volumen:
docker volume create example-vol
docker volume ls
local example-vol
docker volume inspect example-vol
[
{
"Driver": "local",
"Labels": {},
"Mountpoint": "/var/lib/docker/volumes/example-vol/_data",
"Name": "example-vol",
"Options": {},
"Scope": "local"
}
]
docker volume rm example-vol
Iniciar un contenedor con un volumen
Si inicia un contenedor con un volumen que aún no existe, Docker crea el volumen por usted. El siguiente ejemplo monta el volumen demovol en /app/ del contenedor.
docker run -d \
--name demovol-container \
--mount source=demovol,target=/app \
nginx:latest
docker inspect demovol-container para verificar que Docker creó el volumen y se montó correctamente. Busque la Mountssección:
docker inspect demovol-container
"Mounts": [
{
"Type": "volume",
"Name": "demovol",
"Source": "/var/lib/docker/volumes/demovol/_data",
"Destination": "/app",
"Driver": "local",
"Mode": "",
"RW": true,
"Propagation": ""
}
],
docker exec demovol-container df -h
docker stop demovol-container
docker rm demovol-container
docker volume rm demovol
Guía de Laboratorio: Usar Docker Volumes con un contenedor NGINX para un Sitio Web
En esta guía, configuraremos un contenedor NGINX para servir un sitio web sencillo utilizando un Docker Volume. Veremos cómo persistir los datos del sitio, de manera que estos permanezcan disponibles incluso si el contenedor se elimina y se recrea.
Paso 1: Crear un Docker Volume
Primero, crearemos un volumen en Docker para almacenar los datos del sitio web de forma persistente.
docker volume create webdata
Este comando crea un volumen llamado webdata, que usaremos para almacenar los archivos de nuestro sitio web.
Paso 2: Crear el contenido del sitio web
Crea un archivo index.html localmente para usarlo como contenido del sitio web.
- Crea una carpeta temporal:
mkdir ~/nginx-site - Crea un archivo
index.htmldentro de esta carpeta:echo "<h1>Bienvenido a mi sitio web</h1>" > ~/nginx-site/index.html
Paso 3: Iniciar el contenedor NGINX con el volumen
Montaremos el volumen webdata en el contenedor para que sirva los archivos del sitio web.
docker run -d \
--name nginx-container \
-p 8080:80 \
-v webdata:/usr/share/nginx/html \
nginx
Este comando:
- Inicia un contenedor NGINX en segundo plano (
-d). - Lo expone en el puerto
8080de tu máquina host. - Monta el volumen
webdataen el directorio/usr/share/nginx/html, que es donde NGINX busca los archivos a servir.
Paso 4: Copiar el contenido del sitio al volumen
Los volúmenes se encuentran vacíos al principio, por lo que necesitamos copiar el archivo index.html creado en el Paso 2 al volumen.
-
Usa un contenedor temporal para copiar el archivo al volumen:
docker run --rm \ -v ~/nginx-site:/site \ -v webdata:/usr/share/nginx/html \ busybox cp /site/index.html /usr/share/nginx/html/ -
Verifica que el archivo se haya copiado al volumen:
docker run --rm \ -v webdata:/data \ busybox ls /data
Deberías ver el archivo index.html listado.
Paso 5: Probar el sitio web
Utilizar el siguiente comando:
curl http://localhost:8080
Deberías ver el mensaje:
"Bienvenido a mi sitio web"
Paso 6: Eliminar el contenedor y recrearlo
-
Elimina el contenedor NGINX actual:
docker rm -f nginx-container -
Vuelve a crear el contenedor usando el volumen persistente:
docker run -d \ --name nginx-container \ -p 8080:80 \ -v webdata:/usr/share/nginx/html \ nginx -
Verifica nuevamente el sitio web:
curl http://localhost:8080
El sitio web debería seguir mostrándose, confirmando que los datos se han mantenido en el volumen.
Paso 7: Limpieza
Si ya no necesitas este entorno, puedes eliminar el contenedor y el volumen.
-
Eliminar el contenedor:
docker rm -f nginx-container -
Eliminar el volumen:
docker volume rm webdata -
Eliminar la carpeta temporal:
rm -Rf ~/nginx-site
Conclusión
Has configurado un contenedor NGINX con un volumen persistente, probado la persistencia de datos al eliminar y recrear el contenedor, y aprendido cómo gestionar volúmenes en Docker.
Guía de Laboratorio: Utilizando almacenamiento persistente en Data Base Container
La presente guía descubre y aplica el uso de volúmenes compartidos para persistir data de importancia en contenedores.
-
Ingresar al servidor qué contiene al ambiente de laboratorio con credenciales de administración
-
Crear un directorio
sudo mkdir -pv /var/local/mysql -
Cambiar uid y gid de forma recursiva al directorio
sudo chown -Rv 999:999 /var/local/mysql -
Descargar imagen mariadb:10.7
docker pull mariadb:10.7 -
Iniciar el contenedor con la imagen de mariadb:10.7 con los siguientes parámetros (listados con - nombre completo pero, en comando abreviados):
- name=persist-db
- remove=true
- volume=/var/local/mysql:/var/lib/mysql
- environment=MYSQL_USER=user1
- environment=MYSQL_PASSWORD=demo
- environment=MYSQL_DATABASE=inventory
- environment=MYSQL_ROOT_PASSWORD=demo
docker run --name persist-db \ -v /var/local/mysql:/var/lib/mysql \ -e MYSQL_USER=user1 \ -e MYSQL_PASSWORD=demo \ -e MYSQL_DATABASE=inventory \ -e MYSQL_ROOT_PASSWORD=demo -d mariadb:10.7
-
Listar los contenedores activos
docker ps -
Aplicar formato a la lista de contenedores
docker ps --format="\nNAME: {{.Names}} | STATUS: {{.Status}} | IMAGE: {{.Image}}\n" -
Listar contenido de directorio local
ls -l /var/local/mysql
Cambios en data
-
Ingrese al contenedor
persist-dby agregue una tabla y un registro en la base de datos creada de mariadbdocker exec -it persist-db bashmysql -u user1 -pdemo -D inventoryCREATE TABLE customers(id INT, first_name VARCHAR(50), last_name VARCHAR (50), email VARCHAR(100)); INSERT INTO customers VALUES(1, 'Anne', 'Ketchmar', 'annek@noanswer.org'); exitexit -
Detenga el contenedor
docker stop persist-db -
Vea el contenido de la carpeta
/var/local/mysqlls -l /var/local/mysql -
Vuelva a iniciar el contenedor
docker start persist-db -
Revise que el record de la tabla
customersexistadocker exec -it persist-db bashmysql -u user1 -pdemo -D inventorySELECT * FROM customers; exitexit -
Detenga y elimine el contenedor
docker stop persist-dbdocker rm persist-db -
Verifique que la carpeta
/var/local/mysqlaun exista en la máquinals -l /var/local/mysql -
Cree otro contenedor de mariadb
docker run --name persist-db \ -v /var/local/mysql:/var/lib/mysql \ -e MYSQL_USER=user1 \ -e MYSQL_PASSWORD=demo \ -e MYSQL_DATABASE=inventory \ -e MYSQL_ROOT_PASSWORD=demo -d mariadb:10.7 -
Verifique que la tabla
customersexistadocker exec -it persist-db bashmysql -u user1 -pdemo -D inventorySELECT * FROM customers; exitexit -
Cree una carpeta en
/var/local/mysqlllamadacustom-dirsudo mkdir /var/local/mysql/custom-dir -
Ejecute dentro del contenedor el comando para listar los archivos dentro del directorio
/var/lib/mysqldocker exec -it persist-db ls -l /var/lib/mysql -
Observe que el directorio
custom-direxiste dentro del contenedor -
Acceda al contenedor abriendo una terminal bash con docker
docker exec -it persist-db bash -
Cree un archivo vacío dentro de la carpeta
custom-dirtouch /var/lib/mysql/custom-dir/example.txt -
Salga de la terminal del contenedor
exit -
Verifique los archivos del directorio
custom-diren su máquinals -l /var/local/mysql/custom-dir -
Observe que ahora existe el archivo example.txt
-
Agregue el siguiente contenido al archivo
example.txtsudo vi /var/local/mysql/custom-dir/example.txt# Este archivo no afecta al funcionamiento de MariaDB # Su contenido no se lee por ningún servicio Uso: Prueba de almacenamiento persistente en Docker -
Guarde los cambios
-
Verifique en el contenedor de mariadb el contenido del archivo example.txt
docker exec -it persist-db cat /var/lib/mysql/custom-dir/example.txt
Limpieza de ambiente
- Limpiar el ambiente ejecutando
docker stop persist-dbdocker rm persist-dbsudo rm -r /var/local/mysqldocker image rm mariadb:10.7