remove - docker-compose
Cómo tratar con el almacenamiento persistente(por ejemplo, bases de datos) en Docker (14)
¿Cómo lidian las personas con el almacenamiento persistente de sus contenedores Docker?
Actualmente estoy usando este enfoque: compile la imagen, por ejemplo, para PostgreSQL, y luego inicie el contenedor con
docker run --volumes-from c0dbc34fd631 -d app_name/postgres
En mi humilde opinión, eso tiene el inconveniente de que nunca debo (por accidente) borrar el contenedor "c0dbc34fd631".
Otra idea sería montar los volúmenes de host "-v" en el contenedor, sin embargo, el ID de usuario dentro del contenedor no necesariamente coincide con el ID de usuario del host, y luego los permisos pueden estar desordenados.
Nota: en lugar de --volumes-from ''cryptic_id''
también puede usar --volumes-from my-data-container
donde my-data-container
es un nombre que asignó a un contenedor de solo datos, p. Ej., docker run --name my-data-container ...
(ver la respuesta aceptada)
Docker 1.9.0 y superior
Usar volumen API
docker volume create --name hello
docker run -d -v hello:/container/path/for/volume container_image my_command
Esto significa que el patrón de contenedor de solo datos debe ser abandonado en favor de los nuevos volúmenes.
En realidad, la API de volumen es solo una mejor manera de lograr el patrón de contenedor de datos.
Si crea un contenedor con un -v volume_name:/container/fs/path
Docker creará automáticamente un volumen con nombre para usted que puede:
- Ser listado a través del
docker volume ls
- Ser identificado a través del
docker volume inspect volume_name
- Copiado como un directorio normal
- Respaldado como antes a través de una conexión
--volumes-from
La nueva API de volumen agrega un comando útil que le permite identificar volúmenes colgantes:
docker volume ls -f dangling=true
Y luego eliminarlo a través de su nombre:
docker volume rm <volume name>
Como @mpugach subraya en los comentarios, puedes deshacerte de todos los volúmenes colgando con una buena frase:
docker volume rm $(docker volume ls -f dangling=true -q)
# Or using 1.13.x
docker volume prune
Docker 1.8.xy por debajo
El enfoque que parece funcionar mejor para la producción es utilizar un contenedor de solo datos .
El contenedor de solo datos se ejecuta en una imagen de barebones y en realidad no hace nada excepto exponer un volumen de datos.
Luego puede ejecutar cualquier otro contenedor para tener acceso a los volúmenes del contenedor de datos:
docker run --volumes-from data-container some-other-container command-to-execute
- Here puede obtener una buena imagen de cómo organizar los diferentes contenedores.
- Here hay una buena idea de cómo funcionan los volúmenes.
En esta publicación de blog hay una buena descripción del llamado contenedor como patrón de volumen que aclara el punto principal de tener contenedores de solo datos .
A continuación se muestra el procedimiento de copia de seguridad / restauración para Docker 1.8.xy a continuación.
APOYO:
sudo docker run --rm --volumes-from DATA -v $(pwd):/backup busybox tar cvf /backup/backup.tar /data
- --rm: retira el contenedor cuando sale.
- --volumes-from DATA: se adjunta a los volúmenes compartidos por el contenedor DATA
- -v $ (pwd): / backup: bind monta el directorio actual en el contenedor; para escribir el archivo tar a
- busybox: una pequeña imagen más simple, buena para un mantenimiento rápido
- tar cvf /backup/backup.tar / data: crea un archivo tar sin comprimir de todos los archivos en el directorio / data
RESTAURAR:
# Create a new data container
$ sudo docker run -v /data -name DATA2 busybox true
# untar the backup files into the new container᾿s data volume
$ sudo docker run --rm --volumes-from DATA2 -v $(pwd):/backup busybox tar xvf /backup/backup.tar
data/
data/sven.txt
# Compare to the original container
$ sudo docker run --rm --volumes-from DATA -v `pwd`:/backup busybox ls /data
sven.txt
Aquí hay un buen artículo del excelente Brian Goff que explica por qué es bueno usar la misma imagen para un contenedor y un contenedor de datos.
A partir de Docker Compose 1.6, ahora hay soporte mejorado para volúmenes de datos en Docker Compose. El siguiente archivo de composición creará una imagen de datos que persistirá entre los reinicios (o incluso la eliminación) de los contenedores principales:
Aquí está el anuncio del blog: Compose 1.6: Nuevo archivo Compose para definir redes y volúmenes
Aquí hay un ejemplo de archivo de composición:
version: "2"
services:
db:
restart: on-failure:10
image: postgres:9.4
volumes:
- "db-data:/var/lib/postgresql/data"
web:
restart: on-failure:10
build: .
command: gunicorn mypythonapp.wsgi:application -b :8000 --reload
volumes:
- .:/code
ports:
- "8000:8000"
links:
- db
volumes:
db-data:
Hasta donde puedo entender: esto creará un contenedor de volumen de datos ( db_data
) que persistirá entre reinicios.
Si ejecuta: docker volume ls
debería ver su volumen en la lista:
local mypthonapp_db-data
...
Puede obtener más detalles sobre el volumen de datos:
docker volume inspect mypthonapp_db-data
[
{
"Name": "mypthonapp_db-data",
"Driver": "local",
"Mountpoint": "/mnt/sda1/var/lib/docker/volumes/mypthonapp_db-data/_data"
}
]
Algunas pruebas:
# Start the containers
docker-compose up -d
# .. input some data into the database
docker-compose run --rm web python manage.py migrate
docker-compose run --rm web python manage.py createsuperuser
...
# Stop and remove the containers:
docker-compose stop
docker-compose rm -f
# Start it back up again
docker-compose up -d
# Verify the data is still there
...
(it is)
# Stop and remove with the -v (volumes) tag:
docker-compose stop
docker=compose rm -f -v
# Up again ..
docker-compose up -d
# Check the data is still there:
...
(it is).
Notas:
También puede especificar varios controladores en el bloque de
volumes
. Por ejemplo, podría especificar el controlador Flocker para db_data:volumes: db-data: driver: flocker
- A medida que mejoran la integración entre Docker Swarm y Docker Compose (y posiblemente empiecen a integrar Flocker en el ecosistema Docker (escuché el rumor de que Docker ha comprado Flocker), creo que este enfoque debería ser cada vez más poderoso.
Descargo de responsabilidad: este enfoque es prometedor y lo estoy utilizando con éxito en un entorno de desarrollo. ¡Estaría preocupado de usar esto en producción todavía!
Cuando utilice Docker Compose, simplemente adjunte un volumen con nombre, por ejemplo,
version: ''2''
services:
db:
image: mysql:5.6
volumes:
- db_data:/var/lib/mysql:rw
environment:
MYSQL_ROOT_PASSWORD: root
volumes:
db_data:
Depende de su escenario (esto no es realmente adecuado para un entorno de producción), pero aquí hay una forma:
Creando un contenedor MySQL Docker
Esta idea es utilizar un directorio en su host para la persistencia de datos.
En Docker versión v1.0 , el comando dado puede vincular un montaje de un archivo o directorio en la máquina host:
$ docker run -v /host:/container ...
El volumen anterior podría utilizarse como un almacenamiento persistente en el host que ejecuta Docker.
En caso de que no esté claro a partir de la actualización 5 de la respuesta seleccionada, a partir de Docker 1.9, puede crear volúmenes que pueden existir sin estar asociado a un contenedor específico, haciendo que el patrón del "contenedor de datos solamente" sea obsoleto.
¿Ver contenedores de datos obsoletos con docker 1.9.0? # 17798 .
Creo que los mantenedores de Docker se dieron cuenta de que el patrón del contenedor de solo datos era un poco de olor de diseño y decidió hacer de los volúmenes una entidad separada que puede existir sin un contenedor asociado.
Existen varios niveles de administración de datos persistentes, según sus necesidades:
- Guárdalo en tu host
- Utilice el indicador
-v host-path:container-path
para conservar los datos del directorio del contenedor en un directorio del host. - Las copias de seguridad / restauraciones se realizan ejecutando un contenedor de copia de seguridad / restauración (como tutumcloud / dockup) montado en el mismo directorio.
- Utilice el indicador
- Cree un contenedor de datos y monte sus volúmenes en su contenedor de aplicaciones
- Cree un contenedor que exporte un volumen de datos, use
--volumes-from
para montar esos datos en su contenedor de aplicaciones. - Copia de seguridad / restaurar lo mismo que la solución anterior.
- Cree un contenedor que exporte un volumen de datos, use
- Use un complemento de volumen Docker que respalde un servicio externo / de terceros
- Los complementos de volumen de Docker permiten que su fuente de datos provenga de cualquier lugar: NFS, AWS (S3, EFS y EBS)
- Dependiendo del complemento / servicio, puede adjuntar contenedores individuales o múltiples a un solo volumen.
- Dependiendo del servicio, las copias de seguridad / restauraciones pueden ser automatizadas para usted.
- Si bien esto puede ser engorroso de hacer manualmente, algunas soluciones de orquestación, como Rancher , lo tienen integrado y fácil de usar.
- Convoy es la solución más fácil para hacer esto manualmente.
La respuesta de @ tommasop es buena y explica algunos de los mecanismos del uso de contenedores de solo datos. Pero como alguien que inicialmente pensó que los contenedores de datos eran tontos cuando uno solo podía enlazar, montar un volumen en el host (como lo sugieren otras respuestas), pero ahora se da cuenta de que, de hecho, los contenedores de solo datos son bastante claros, puedo sugerir mi propia publicación de blog sobre este tema: ¿Por qué los contenedores de datos de Docker (¡Volúmenes!) son buenos
Vea también: mi respuesta a la pregunta " ¿Cuál es la (mejor) forma de administrar permisos para volúmenes compartidos de Docker? " Para ver un ejemplo de cómo usar contenedores de datos para evitar problemas como permisos y mapeo de uid / gid con el host.
Para abordar una de las preocupaciones originales del OP: que el contenedor de datos no debe eliminarse. Incluso si se elimina el contenedor de datos, los datos en sí no se perderán siempre que cualquier contenedor tenga una referencia a ese volumen, es decir, cualquier contenedor que haya montado el volumen a través de --volumes-from
. Entonces, a menos que todos los contenedores relacionados se detengan y se eliminen (se podría considerar que esto es equivalente a un rm -fr /
accidental), los datos están seguros. Siempre puede volver a crear el contenedor de datos haciendo --volumes-from
cualquier contenedor que tenga una referencia a ese volumen.
Como siempre, hacer copias de seguridad sin embargo!
ACTUALIZACIÓN: Docker ahora tiene volúmenes que pueden administrarse independientemente de los contenedores, lo que hace que sea más fácil de administrar.
Mi solución es utilizar el nuevo docker cp
, que ahora puede copiar datos de contenedores, sin importar si se está ejecutando o no, y compartir un volumen de host en la misma ubicación donde la aplicación de base de datos está creando sus archivos de base de datos. El contenedor. Esta doble solución funciona sin un contenedor de solo datos, directamente del contenedor de la base de datos original.
Así que mi script de inicio de systemd está tomando la tarea de hacer una copia de seguridad de la base de datos en un archivo en el host. Puse una marca de tiempo en el nombre de archivo para nunca volver a escribir un archivo.
Lo está haciendo en el ExecStartPre:
ExecStartPre=-/usr/bin/docker cp lanti-debian-mariadb:/var/lib/mysql /home/core/sql
ExecStartPre=-/bin/bash -c ''/usr/bin/tar -zcvf /home/core/sql/sqlbackup_$$(date +%%Y-%%m-%%d_%%H-%%M-%%S)_ExecStartPre.tar.gz /home/core/sql/mysql --remove-files''
Y está haciendo lo mismo en ExecStopPost también:
ExecStopPost=-/usr/bin/docker cp lanti-debian-mariadb:/var/lib/mysql /home/core/sql
ExecStopPost=-/bin/bash -c ''tar -zcvf /home/core/sql/sqlbackup_$$(date +%%Y-%%m-%%d_%%H-%%M-%%S)_ExecStopPost.tar.gz /home/core/sql/mysql --remove-files''
Además, expuse una carpeta del host como un volumen a la misma ubicación donde se almacena la base de datos:
mariadb:
build: ./mariadb
volumes:
- $HOME/server/mysql/:/var/lib/mysql/:rw
Funciona muy bien en mi VM (yo construyo una pila LEMP para mí): https://github.com/DJviolin/LEMP
¿Pero no sé si es una solución "a prueba de balas" cuando su vida depende realmente de ella (por ejemplo, una tienda web con transacciones en cualquier milisegundo posible)?
A los 20 minutos y 20 segundos de este video de presentación oficial de Docker, el presentador hace lo mismo con la base de datos:
"Para la base de datos tenemos un volumen, por lo que podemos asegurarnos de que, a medida que la base de datos sube y baja, no perdemos datos cuando se detiene el contenedor de la base de datos".
Recientemente escribí sobre una solución potencial y una aplicación que demuestra la técnica. Me parece que es bastante eficiente durante el desarrollo y en la producción. Espero que ayude o despierte algunas ideas.
Repo: https://github.com/LevInteractive/docker-nodejs-example
Artículo: http://lev-interactive.com/2015/03/30/docker-load-balanced-mongodb-persistence/
Si bien esto es todavía una parte de Docker que necesita algo de trabajo , debe colocar el volumen en el Dockerfile con la instrucción VOLUME para que no tenga que copiar los volúmenes de otro contenedor.
Eso hará que sus contenedores sean menos interdependientes y no tendrá que preocuparse por la eliminación de un contenedor que afecta a otro.
Si desea mover sus volúmenes a su alrededor, también debe mirar a Flocker .
Desde el README:
Flocker es un administrador de volumen de datos y una herramienta de administración de clústeres Docker de host múltiple. Con él, puede controlar sus datos utilizando las mismas herramientas que utiliza para sus aplicaciones sin estado aprovechando el poder de ZFS en Linux.
Esto significa que puede ejecutar sus bases de datos, colas y tiendas de valor-clave en Docker y moverlas tan fácilmente como el resto de su aplicación.
Solo estoy usando un directorio predefinido en el host para conservar los datos de PostgreSQL. Además, de esta manera es posible migrar fácilmente las instalaciones existentes de PostgreSQL a los contenedores de Docker: https://crondev.com/persistent-postgresql-inside-docker/
Use el reclamo de volumen persistente (PVC) de Kubernetes, que es una herramienta de administración y programación de contenedores de Docker:
Las ventajas de usar Kubernetes para este propósito son que:
- Puede usar cualquier almacenamiento como NFS u otro almacenamiento, e incluso cuando el nodo está inactivo, el almacenamiento no tiene por qué serlo.
- Además, los datos en tales volúmenes pueden configurarse para ser retenidos incluso después de que se destruya el propio contenedor, de modo que otro contenedor pueda reclamarlo, si es necesario.