Cómo configurar y ejecutar volúmenes de datos de Docker
En este tutorial vamos a recorrer el uso del volumen de la ventana acoplable, que puede verse como una forma flexible proporcionada por el ecosistema de la ventana acoplable para administrar y manejar datos, tanto internamente por contenedores como de manera compartida entre ellos.
Por favor, no, para la demostración usaré Docker para Mac, la versión que se muestra a continuación, pero creo que las instrucciones / comandos siguen siendo los mismos para Linux, Windows o incluso para la nueva versión de Docker en una plataforma basada en la nube y mi carpeta de trabajo. en la terminal estará Volúmenes de Docker.
➜ ~ docker --version Docker version 1.12.3, build 6b644ec
Que aprenderemos:
- Comprender qué es un volumen en el ecosistema de Docker
- Cree y use volúmenes de datos
- Como carpetas o incluso archivos
- Como contenedores docker
- Eliminar volúmenes
Introducción
A modo de introducción, diría que la pregunta básica que el lector podría hacer es ¿por qué deberíamos usar volúmenes? Los contenedores de la ventana acoplable proporcionan una virtualización a nivel de sistema operativo de forma liviana, lo que significa que mediante un contenedor de ventana acoplable puedo ejecutar un sistema operativo completo para trabajar con, entonces, por qué importan los volúmenes; bueno, de hecho, hay muchas razones detrás de traer este mecanismo; Las características más importantes son, en primer lugar, la separación de preocupaciones, lo que significa que, para poder separar el almacenamiento de datos de los contenedores, este acoplamiento flexible nos permite mantener volúmenes principalmente de datos incluso después de eliminar nuestros contenedores, lo cual es muy agradable y caso de uso frecuente, en segundo lugar, los volúmenes nos permiten compartir datos entre la máquina host y los contenedores de la ventana acoplable que se ejecutan en la parte superior de esta máquina; en tercer lugar, nos permite compartir datos entre los propios contenedores.
Crear un volumen de Docker
De hecho, hay varias formas de crear volúmenes de Docker; principalmente, ya sea dentro del ciclo de vida de creación del contenedor o por separado.
Agregar un volumen dentro de la creación de la ventana acoplable
Cuando creamos e iniciamos un contenedor docker usando el comando Docker ejecutar podemos especificar un volumen que se adjuntará al contenedor creado agregando el argumento -v y especificando una ruta de carpeta del volumen como se ilustra a continuación.
Creemos una imagen de Docker (imagen de nodo js) y configuremos una aplicación web de nodo de muestra para trabajar a lo largo de este artículo:
- Configurar una aplicación simple de node js
➜ DockerVolumes ls Dockerfile node_modules package.json server.js // Dockerfile ➜ DockerVolumes cat Dockerfile FROM node:latest # Create app directory RUN mkdir -p /usr/src/app WORKDIR /usr/src/app # Install app dependencies COPY package.json /usr/src/app/ RUN npm install # Bundle app source COPY . /usr/src/app EXPOSE 3000 CMD [ "node", "server.js" ] // server.js ➜ DockerVolumes cat server.js var express = require('express'); var app = express(); app.get('/', function (req, res) { res.send("What's up docker volume!"); }); app.listen(3000, function () { console.log('Server listening on port 3000!'); });
- Cree nuestra imagen de Docker y etiqueta está usando –T bandera
➜ DockerVolumes docker build -t linoxide/nodewebapp . Sending build context to Docker daemon 5.12 kB Step 1 : FROM node:latest ---> f5eca816b45d Step 2 : RUN mkdir -p /usr/src/app ---> Using cache ---> 26654b09fdc4 Step 3 : WORKDIR /usr/src/app ---> Using cache ---> 37845a9e9171 Step 4 : COPY package.json /usr/src/app/ ---> 6c56590fbccb Removing intermediate container bdb0b1c0881b Step 5 : RUN npm install ---> Running in 47e7726adb89 … … Removing intermediate container bc82f32eef88 Successfully built 7d558c342dfb
- Ejecutemos un contenedor con un volumen usando nuestra última imagen construida, nodo enlazaremos el puerto público 3001 al puerto privado (dentro de nuestro contenedor) 3000 de nuestro servidor de nodo:
➜ DockerVolumes docker run -p 3001:3000 -d --name nodewebapp -v /nodewebapp linoxide/nodewebapp 602f318d57d5e03b353b15a4c644f90a9918e46590ddff0fb776fa09cf32c51a
- Podemos probar nuestra web de nodos simplemente usando curl
➜ ~ curl localhost:3001 What's up docker volume!
- Inspeccionando nuestro contenedor para verificar nuestro volumen creado, para hacerlo, ejecute
➜ La ventana acoplable DockerVolumes inspecciona nodewebapp [ { "Id": "602f318d57d5e03b353b15a4c644f90a9918e46590ddff0fb776fa09cf32c51a", "Created": "2016-12-04T10:17:50.65018429Z", "Path": "node", "Args": [ "server.js" …… "Mounts": [ { "Name": "cadf05a38efc5c2445f5f7b848c16c3fa2c15e1a036a9b4cad40acc1a9e74371", "Source": "/var/lib/docker/volumes/cadf05a38efc5c2445f5f7b848c16c3fa2c15e1a036a9b4cad40acc1a9e74371/_data", "Destination": "/nodewebapp", "Driver": "local", "Mode": "", "RW": true, "Propagation": ""
In the Mounts array we have “Source” field which is the folder in the host machine linked to the create volume inside the container, which the “Destination” field.
- We can also inspect the created docker volume using the volume Id:
➜ DockerVolumes docker volume inspect cadf05a38efc5c2445f5f7b848c16c3fa2c15e1a036a9b4cad40acc1a9e74371 [ { "Name": "cadf05a38efc5c2445f5f7b848c16c3fa2c15e1a036a9b4cad40acc1a9e74371", "Driver": "local", "Mountpoint": "/var/lib/docker/volumes/cadf05a38efc5c2445f5f7b848c16c3fa2c15e1a036a9b4cad40acc1a9e74371/_data", "Labels": null, "Scope": "local" } ]
Nota:
Otra forma de crear volúmenes dentro de la creación del contenedor es agregando VOLUMEN a Dockerfile como:
VOLUME ["/foo", "/var/bar", "/etc/baz"]
Usando la carpeta de host como volumen
Una de las características agradables más orientadas al desarrollador del volumen de la ventana acoplable es la posibilidad de usar una carpeta de host como volumen; al hacerlo, un desarrollador, por ejemplo, puede vincular su espacio de trabajo a un volumen de la ventana acoplable y ejecutar un contenedor usando ese volumen, por lo que cualquier cambio realizado en el espacio de trabajo se refleja automáticamente en el volumen relacionado, que es una característica interesante desde el punto de vista del desarrollador. Entonces, probemos esto, voy a usar la carpeta de la aplicación web de mi nodo creada anteriormente para vincularla al volumen de la ventana acoplable.
Tenga en cuenta que he cambiado un poco mi Dockerfile, por lo que mi directorio de trabajo será el volumen de la ventana acoplable y package.json para usar nodemon para que el servidor de nodos se reinicie después de cualquier cambio, mis archivos ahora se ven así:
// Dockerfile ➜ DockerVolumes cat Dockerfile FROM node:latest RUN npm i -g nodemon WORKDIR /nodewebapp EXPOSE 3000 CMD [ "npm", "run", "dev" ] // package.json ➜ DockerVolumes cat package.json { "name": "DockerVolumes", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo "Error: no test specified" && exit 1", "dev" : "npm i && nodemon server.js" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "express": "^4.14.0" } }
Reconstruyendo la imagen linoxido / nodewebapp y ejecuta el contenedor
➜ DockerVolumes docker run -p 3002:3000 -d --name nodewebapp2 -v /Users/deep/Code/docker-volume/linoxide/DockerVolumes:/nodewebapp linoxide/nodewebapp 9ab92d3b8b585244408da79f9b8b1755e20fa9b32bdfdb147b0fc7ac64d06e0d
Y pruebe la aplicación de nodo usando curl y tenga en cuenta que cada vez que se realiza un cambio en server.js, por ejemplo, el cambio del mensaje de registro en el punto final ‘/’ se reflejará automáticamente:
➜ ~ curl localhost:3002 What's up docker volume! ➜ ~ curl localhost:3002 What's up docker volume update server .js !
Notas:
- Una nota que debe tenerse en cuenta aquí es que debemos proporcionar la ruta absoluta del directorio de host que se enlazará como volumen.
- Otra cosa es que, por defecto, los volúmenes se montan en modo lectura-escritura, este comportamiento podría cambiarse especificando el :modo después de la ruta del volumen, por ejemplo : ro por solo lectura modo como a continuación:
➜ DockerVolumes docker run -p 3002:3000 -d --name nodewebapp2 -v /Users/deep/Code/docker-volume/linoxide/DockerVolumes:/nodewebapp:ro linoxide/nodewebapp 9ab92d3b8b585244408da79f9b8b1755e20fa9b32bdfdb147b0fc7ac64d06e0d
- La tercera cosa a tener en cuenta es que no podemos montar una carpeta de host utilizando Dockerfile, ya que cualquier imagen de la ventana acoplable debe ser portátil, por lo que debe estar separada de cualquier host.
- En cuarto lugar, de manera similar, para montar una carpeta de host como volumen de la ventana acoplable, podemos montar un archivo proporcionando la ruta del archivo en lugar de la ruta de una carpeta.
Volumen de Docker como contenedor
Como mecanismo sofisticado para compartir / conservar datos entre contenedores, la ventana acoplable proporciona volúmenes como contenedores.
Voy a tomar una imagen de Docker Hub para ilustrar el volumen como contenedor, por ejemplo, tomemos el oficial redis imagen. Para crear un volumen llamado redisDB con debajo de la carpeta / redisdbstore usando esta imagen, ejecute el siguiente comando, redis al final del comando, represente el nombre de la imagen de la ventana acoplable:
➜ ~ docker create -v /redisdbstore --name redisDB redis Unable to find image 'redis:latest' locally latest: Pulling from library/redis 386a066cd84a: Already exists 769149e3a45c: Pull complete 1f43b3c0854a: Pull complete 70e928127ad8: Pull complete 9ad9c0058d76: Pull complete bc845722f255: Pull complete 105d1e8cd76a: Pull complete Digest: sha256:c2ce5403bddabd407c0c63f67566fcab6facef90877de58f05587cdf244a28a8 Status: Downloaded newer image for redis:latest 95f01cea2cd94376de471667fa6e643cb46bf93064de007d92b20a2658ee0134
Por lo tanto, podemos usar –de-volúmenes argumento para montar el volumen creado / redisdbstore en otro contenedor:
➜ ~ docker run -d --volumes-from redisDB --name nodeWebAppWithRedisDB1 linoxide/nodewebapp 3ea2f024ede0c106dd2db034534977634011d164f453aa77b11c34fb3f033303
Notas:
- Es posible usar varias veces –volúmenes-de utilizar los volúmenes de diferentes contenedores
- Es posible encadenar la creación de contenedores montando volúmenes provenientes de un volumen principal como redisDB por ejemplo, podemos usar nodeWebAppWithRedisDB1 para crear nodeWebAppWithRedisDB2 como se ilustra a continuación:
➜ ~ docker run -d --name nodeWebAppWithRedisDB2 --volumes-from nodeWebAppWithRedisDB1 linoxide/nodewebapp 06af9b81d5bb65076e643615e933c1088852d6466d488a34bc2247a746eead3b
Eliminar volúmenes
Como mencioné anteriormente, los volúmenes están separados de los contenedores, eliminar un contenedor no eliminará sus volúmenes adjuntos.
Eliminar un volumen con el contenedor
La forma más sencilla de eliminar un volumen dentro de su contenedor es usar la opción –v:
➜ ~ docker rm –v container_id
Eliminar un volumen con su nombre / id
➜ ~ docker volume rm –v volume_id
Eliminar volúmenes colgantes
Si eliminamos un contenedor sin especificar la opción –v los volúmenes asociados terminan como un volumen colgante en el disco local, se pueden eliminar usando:
➜ ~ docker volume rm `docker volume ls -q -f dangling=true`
Conclusión
Para concluir este artículo, me gustaría mencionar que los volúmenes son un mecanismo de gestión de datos muy agradable. Se pueden utilizar de diferentes formas y en muchos niveles en el ecosistema devops para crear copias de seguridad, restauraciones o incluso migraciones. Los volúmenes siguen siendo accesibles directamente desde la máquina de alojamiento, por lo que interactúan de manera amigable con las herramientas clásicas orientadas a Linux, pero el usuario experimentado puede prestar atención al jugar con los volúmenes de tal manera que no se corrompan los datos.