Aprende desde cero a crear y a configurar tus propias infraestructuras de software utilizando contenedores. De forma sencilla y potente podrás crear plataformas personalizadas con las que podrás desplegar tus aplicaciones en la nube o en cualquier infraestructura donde tengas Docker.
2. Indice
• Introducción a Docker
• Instalación de Docker
• Uso de imágenes
• Contenedores
• Creación de imágenes
• Desde un contenedor
• Desde Dockerfile
• Volúmenes
• Redes
• Compose
• Anexo
3. Introducción a Docker
¿Qué es Docker?
“Docker es un proyecto de código abierto que automatiza el despliegue de
aplicaciones dentro de contenedores de software, proporcionando una capa adicional
de abstracción y automatización de virtualización de aplicaciones en múltiples
sistemas operativos.
Docker utiliza características de aislamiento de recursos del kernel Linux, tales como
cgroups y espacios de nombres (namespaces) para permitir que "contenedores"
independientes se ejecuten dentro de una sola instancia de Linux, evitando la
sobrecarga de iniciar y mantener máquinas virtuales”. Wikipedia:
https://es.wikipedia.org/wiki/Docker_(software)
“La idea detrás de Docker es crear contenedores ligeros y portables para las
aplicaciones software que puedan ejecutarse en cualquier máquina con Docker
instalado, independientemente del sistema operativo que la máquina tenga por
debajo, facilitando así también los despliegues”. Documentación oficial de Docker
4. Introducción a Docker
¿Qué es Docker?
“Docker es una plataforma abierta para desarrollar, enviar y ejecutar
aplicaciones. Docker le permite separar sus aplicaciones de su infraestructura
para que pueda entregar el software rápidamente. Con Docker, puede
gestionar su infraestructura de la misma manera que gestiona sus
aplicaciones. Al aprovechar las metodologías de Docker para enviar, probar e
implementar código rápidamente, puede reducir significativamente el tiempo
que transcurre entre la escritura del código y su ejecución en producción”.
Docker overview: https://docs.docker.com/engine/docker-overview/
“Docker es una herramienta que puede empaquetar una aplicación y sus
dependencias en un contenedor virtual que se puede ejecutar en cualquier
servidor Linux. Esto ayuda a permitir la flexibilidad y portabilidad en donde la
aplicación se puede ejecutar, ya sea en las instalaciones físicas, la nube
pública, nube privada, etc”. 451 Research
5. Introducción a Docker
¿Qué es Docker?
Al contrario que una máquina virtual, el
contenedor no necesita incluir un
sistema operativo.
El contenedor Docker utiliza facilidades
del kernel, tales como el uso de
namespaces separados o el aislamiento
de recursos, con lo que la aplicación
está aislada del sistema operativo.
Docker utiliza la virtualización del kernel
de dos formas: directa (mediante
libcontainer) o indirecta (mediante
libvirt).
Los recursos (CPU, memoria, red, etc.)
pueden ser aislados y los servicios
pueden ser restringidos.
6. Introducción a Docker
Máquina virtual Vs Docker
• Una máquina virtual tiene un coste significativo, mientras Docker es gratuito y de código abierto.
• Docker utiliza procesos aislados y no requiere un hardware hypervisor
• Docker es mucho más rápido
• Los contenedores de Docker son mucho más pequeños y consumen muchos menos recursos.
• Los contenedores pueden ser compartidos entre varios equipos
• Los contenedores son más portables
• Los contenedores se pueden ejecutar en varias máquinas sin problemas de compatibilidad.
• Los contenedores pueden ser versionados, archivados, compartidos y facilitar la compatibilidad
7. Introducción a Docker
Motor Docker
El motor Docker es una aplicación
cliente-servidor con los siguientes
componentes:
• Un servidor o programa de
ejecución continua, ejecutado en
un proceso demonio (comando
dockerd)
• Una API REST con interfaces para
que los programas puedan ejecutar
funcionalidades del servidor.
• Una consola de comandos
(comando docker) o CLI, la cual
utiliza la REST API para interactuar
con el servidor Docker mediante
comandos.
8. Introducción a Docker
Arquitectura de Docker
• Docker daemon: El servidor Docker (comando dockerd)
• Docker client: La consola de comandos o CLI (comando docker)
• Docker registry: Almacena las imágenes Docker.
• Docker objects: Imágenes, contenedores, redes, volúmenes, plugins y otros objetos.
9. Introducción a Docker
Ventajas de Docker
• Beneficio para desarrolladores, testers y administradores de sistemas
• Sin preocupaciones de si el código se ejecutará o no en la máquina
• Sólo es necesario tener Docker, sin preocuparse de software
adicional ni de dependencias
• Es muy fácil copiar un contenedor para un entorno de pruebas
• Los contenedores son muy ligeros (por ejemplo, un contenedor Ubuntu
ocupa 64MB), con lo que podemos tener muchas más capacidades en
una máquina que con máquinas virtuales, ahorrando en máquinas físicas.
• Se pueden ejecutar múltiples contenedores en una misma máquina
• Casos de éxito:
• Ideal para flujos de integración continua y entrega continua (CI/CD)
• Desarrollo responsivo y escalado
• Ejecución de varias cargas de trabajo con el mismo hardware, al tener
más capacidad de computación
10. Indice
• Introducción a Docker
• Instalación de Docker
• Uso de imágenes
• Contenedores
• Creación de imágenes
• Desde un contenedor
• Desde Dockerfile
• Volúmenes
• Redes
• Compose
• Anexo
11. Instalación de Docker
Instalación
Docker se instala y se ejecuta sobre sistemas Linux:
CentOS: https://docs.docker.com/install/linux/docker-ce/centos/
Debian: https://docs.docker.com/install/linux/docker-ce/debian/
Fedora: https://docs.docker.com/install/linux/docker-ce/fedora/
Ubuntu: https://docs.docker.com/install/linux/docker-ce/ubuntu/
Para hacerlo funcionar en Windows, se requiere Windows 10 Professional,
aprovechando la características de utilizar el kernel de Linux y del Windows
Subsystem for Linux (WSL):
Windows: https://docs.docker.com/docker-for-windows/install/
12. Instalación de Docker
Comandos iniciales
Desde la consola de comandos se pueden ejecutar los comandos Docker:
// Versión de docker
$ docker –v
// Ayuda de comandos
$ docker --help
// Ayuda sobre un comando concreto
$ docker <comando> --help
// Ayuda del estado y configuración actual de Docker
$ docker info
13. Indice
• Introducción a Docker
• Instalación de Docker
• Uso de imágenes
• Contenedores
• Creación de imágenes
• Desde un contenedor
• Desde Dockerfile
• Volúmenes
• Redes
• Compose
• Anexo
14. Uso de imágenes
¿Qué es una imagen?
Una imagen es como una plantilla que incluye todo lo necesario para
ejecutar una aplicación (código, runtimes, dependencias, etc).
Una imagen es una combinación de un sistema de ficheros y parámetros.
A partir de las imágenes se crearán y configurarán los contenedores, sobre
los cuales se desplegarán y ejecutarán las aplicaciones.
Las imágenes se forman mediante diferentes capas de software,
comenzando con un sistema operativo. Dichas capas son de sólo lectura.
15. Uso de imágenes
Imágenes oficiales
Docker provee un repositorio público general de imágenes generadas por
fabricantes de software. En este repositorio podemos encontrar multitud de
imágenes para una gran cantidad de proyectos software:
https://hub.docker.com/
Algunas de las imágenes más populares son: PostgreSQL, MySQL, MariaDB,
Couchbase, Cassandra, Redis, MongoDB, Neo4j, Ubuntu, Debian, CentOS,
OpenSuse, Fedora, NodeJS, Golang, OpenJDK, Java, Swift, Rust, R, Python,
Ruby, PHP, Maven, Jenkins, Gradle, Sonarqube, Nginx, httpd, Apache,
Tomcat, RabbitMQ, ElasticSearch, Kibana, Solr, Wordpress, Joomla, Drupal
16. Uso de imágenes
Instalación de una imagen
Para instalar una imagen se utilizará el comando pull:
// comando: docker pull <imagen>[:tag|@digest]
$ docker pull debian
Using default tag: latest
latest: Pulling from library/debian
c7b7d16361e0: Pull complete
Digest:
sha256:41f76363fd83982e14f7644486e1fb04812b3894aa4e396137c3435ea
f05de88
Status: Downloaded newer image for debian:latest
docker.io/library/debian:latest
En el repositorio de la imagen correspondiente, se pueden encontrar los
diferentes tags de la imagen. Estos tags indican una determinada
característica o versión de la imagen, los cuales se utilizarán junto con el
comando pull.
17. Uso de imágenes
Listado de imágenes
Para listar las imágenes instaladas en Docker:
// Forma 1
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
debian latest 8e9f8546050d 4 weeks ago 114MB
// Forma 2
$ docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
debian latest 8e9f8546050d 4 weeks ago 114MB
La sintaxis
docker images
En realidad es un alias de la
sintaxis
docker image ls
Docker utiliza alias para
simplificar comandos.
18. Uso de imágenes
Información de una imagen
Para conocer la historia de una imagen específica instalada:
// sintaxis: docker image history –H <imagen|id imagen>
$ docker image history –H debian
Para obtener información detallada de la imagen:
// sintaxis: docker image inspect <imagen|id imagen>
$ docker image inspect debian
Podemos usar un alias para
simplificar el parámetro
inspect. Para ello, podemos
obviar el parámetro image:
docker inspect debian
Lo mismo ocurre con el
parámetro history:
docker history debian
19. Uso de imágenes
Eliminar una imagen
Para eliminar una imagen previamente instalada:
// sintaxis: docker image rm <imagen|id imagen>
$ docker image rm debian
Untagged: debian:latest
Untagged:
debian@sha256:41f76363fd83982e14f7644486e1fb04812b3894aa4e396137c3435eaf05de88
Deleted: sha256:8e9f8546050da8aae393a41d65ad37166b4f0d8131d627a520c0f0451742e9d6
Deleted: sha256:831b66a484dc30b193f5d64771e8c01fa7e8fa5c8dab3e5adab5bea21b4223a4
Docker ofrece un alias: docker rmi <imagen|id>
20. Indice
• Introducción a Docker
• Instalación de Docker
• Uso de imágenes
• Contenedores
• Creación de imágenes
• Desde un contenedor
• Desde Dockerfile
• Volúmenes
• Redes
• Compose
• Anexo
21. Contenedores
¿Qué son los contenedores?
El despliegue de las aplicaciones se realiza mediante contenedores, los
cuales se ejecutan nativamente en un proceso en Linux y comparten el
Kernel con otros contenedores, tomando la memoria que necesitan (como
cualquier otra aplicación). Básicamente, un contenedor es una instancia de
ejecución de una imagen, con capacidad de lectura y escritura.
Los contenedores son:
• Flexibles: Las aplicaciones complejas también se pueden contenederizar.
• Ligeros: Comparten el kernel, optimizando recursos.
• Portables: Se puede construir localmente, desplegarse en la nube y
ejecutarse en cualquier parte.
• Débilmente acoplados: Son autosuficientes y encapsulados.
• Escalables: Se pueden incrementar y distribuir réplicas de contenedores.
• Seguros: Aplican restricciones y aislamientos estrictos a procesos.
• Temporales: Los cambios desaparecen con el contenedor.
• Múltiples: Se puede ejecutar varios sobre una misma imagen.
Una imagen es de sólo
lectura, y su contenido es
persistente.
Un contenedor es de lectura
y escritura, pero su contenido
es temporal. Este contenido
desaparece cuando el
contenedor se elimina.
22. Contenedores
Un ejemplo sencillo
En primer lugar, vamos a instalar la imagen de Debian:
$ docker pull debian
Using default tag: latest
latest: Pulling from library/debian
c7b7d16361e0: Pull complete
Digest: sha256:41f76363fd83982e14f7644486e1fb04812b3894aa4e396137c3435eaf05de88
Status: Downloaded newer image for debian:latest
docker.io/library/debian:latest
A continuación, vamos a crear y ejecutar un contenedor de esta imagen:
$ docker container run -it debian /bin/bash
root@084d9517c8e6:/#
Cada contenedor tendrá su
propio comando de arranque,
normalmente a una consola
de comandos. En el ejemplo,
se arranca una consola bash
del sistema operativo, con
una sesión de usuario root.
Normalmente, para terminar
la ejecución del contenedor
desde su propia consola, se
utilizará el comando exit o
quit.
Para obtener la ayuda
completa de cómo arrancar
un contenedor:
$ docker run --help
Se puede abreviar mediante el siguiente comando (es un alias):
$ docker run -it debian /bin/bash
root@084d9517c8e6:/#
23. Contenedores
Listar contenedores
Para listar los contenedores actualmente activos:
$ docker ps
Para listar todos los contenedores, incluidos los detenidos:
$ docker ps -a
Se puede abreviar, utilizando el siguiente alias:
$ docker container ls
Para obtener ayuda del comando container:
$ docker container ls --help
$ docker ps --help
Parámetros interesantes:
- a: Todos los contenedores
(cualquier estado)
- all: Todos los contenedores
(cualquier estado)
-n 5: Últimos 5 contenedores
--last 5: Últimos 5 contened.
-l: Últimos contenedores
(cualquier estado)
--latest: Últimos contened.
(cualquier estado)
--no-trunc: Sin trucar salida
-q: Sólo ids numéricos
--quiet: Sólo ids numéricos
-s: Visualiza tamaño total
--size: Visualiza tamaño total
$ docker container --help
Para obtener ayuda de cada parámetro del comando container:
24. Contenedores
Configuración de puertos
Algunos contenedores versan sobre aplicaciones de algún servicio, y
exponen un puerto.
Veamos un ejemplo con el servidor web Nginx:
$ docker run –d --name cont-nginx -p 80:80 nginx
A la hora de crear y/o arrancar el contenedor, con el parámetro –p,
mapeamos un puerto de nuestra máquina con el puerto de uso interno del
contenedor:
// Instalación de la imagen de Nginx
$ docker pull nginx
El parámetro –d permite
ejecutar el contenedor en
background (de fondo).
El parámetro --name permite
asignar un nombre al
contenedor. Por defecto,
Docker le asigna un nombre
aleatorio.
El parámetro –p permite
mapear el puerto de la
máquina en la que tenemos
docker con el puerto interno
del contenedor. El primer
parámetro es el puerto en
nuestra máquina local. El
segundo parámetro es el
puerto expuesto en el
contenedor.
En este momento, el servidor Nginx está arrancado y escuchando por el
puerto 80. Si se accede a un navegador y se acceder a la url en localhost, se
accederá a la página principal de Nginx.
25. Contenedores
Nombres de contenedor
Cuando se crea un contenedor, automáticamente, Docker le asigna un
nombre aleatorio.
Podemos asignar un nombre mediante el parámetro --name:
$ docker run –d --name cont-nginx -p 80:80 nginx
También es posible modificar el nombre de un contenedor ya creado, a
través del parámetro rename:
El parámetro rename tiene
dos argumentos. El primero
es el nombre actual (a
modificar) y el nuevo nombre.
$ docker rename cont-nginx mi-nginx
26. Contenedores
Copiar archivos a un contenedor
Con el parámetro cp podemos copiar archivos de nuestra máquina local a
la ruta especificada dentro de un contenedor:
$ echo "Hola, mundo" > index.html
$ docker cp index.html mi-nginx:/usr/share/nginx/html
El primer argumento se
refiere al archivo o archivos
de origen, y el segundo a la
ruta de destino.
Cuando especificamos el
nombre del contenedor,
seguido de dos puntos (:), nos
referimos al contenedor de
Docker.
$ docker cp mi-nginx:/usr/share/nginx/html/50x.html .
Para copiar un archivo desde el contenedor a nuestra máquina:
El punto se refiere al directorio actual en nuestra máquina.
27. Contenedores
Parar la ejecución de un contenedor
Para detener la ejecución de un contenedor, usaremos el parámetro stop:
$ docker ps –a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORT
NAMES
ffb40376f2fc nginx "nginx -g 'daemon of…" 20 minutes ago Up 20 minutes 0.0.0.0:80-
>80/tcp mi-nginx
$ docker stop mi-nginx
mi-nginx
$ docker ps –a
CONTAINER ID IMAGE COMMAND CREATED STATUS
PORTS NAMES
ffb40376f2fc nginx "nginx -g 'daemon of…" 22 minutes ago Exited (0) 14 seconds ago
mi-nginx
La detención de un
contenedor significa la pausa
del mismo; no implica su
destrucción. Seguirá estando
vivo, y listo para ser
nuevamente reanudado.
Para detener el contenedor,
podemos referirnos a éste
mediante su nombre o
mediante su ID.
Si ejecutamos el comando:
$ docker ps
No se listarán aquellos
contenedores detenidos. Para
listarlos hay que usar el
argumento -a
28. Contenedores
Reanudar la ejecución de un contenedor
Para reaudar la ejecución de un contenedor detenido, usaremos el
parámetro start:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED
STATUS PORTS NAMES
$ docker start mi-nginx
mi-nginx
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED
STATUS PORTS NAMES
ffb40376f2fc nginx "nginx -g 'daemon of…" 54 minutes ago
Up 2 seconds 0.0.0.0:80->80/tcp mi-nginx
Para reanudar el contenedor,
podemos referirnos a éste
mediante su nombre o
mediante su ID.
Con el parámetro restart,
automáticamente se detiene
y vuelve a arrancar el
contenedor.
Si hubiera problemas en la ejecución de un contenedor (como un alto
consumo de RAM o ralentización), utilizaríamos el parámetro restart:
$ docker restart mi-nginx
29. Contenedores
Acceder al entorno del contenedor
Un contenedor suele tener como primera capa o capa base un sistema
operativo, por lo que podemos acceder a la consola del mismo:
$ docker exec -ti mi-nginx bash
root@ffb40376f2fc:/#
Ejecutar comandos en el
entorno del contenedor
permitiría, por ejemplo, lanzar
scripts, parar o detener
servicios, agregar o modificar
ficheros, etc.
Se puede agregar el
argumento –u <usuario>
para indicar el usuario de
sistema para ejecutar el
comando.
El argumento –ti significa
“terminal interactive”.
Normalmente se ejecuta el
bash o sh para lanzar la
consola de ese contenedor.
El parámetro exec –ti permite ejecutar un comando dentro del entorno
del contenedor. Por ejemplo:
$ docker exec -ti mi-nginx ls
bin dev home lib64 mnt proc run srv tmp var
boot etc lib media opt root sbin sys usr
// Detener el servicio de Nginx (y, por ende, el contenedor)
$ docker exec -u root -ti mi-nginx service nginx stop
// Acceder momentáneamente al entorno y ejecutar un comando del Sistema
$ docker exec –ti mi-nginx bash –c "whoami"
root
30. Contenedores
Pasar variables de entorno a un contenedor
Es posible pasar variables de entorno a un contenedor en el momento de
su creación y ejecución, mediante el parámetro -e:
$ docker run -d -e "nombre=Rafael" --name mi-nginx -p:80:80 nginx
82804f423029965ba12b86022f672d09f6e739632c727ceaa06a41aa0001d57e
$ docker exec -ti mi-nginx bash
root@82804f423029:/# echo $nombre
Rafael
root@82804f423029:/# env
HOSTNAME=82804f423029
nombre=Rafael
PWD=/
PKG_RELEASE=1~buster
HOME=/root
NJS_VERSION=0.3.6
TERM=xterm
SHLVL=1
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
NGINX_VERSION=1.17.5
_=/usr/bin/env
El uso de variables de
entorno puede ser muy útil
para generar contenedores
que cambien su
comportamiento de ejecución
en base al valor de estas
variables.
Lo más recomendable es
tener listas estas variables en
el Dockerfile (que veremos
más adelante).
31. Contenedores
Ejemplo de contenedor MySQL
En el siguiente ejemplo vamos a descargar la imagen de MySQL:
$ docker pull mysql
Existen más variables de
entorno, documentadas en el
repositorio de MySQL:
https://hub.docker.com/_/m
ysql
Deberíamos mapear el
puerto 3306 para poder
acceder externamente a la
base de datos.
Si tenemos el cliente de
MySQL en nuestra máquina
local, podemos pasar la ip
del contenedor mediante el
parámetro –h en mysql. Esta
ip se obtiene mediante:
docker inspect <contenedor>
Para crear el contenedor y arrancarlo, es necesario crear una variable de
entorno para definir la contraseña del usuario root:
$ docker run -d --name my-mysql -e "MYSQL_ROOT_PASSWORD=mi-root-password" mysql
Accedemos a la consola del sistema operativo del contenedor:
$ docker exec -ti my-mysql bash
Ejecutamos el cliente de MySQL:
root@d3d61a1cf30a:/# mysql -u root –pmi-root-password
32. Contenedores
Ejemplo de contenedor Postgres
En el siguiente ejemplo vamos a descargar la imagen y crear y ejecutar un
contenedor Postgres:
$ docker pull postgres
$ docker run -d --name mi-pg -e "POSTGRES_PASSWORD=12345678" -e "POSTGRES_USER=mi-pg" -
e "POSTGRES_DB=mi-pg-db" -p 5433:5432 postgres
$ docker exec -ti mi-pg bash
root@e9a32fa1b411:/# psql -d mi-pg-db -U mi-pg
psql (12.0 (Debian 12.0-2.pgdg100+1))
Type "help" for help.
mi-pg-db=# l
List of databases
Name | Owner | Encoding | Collate | Ctype | Access privileges
-----------+-------+----------+------------+------------+---------------------
mi-pg-db | mi-pg | UTF8 | en_US.utf8 | en_US.utf8 |
postgres | mi-pg | UTF8 | en_US.utf8 | en_US.utf8 |
template0 | mi-pg | UTF8 | en_US.utf8 | en_US.utf8 | =c/"mi-pg" +
| | | | | "mi-pg"=CTc/"mi-pg"
template1 | mi-pg | UTF8 | en_US.utf8 | en_US.utf8 | =c/"mi-pg" +
| | | | | "mi-pg"=CTc/"mi-pg"
(4 rows)
Las variables de entorno
utilizadas son:
POSTGRES_USER crea un
nuevo usuario
POSTGRES_PASSWORD
asigna una contraseña al
nuevo usuario
POSTGRES_DB genera una
nueva base de datos
33. Contenedores
Ejemplo de contenedor MongoDB
En el siguiente ejemplo vamos a descargar la imagen de MongoDB:
$ docker pull mongo
Para crear el contenedor y arrancarlo:
$ docker run -d --name mi-mongo -p 27017:27017 mongo
Accedemos a la consola del sistema operativo del contenedor:
$ docker exec -ti mi-mongo bash
Ejecutamos el cliente de MongoDB:
root@4ecbd116fe90:/# mongo
...
> db.help()
...
> db.version()
4.2.1
MongoDB requiere crear
manualmente el directorio
donde guarda los datos. Por
defecto es /data/db
34. Contenedores
Logs de un contenedor
Para realizar un seguimiento del log de un contenedor, usaremos el
parámetro logs:
$ docker logs -f my-mysql
El parámetro –f permite
hacer un seguimiento
completo en tiempo real. La
consola recoge el foco del
log.
35. Contenedores
Estadísticas de uso de un contenedor
Para visualizar estadísticas de uso de un contenedor, usaremos el
parámetro stats:
$ docker stats mi-mongo
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM % NET I/O BLOCK I/O
PIDS
4ecbd116fe90 mi-mongo 0.22% 67.73MiB / 1.952GiB 3.39% 5.45kB / 42.7kB 0B / 733kB
32
Las estadísticas se miden en
tiempo real.
Los indicadores son:
- Porcentaje de CPU
- Uso de memoria
- Límite de memoria
- Porcentaje de memoria
- Tráfico de entrada de red
- Tráfico de salida de red
- Bloques de entrada
- Bloques de salida
- PIDS
36. Contenedores
Limitar los recursos de un contenedor
Un contenedor se puede limitar en el momento de crearlo. Para limitar el
uso de memoria se utiliza el parámetro -m:
$ docker run -d -m "1gb" --name mi-mongo -p 27017:27017 mongo
$ docker stats mi-mongo
CONTAINER ID NAME CPU % MEM USAGE / LIMIT MEM %
NET I/O BLOCK I/O PIDS
20b1d7a9a375 mi-mongo 0.20% 67.72MiB / 1GiB 6.61%
788B / 0B 0B / 348kB 32
Para ayuda de estos
parámetros:
docker run --help | grep
memory
docker run --help | grep cpu
Si queremos limitar el número de CPUs utilizaremos el parámetro --cpus:
$ docker run -d -m "1gb" --cpus 2-3 --name mi-mongo -p 27017:27017 mongo
Como argumento indicamos que usaremos las CPUs 3 y 4 (CPU 1 = 0)
37. Contenedores
Eliminar un contenedor
Para eliminar un contenedor, usaremos el parámetro rm:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED
STATUS PORTS NAMES
ffb40376f2fc nginx "nginx -g 'daemon of…" 54 minutes ago Up
2 seconds 0.0.0.0:80->80/tcp mi-nginx
$ docker rm –f mi-nginx
$ docker ps –a
CONTAINER ID IMAGE COMMAND CREATED
STATUS PORTS NAMES
El parámetro –f fuerza la
detención y eliminación del
contenedor.
Si se especifica el parámetro
v, eliminará los volúmenes
asociados a ese contenedor.
El comando rm permite
especificar varios
contenedores en la misma
línea, separados por espacios
en blanco.
38. Indice
• Introducción a Docker
• Instalación de Docker
• Imágenes
• Contenedores
• Creación de imágenes
• Desde un contenedor
• Desde Dockerfile
• Volúmenes
• Redes
• Compose
• Anexo
39. Creación de imágenes desde un contenedor
Crear imagen desde un contenedor
La forma más simple es crear una imagen desde un contenedor, mediante
el parámetro commit:
$ docker commit mi-nginx nueva-imagen
Crear una imagen desde un
contenedor se lo conoce
como “congelar” un
contenedor.
Toma el contenedor
especificado, con todos sus
cambios (archivos,
configuración, etc.), y genera
una versión o foto de ese
contenedor en forma de
imagen.
Podemos comprobar que esta nueva imagen se ha creado y se ha añadido
al registro de Docker:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nueva-imagen latest 1aa78cfebe73 9 seconds ago 126MB
mongo latest 965553e202a4 2 weeks ago 363MB
nginx latest 540a289bab6c 3 weeks ago 126MB
mysql latest c8ee894bd2bd 4 weeks ago 456MB
postgres latest f88dfa384cc4 4 weeks ago 348MB
debian latest 8e9f8546050d 4 weeks ago 114MB
redis latest 01a52b3b5cd1 7 weeks ago 98.2MB
ubuntu latest 2ca708c1c9cc 2 months ago 64.2MB
40. Creación de imágenes desde un contenedor
Guardar imagen en un archivo tar
Las imágenes se guardan en el registro de Docker. Si deseamos obtener
una copia de la imagen en un fichero con formato tar, utilizaremos la
siguiente sentencia:
$ docker save nueva-image –o nueva-imagen.tar
Por defecto, el parámetro
save utiliza como canal
STDOUT. Con la opción –o
indicamos la salida a fichero.
El primer parámetro es el
nombre de la imagen.
El segundo parámetro (tras la
opción –o) es el nombre del
fichero resultante.
El parámetro load utiliza el
canal STDIN por defecto.
Con la opción –i indicamos
el fichero tar de entrada.
Si queremos cargar la imagen guardada en un archivo tar en un nuevo
Docker, utilizaremos la siguiente sentencia:
$ docker load –i nueva-imagen.tar
41. Creación de imágenes desde un contenedor
Ejemplo: Objetivo
Para este ejemplo, vamos a crear una imagen desde un contenedor, el cual
tendrá la siguiente configuración:
• Sistema Operativo Ubuntu (base)
• NodeJS
• Base de datos PostgreSQL
• Base de datos REDIS
• Base de datos MongoDB
El objetivo del ejemplo será
generar un entorno para
desarrollar nuestras
aplicaciones en NodeJS.
42. Creación de imágenes desde un contenedor
Ejemplo: Creación del contenedor
El primer paso será descargar y obtener la imagen de Ubuntu:
Tanto la imagen de Ubuntu
como la de CentOS requieren
ser arrancadas con el
parámetro –dti
MUY IMPORTANTE
Antes de crear el contenedor
es muy importante diseñar
previamente qué queremos
de éste cuando sea una
imagen. Por ejemplo, si
queremos exponer algún
puerto para nuestra
aplicación o si queremos
exponer los puertos de las
bases de datos para que
sean accesibles en remoto.
$ docker pull ubuntu
El siguiente paso será crear y arrancar el contenedor:
$ docker run -dti -p 1234:1234 -p 5432:5432 -p 27017:27017 -p
6379:6379 --name mi-contenedor ubuntu
A continuación, accedemos al contenedor:
$ docker exec –it mi-contenedor bash
Los puertos habilitados son: 1234 para la futura aplicación de NodeJS; 5432
para PostgreSQL; 27017 para MongoDB y 6379 para REDIS.
43. Creación de imágenes desde un contenedor
Ejemplo: Instalación de NodeJS
Antes de empezar cualquier instalación, actualizaremos Ubuntu:
Oficialmente, el comando
para lanzar NodeJS es node.
Sin embargo, en Ubuntu, este
comando es nodejs. Esto se
debe a que el nombre entra
en conflicto con otro paquete
de Ubuntu.
También se puede instalar
mediante PPA.
Para más información sobre
la instalación de NodeJS:
https://www.digitalocean.co
m/community/tutorials/how
-to-install-node-js-on-
ubuntu-18-04
root@1cbcf9a53278:/# apt-get update
root@1cbcf9a53278:/# apt-get upgrade
El siguiente paso será instalar el paquete de NodeJS:
root@1cbcf9a53278:/# apt-get install nodejs
Después, se instala el paquete de NPM:
root@1cbcf9a53278:/# apt-get install npm
Por último, verificamos que NodeJS funciona, obteniendo su versión:
root@1cbcf9a53278:/# nodejs –v
V8.10.0
44. Creación de imágenes desde un contenedor
Ejemplo: Instalación de PostgreSQL
La imagen de Ubuntu ofrece
un Kernel básico. Hay que
instalar paquetes adicionales
para poder ejecutar los
comandos anteriores:
• sudo
• wget
• lsb_release (lsb-
core)
• nano
Aunque se cite el uso de
systemctl para arrancar el
servidor de PostgreSQL como
un servicio, es mejor utilizar el
comando service.
Más info:
https://computingforgeeks.c
om/install-postgresql-12-on-
ubuntu/
Importar la firma del repositorio y actualizar la lista de paquetes de Ubuntu:
root@1cbcf9a53278:/# wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-
key add -
Añadir los contenidos de repositorio:
root@1cbcf9a53278:/# echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main"
|sudo tee /etc/apt/sources.list.d/pgdg.list
Instalar el paquete de PostgreSQL:
root@1cbcf9a53278:/# sudo apt-get update
root@1cbcf9a53278:/# sudo apt -y install postgresql-12 postgresql-client-12
Para arrancar el servidor de PostgreSQL, y lanzar el cliente psql:
root@1cbcf9a53278:/# sudo service postgresql start
root@1cbcf9a53278:/# sudo –u postgres –i
postgres@1cbcf9a54278:~$ psql
postgres-# l
45. Creación de imágenes desde un contenedor
Ejemplo: Instalación de MongoDB
Ejecutar los siguientes comandos:
Aunque se cite el uso de
systemctl para arrancar el
servidor de MongoDB como
un servicio, es mejor utilizar el
comando service.
Más info:
https://itsfoss.com/install-
mongodb-ubuntu/
root@1cbcf9a53278:/# sudo apt-get install mongodb
root@1cbcf9a53278:/# mkdir –p /data/db
Arrancar el servidor de MongoDB como un servicio:
root@1cbcf9a53278:/# sudo service mongodb start
Ejecutar la consola cliente de MongoDB:
root@1cbcf9a53278:/# mongo
MongoDB shell version v3.6.3
connecting to: mongodb://127.0.0.1:27017
MongoDB server version: 3.6.3
Welcome to the MongoDB shell.
For interactive help, type "help".
...
> show dbs
admin 0.000GB
local 0.000GB
> db.version()
> 3.6.3.
46. Creación de imágenes desde un contenedor
Ejemplo: Instalación de REDIS
Ejecutar el siguiente comando:
Más info:
https://tecadmin.net/install-
redis-ubuntu/
root@1cbcf9a53278:/# sudo apt-get install redis-server
Arrancar el servidor de REDIS:
root@1cbcf9a53278:/# redis-server &
Ejecutar la consola cliente de REDIS:
root@1cbcf9a53278:/# redis-cli
127.0.0.1:6379> help
redis-cli 4.0.9
To get help about Redis commands type:
"help @<group>" to get a list of commands in <group>
"help <command>" for help on <command>
"help <tab>" to get a list of possible help topics
"quit" to exit
To set redis-cli preferences:
":set hints" enable online hints
":set nohints" disable online hints
Set your preferences in ~/.redisclirc
47. Creación de imágenes desde un contenedor
Ejemplo: Ajustes del contenedor
El contenedor debe ajustarse a la configuración que deseamos para
generar la imagen.
Al principio, antes de crear el contenedor, hemos de configurar los puertos
que deseamos exponer y su fin. Es recomendable no exponer los puertos
de las bases de datos en un entorno de producción, y que sea la propia
aplicación NodeJS la que acceda de forma exclusiva.
Una vez creado el contenedor, podemos configurar servicios, scripts de
inicio, variables de entorno, usuarios concretos, etc. Es importante la
configuración de arranque automática de los servicios.
Una vez tengamos listo el contenedor con la configuración deseada,
procederemos a generar la imagen.
48. Creación de imágenes desde un contenedor
Ejemplo: Generación de la imagen
Salimos del contenedor para volver al S/O donde gestionamos Docker:
root@1cbcf9a53278:/# exit
Generamos la imagen a partir del contenedor:
$ docker commit mi-contenedor mi-imagen
sha256:4a79f723b0f65aa3bf830a4d14f859372a297262abc9ae82a114033dfb60c337
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
mi-imagen latest 4a79f723b0f6 About a minute ago 1.21GB
ubuntu latest 775349758637 2 weeks ago 64.2MB
Guardamos la imagen en un archivo tar:
$ docker save mi-imagen -o mi-imagen.tar
49. Creación de imágenes desde un contenedor
Ejemplo: Generar contenedores a partir de la imagen
Creamos el contenedor, mapeando los puertos que necesitemos:
$ docker run -dti -p 1234:1234 -p 6379:6379 -p 5432:5432 -p
27017:27017 --name mi-cont mi-imagen
Accedemos al nuevo contenedor:
$ docker exec -it mi-cont bash
Probamos los componentes del contenedor:
root@4d6284c5db02:/# nodejs -v
v8.10.0
root@4d6284c5db02:/# service mongodb start
root@4d6284c5db02:/# mongo
root@4d6284c5db02:/# redis-server &
root@4d6284c5db02:/# redis-cli
root@4d6284c5db02:/# sudo service postgresql start
root@4d6284c5db02:/# sudo -u postgres –i
postgres@4d6284c5db02:~$ psql
Para el ejemplo, no
configuramos ni ajustamos el
contenedor, de ahí que
tengamos que arrancar los
servicios manualmente.
Si hubiésemos configurado
correctamente el contenedor
original, cuando creásemos
el nuevo contenedor a partir
de la imagen,
automáticamente habrían
arrancado los servicios.
Por ejemplo, podríamos
haber introducido todo como
un script en /root/.bashrc,
de forma que arrancase
automáticamente
50. Indice
• Introducción a Docker
• Instalación de Docker
• Imágenes
• Contenedores
• Creación de imágenes
• Desde un contenedor
• Desde Dockerfile
• Volúmenes
• Redes
• Compose
• Anexo
51. Creación de imágenes desde Dockerfile
Qué es Dockerfile
Dockerfile es un fichero que describe a Docker cómo construir una nueva
imagen sin necesidad de generar un contenedor previamente. Es decir,
contiene la configuración de la imagen.
Vamos a crear un fichero Dockerfile para construir una imagen basada en
Ubuntu (sistema operativo de base), y con un entorno de aplicaciones
basado en NodeJS y MongoDB:
FROM ubuntu
RUN apt-get update -y
RUN apt-get upgrade -y
RUN apt-get install sudo -y
RUN sudo apt-get install nodejs -y
RUN sudo apt-get install npm –y
RUN sudo npm install pm2 -g
RUN sudo apt-get install mongodb –y
RUN sudo mkdir –p /data/db
RUN echo "sudo service mongodb start" >> /root/.bashrc
La línea FROM indica la
imagen inicial, la cual Docker
importará (docker pull).
Cada línea RUN creará una
capa de construcción y
ejecutará un comando sobre
la imagen importada.
El parámetro –y sirve para
que la instalación de ciertos
paquetes asuma yes por
defecto. Si no se hace esto, la
ejecución se para hasta que
el usuario responda.
En Windows, utilizar un editor
de textos que no sea el Bloc
de Notas, ya que deja
caracteres ocultos que no
entiende Docker.
52. Creación de imágenes desde Dockerfile
Construir la imagen a partir del Dockerfile
Para generar la imagen desde Dockerfile usaremos el parámetro build:
$ docker build -t img-node-mongo . El parámetro –t indica el tag
o nombre de la imagen. En
este caso sería img-node-
mongo.
El último parámetro indica la
ruta donde se encuentra el
archivo Dockerfile (el
punto indica el directorio
actual).
Por defecto utiliza un archivo
llamado Dockerfile. Si el
fichero tiene distinto nombre
utilizaremos el parámetro –f
seguido del nombre del
archivo.
En el ejemplo, asumimos el
puerto 1234 como el puerto a
exponer por la app NodeJS
Verificar que se ha creado la imagen y añadido al registro de Docker:
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
img-node-mongo latest e782751328aa 14 seconds ago 625MB
Crear un contenedor basado en esta imagen:
$ docker run -dti --name cont-nodemongo img-node-mongo
De16318303c2743696c4597e59fac98dcd8c166fbf02dba147f4ffa3e8ae9e58
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
de16318303c2 img-node-mongo "/bin/bash" 4 minutes ago Up 4 minutes cont-nodemongo
Acceder al contenedor:
$ docker exec -it cont-nodemongo bash
* Starting database mongodb [ OK ]
root@de16318303c2:/#
53. Creación de imágenes desde Dockerfile
Comando FROM
FROM
Normalmente, se parte de
una imagen de un sistema
operativo.
A partir de esta imagen,
iremos añadiendo
componentes o capas a la
nueva imagen.
Permite comenzar una imagen a partir de una imagen inicial.
Sintaxis:
FROM <imagen>
Ejemplos:
FROM ubuntu
FROM debian
FROM centos
FROM nginx
FROM node
54. Creación de imágenes desde Dockerfile
Comando RUN
RUN
El comando RUN es útil para
ejecutar los comandos de
instalación en la imagen.
Se suele agregar al inicio del
Dockerfile
Permite ejecutar un comando.
Sintaxis:
RUN <comando> <param1> <param2>
RUN ["comando", "param1", "param2"]
Ejemplos:
RUN apt-get install sudo
RUN ["apt-get", "install", "sudo"]
RUN echo "Bienvenido"
55. Creación de imágenes desde Dockerfile
Comando COPY
COPY
En el ejemplo, copia el
contenido de la carpeta
proyecto de nuestra
máquina local a la ruta
/var/www/html en la
imagen
Permite copiar archivos desde nuestra máquina local a la imagen.
Sintaxis:
COPY <origen> <destino>
Ejemplos:
COPY proyecto /var/www/html
56. Creación de imágenes desde Dockerfile
Comando ADD
ADD
Para copiar archivos desde
nuestra máquina, es
recomendable utilizar el
comando COPY.
Permite copiar archivos desde nuestra máquina local o una URL concreta a
la imagen.
Sintaxis:
ADD <origen> <destino>
Ejemplos:
ADD proyecto /var/www/html
57. Creación de imágenes desde Dockerfile
Comando ENV
ENV
Las variables de entorno son
muy útiles para definir rutas,
usuarios o valores clave que
podemos usar en nuestros
entornos.
Permite crear variables de entorno y asignarles un valor.
Sintaxis:
ENV <variable> <valor>
Ejemplos:
ENV ruta ~/miruta
58. Creación de imágenes desde Dockerfile
Comando WORKDIR
WORKDIR
Este comando es muy útil si
realizamos diferentes copias
de archivos a la misma ruta
como base.
Si en la copia especificamos
el punto (.) como ruta de
destino, la copia se realizará
en la ruta especificada por
WORKDIR
Define la ruta de trabajo en la imagen.
Sintaxis:
WORKDIR <ruta>
Ejemplos:
WORKDIR /var/www
59. Creación de imágenes desde Dockerfile
Comando EXPOSE
EXPOSE
El puerto a exponer debe
estar disponible por del
software que corre bajo la
imagen.
Por ejemplo, si la imagen
contiene un servidor Apache,
sólo se puede exponer el
puerto 80 (por defecto). Si se
desea cambiar el puerto, o
bien mapeamos el
contenedor en su creación, o
bien cambiamos la
configuración de Apache
para que apunte a otro
puerto distinto.
Permite exponer un puerto en la imagen para que sea accedido desde la
máquina donde se ejecute el contenedor.
Sintaxis:
EXPOSE <puerto>
Ejemplos:
EXPOSE 8080
60. Creación de imágenes desde Dockerfile
Comando LABEL
LABEL
Las etiquetas no influyen ni
afectan al software de la
imagen. Definen datos
descriptivos o informativos de
la propia imagen.
Las etiquetas se suelen
definir al principio del
Dockerfile, justo después
del comando FROM
Define etiquetas a la imagen, a modo de metadata.
Sintaxis:
LABEL <etiqueta>=<valor>
Ejemplos:
LABEL version=1.0
LABEL descripcion="Entorno optimizado para Web"
61. Creación de imágenes desde Dockerfile
Comando USER
USER
Por defecto, el usuario que
ejecuta los comandos del
Dockerfile, es el usuario
root.
En algunos sistemas se
definen usuarios concretos
(por ejemplo, en las bases de
datos).
Especifica qué usuario va a ejecutar los próximos comandos.
Sintaxis:
USER <usuario>
Ejemplos:
USER postgres
62. Creación de imágenes desde Dockerfile
Comando VOLUME
VOLUME
Recordemos que los
contenedores son
temporales, ya que son
instancias de una imagen.
Por tanto, los datos que se
generen durante su ejecución
se eliminarán cuando éste se
elimine.
Un volumen permite que los
datos de una determinada
ruta sobrevivan a la actividad
del contenedor.
Podemos listar los volúmenes
mediante el comando:
docker volumen list
Para eliminar un volumen:
docker volumen rm <vol>
Especifica una ruta, dentro del volumen, en donde los archivos serán
persistentes después de que el contenedor se detenga o se elimine.
Sintaxis:
VOLUME <ruta>
Ejemplos:
VOLUME /var/www/html
63. Creación de imágenes desde Dockerfile
Comando CMD
CMD
El comando CMD es útil para
ejecutar scripts o levantar
servicios.
Se suele agregar al final del
Dockerfile, cuando todas
las operaciones de
instalación y configuración ya
han sido ejecutadas.
El comando RUN se utiliza
para la instalación de
paquetes.
El comando CMD se ejecuta
por defecto como punto de
entrada a la imagen, cuando
ejecutamos el contenedor
como
docker run -it
Permite ejecutar un comando.
Sintaxis:
CMD ["comando", "param1", "param2"]
CMD <comando> <param1> <param2>
Ejemplos:
CMD apachectl –DFOREGROUND
CMD service apache2 start
CMD ~/script.cmd
CMD service mongodb start
…
$ docker run --name cont-nodemongo –it img-node-mongo
64. Creación de imágenes desde Dockerfile
Comando ENTRYPOINT
ENTRYPOINT
El comando ENTRYPOINT es
útil para ejecutar scripts o
levantar servicios.
Este comando se suele
utilizar cuando queremos que
el contenedor se ejecute
como un ejecutable.
Si después se añade CMD,
éste se utilizará como los
parámetros de ENTRYPOINT.
Se suele agregar al final del
Dockerfile, cuando todas
las operaciones de
instalación y configuración ya
han sido ejecutadas.
Permite ejecutar un comando como punto de entrada del contenedor.
Sintaxis:
ENTRYPOINT ["comando", "param1", "param2"]
ENTRYPOINT <comando> <param1> <param2>
Ejemplos:
ENTRYPOINT apachectl –DFOREGROUND
ENTRYPOINT ["service", "mongodb", "start"]
65. Creación de imágenes desde Dockerfile
Consejos para crear imágenes
1. Generar de imágenes livianas
2. Restringir el número de capas
3. Instalar únicamente lo justo y necesario
4. Crear un único servicio por imagen
5. Utilizar metadata para una mejor comprensión
66. Indice
• Introducción a Docker
• Instalación de Docker
• Imágenes
• Contenedores
• Creación de imágenes
• Desde un contenedor
• Desde Dockerfile
• Volúmenes
• Redes
• Compose
• Anexo
67. Volúmenes
Introducción a los volúmenes
A modo de repaso, los contenedores son instancias de una imagen, y como
tales son transitorios, por lo que la información que se genere (datos,
archivos, etc.), desaparecerá cuando el contenedor se elimine.
Un contenedor que contenga una base de datos con información
importante perdería los datos y sería un problema. Pero gracias a los
volúmenes, esta información persistiría, conservando los cambios en
cualquier momento.
Un volumen es también interesante para persistir ficheros de log.
Existen tres tipos de volúmenes:
• Anfitriones (host volumes)
• Anónimos (anonymous volumes)
• Nominativos (named volumes)
68. Volúmenes
Volúmenes anfitriones
El parámetro –v permite
definir un volumen,
sincronizando una carpeta
local con una carpeta del
contenedor (en ese orden).
Si se cayera o se eliminase el
contenedor, los datos estarán
salvaguardados en la
carpeta mapeada en local.
A la hora de generar de
nuevo el contenedor, hay que
mapear exactamente igual
para que el nuevo
contenedor se sincronice con
la carpeta en local.
Un volumen anfitrión permite mapear una carpeta de nuestra máquina
hacia una carpeta del contenedor. De esta manera, automáticamente, se
sincronizará el contenido del contenedor con nuestra máquina.
Imaginemos una imagen con MySQL, y queremos sincronizar una carpeta
de nuestra máquina (donde corre Docker) con la carpeta donde MySQL
guarda los datos. El mapeo se realiza en el momento de crear y ejecutar el
contenedor:
$ docker run –d --name cont-mysql –e
"MYSQL_ROOT_PASSWORD=myrootpassword" –p 3306:3306 –v
/micarpeta:/var/lib/mysql mysql:5.5
69. Volúmenes
Volúmenes anónimos
La carpeta volumes se puede
encontrar dentro del sistema
de Docker.
Este comando nos dice cuál
es el directorio de Docker:
$ docker info | grep –i
root
Docker Root Dir:
/home/miusuario/docker
Podemos averiguar la ruta y
la carpeta del volumen
mediante este comando:
$ docker inspect
Por eficiencia, no es
recomendable utilizar
volúmenes anónimos
Un volumen anónimo sincroniza una carpeta del contenedor, creando una
carpeta aleatoria dentro de la carpeta volumes en el directorio de Docker.
Para crear un volumen anónimo, a la hora de crear y arrancar el contenedor,
indicamos el parámetro –v, pero sin especificar una carpeta local
(solamente la ruta en el contenedor):
$ docker run –d --name cont-mysql –e
"MYSQL_ROOT_PASSWORD=myrootpassword" –p 3306:3306 –v /var/lib/mysql
mysql:5.5
70. Volúmenes
Volúmenes nominativos
Por defecto, todos los
archivos de la carpeta del
contenedor se copiarán a la
carpeta del volumen,
concretamente, a la carpeta
_data.
Como en los volúmenes
anónimos, si el contenedor se
elimina con la opción –f, la
carpeta del volumen en la
máquina local, persistirá los
datos para recuperarlos en la
creación de un nuevo
contenedor.
Un volumen nominativo se genera desde un Dockerfile mediante el
comando VOLUME, el cual indica qué carpeta del contenedor contendrá la
información a persistir.
Cuando se crea y se arranca el contenedor, automáticamente genera un
volumen anónimo que se sincroniza con esa carpeta. Por tanto, no es
necesario especificar el parámetro –v en la creación del contenedor.
Para conocer los volúmenes utilizaremos el siguiente comando:
$ docker volume ls
Otra forma es crear el volumen con un nombre legible mediante:
$ docker volume create volume_datos
Y después mapearlo a la hora de crear y arrancar el contenedor:
$ docker run –d --name cont-mysql –e "MYSQL_ROOT_PASSWORD=myrootpassword" –p 3306:3306
–v volumen_datos:/var/lib/mysql mysql:5.5
71. Volúmenes
Eliminar volúmenes
Para eliminar un volumen utilizamos el siguiente comando:
$ docker volume rm <volume>
También podemos eliminar el volumen a la hora de borrar el contenedor
con el que está vinculado, utilizando el parámetro –fv:
$ docker rm –fv mi-contenedor
La forma
docker volumen rm xxx
afecta únicamente a
volúmenes creados de forma
anónima o nominativa.
Recordemos que si borramos
un contenedor con el
parámetro –f (sin la v), el
contenedor se borra, pero el
volumen no.
72. Indice
• Introducción a Docker
• Instalación de Docker
• Imágenes
• Contenedores
• Creación de imágenes
• Desde un contenedor
• Desde Dockerfile
• Volúmenes
• Redes
• Compose
• Anexo
73. Redes
La interfaz de red de Docker
En cada contenedor, Docker genera una interfaz de red con el contenedor.
Para averiguar esta interfaz, utilizaremos el siguiente comando:
$ docker inspect mi-contenedor
La IP del Gateway es la IP
utilizada por la interfaz de
Docker.
IPAddress contiene la IP del
contenedor dentro del
Gateway.
Cuando creamos un
contenedor, de forma
automática, Docker creará y
asignará una red a dicho
contenedor.
Adicionalmente, podemos
crear y configurar una red y
asignarla a un determinado
contenedor.
De toda la información del contenedor encontraremos la siguiente:
"Networks": {
"bridge": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "fc92ed9b3b3e3364de4f5654a99ba4c26528ea84d55e5b9511a62707c099f144",
"EndpointID": "96a71718f6764fc281a02d80a03b7bf0a054f6d2ea12b63f3a9cf0b1266e9ea4",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
}
}
74. Redes
La red de Docker en detalle
Para visualizar los detalles de las redes usadas por Docker:
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
fc92ed9b3b3e bridge bridge local
807c2153859e host host local
7d4afbc3d9a6 none null local
Todos los contenedores se
configuran a esta red de
Docker.
Cuando hacemos un
docker inspect <contenedor>
En la clave “Networks”
veremos que se configura con
el driver “bridge”.
Desde un contenedor
podemos hacer un ping a la
red de otro contenedor, o
realizar accesos de uno a otro
contenedor a través de la red.
Las redes que nos interesan serán de tipo bridge.
$ docker network inspect bridge
Retornará todo el detalle de la configuración de una red.
Adicionalmente, podemos crear nuestras propias redes mediante:
$ docker network create [opciones] <nombre_red>
Para más info: docker network create --help
75. Redes
Creación de una red
Para más info:
docker network create --
help
Para crear nuestras propias redes utilizaremos el siguiente comando:
$ docker network create [opciones] <nombre_red>
Existen multitud de parámetros de configuración.
En el siguiente comando configuraremos una red con las opciones más
básicas.
$ docker network create –d bridge --subnet 172.17.0.0/24 --gateway 172.17.0.1 mi-red
Para inspeccionar los detalles de esta nueva red:
$ docker network inspect mi-red
Para verificar que la red se ha añadido a la lista de redes de Docker:
$ docker network ls
76. Redes
Asignar una red distinta a un contenedor
Si no se especifican opciones
al comando create, Docker
generará automáticamente
una red con unos valores
sugeridos.
Para más info:
docker network create --
help
Para asignar una red a un contenedor, lo haremos en el momento de crear y
ejecutar dicho contenedor, a través del parámetro --network:
$ docker run –d --network mi-red --name mi-contenedor mi-imagen
Para inspeccionar los detalles del contenedor y comprobar la red:
$ docker inspect mi-contenedor
"Networks": {
"mi-red": {
"IPAMConfig": null,
"Links": null,
"Aliases": null,
"NetworkID": "fc92ed9b3b3e3364de4f5654a99ba4c26528ea84d55e5b9511a62707c099f144",
"EndpointID": "96a71718f6764fc281a02d80a03b7bf0a054f6d2ea12b63f3a9cf0b1266e9ea4",
"Gateway": "172.17.0.1",
"IPAddress": "172.17.0.2",
"IPPrefixLen": 24,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "02:42:ac:11:00:02",
"DriverOpts": null
}
}
77. Redes
Conectar una red a un contenedor
El contenedor seguirá
perteneciendo a la red en la
que se creó. Pero ahora podrá
estar conectado también a la
nueva red.
Cuando creamos un contenedor, éste está asignado a una determinada red,
pero podemos conectarle a otra red mediante el parámetro connect:
$ docker network otra-red mi-contenedor
Para inspeccionar los detalles del contenedor y comprobar la red:
$ docker inspect mi-contenedor
Ahora la propiedad Networks tendrá dos redes: la red (original) con la que
se creó el contenedor, y la red que le acabamos de conectar.
78. Redes
Desconectar y eliminar redes
La desconexión no elimina la
red implicada.
Docker no permitirá eliminar
una red que esté siendo
utilizada por algún
contenedor. Previamente,
habría que desconectar esa
red o eliminar el contenedor.
Para desconectar una red de un contenedor:
$ docker network disconnect mi-red mi-contenedor
Para eliminar una red de Docker:
$ docker network rm mi-red
79. Indice
• Introducción a Docker
• Instalación de Docker
• Imágenes
• Contenedores
• Creación de imágenes
• Desde un contenedor
• Desde Dockerfile
• Volúmenes
• Redes
• Compose
• Anexo
80. Compose
¿Qué es Docker Compose?
Mientras que para Linux se
requiere de instalación
adicional para Docker
Compose, en Windows ya
está incluido en Docker
Desktop.
El parámetro –d permite
ejecutar todo en background.
Si se omite, la consola se
quedará bloqueada con la
ejecución de Docker
Compose.
Docker Compose es una herramienta que permite definir y ejecutar
aplicaciones con múltiples contenedores Docker.
Básicamente, generamos un archivo llamado docker-compose.yml, el cual
contiene la definición y la configuración de todos los contenedores y
servicios necesarios para ejecutar las aplicaciones.
Para ejecutar las aplicaciones y servicios usamos el siguiente comando:
$ docker-compose up -d
Para detener y eliminar los contenedores y servicios generados, se utilizaría
el siguiente comando:
$ docker-compose down
81. Compose
Un ejemplo sencillo
Automáticamente, se creará
el contenedor y se iniciará el
servicio de Apache, por lo que
podemos acceder a la página
por defecto con
http://localhost
Si queremos usar un archivo
yaml con diferente nombre,
hemos de especificar este
archivo mediante el
parámetro –f del comando
docker-compose.
Vamos a crear el archivo docker-compose.yml, con el siguiente contenido:
$ docker-compose up -d
Automáticamente, el servidor Apache será lanzado y podemos acceder vía
web a la página por defecto con http://localhost
version: "3.7"
services:
web:
image: apache:latest
ports:
- "80:80"
Lanzamos la Docker Compose:
82. Compose
Partes de docker-compose.yml
Para más información sobre
estos comandos:
https://docs.docker.com/
compose/compose-file/
El archivo docker-compose.yml, está formado por las siguientes secciones:
• version (obligatorio): Versión de Composer en la que está definido este
archivo
• services (obligatorio): Define todas las características de los servicios
que va a tener la aplicación: imágenes, contenedores, puertos, etc.
• volumes (opcional): Definición de volúmenes
• network (opcional): Definición de las redes
83. Compose
Variables de entorno
$ docker exec -it docker-compose_db_1 bash
root@453281301e7e:/# mysql -u root mysql -u root -p
Enter password:
Se pueden definir las
variables de entorno en un
archivo externo, con extensión
.env. En este caso,
utilizaremos el parámetro
env_file para indicar el
archivo en el que se
encuentran estas variables,
Para más información:
https://docs.docker.com/
compose/environment-
variables/
El parámetro environment permite definir las variables de entorno que
necesitarán las aplicaciones.
El siguiente ejemplo crea un entorno con MySQL, definiendo la contraseña
del usuario root:
version: "3.7"
services:
db:
image: mysql:latest
ports:
- "3306:3306"
environment:
- "MYSQL_ROOT_PASSWORD=my-root-password"
84. Compose
Volúmenes
Docker Compose crea el
prefijo docker-compose para
el volumen y otros elementos,
tomando dicho prefijo del
nombre de la carpeta actual.
Si queremos modificar este
prefijo, utilizaremos la opción
–p en el comando docker-
compose.
Para más información sobre
volúmenes:
https://www.linux.com/tu
torials/docker-volumes-
and-networks-compose/
$ docker volume ls
DRIVER VOLUME NAME
local c9040d5bb7d0f586239d0bba17ebafb7fab4d1be1f9da12add3803410dab1c29
local docker-compose_mi-volumen
local f6a295ab16e56d144bff53c23024b5bb3f138908f3d597fa81fba2c4ad8b886b
Para definir volúmenes, utilizaremos el parámetro volumes en la sección
services, y lo completamos en la sección volumes:
version: "3.7"
services:
db:
image: mysql:latest
ports:
- "3306:3306“
volumes:
- "mi-volumen:/var/lib/mysql"
environment:
- "MYSQL_ROOT_PASSWORD=my-root-password“
volumes:
mi-volumen:
85. Compose
Redes
La sección networks
funciona como el comando
docker network.
Para más información sobre
redes:
https://docs.docker.com/
compose/networking/
Para definir y utilizar redes, utilizaremos la sección networks para crear la
red, y en la sección services, asignaremos dicha red al servicio concreto:
version: "3.7"
services:
db:
image: mysql:latest
ports:
- "3306:3306“
volumes:
- "mi-volumen:/var/lib/mysql“
networks:
- mi-red
environment:
- "MYSQL_ROOT_PASSWORD=my-root-password“
volumes:
mi-volumen:
networks:
mi-red:
$ docker network ls
NETWORK ID NAME DRIVER SCOPE
fc92ed9b3b3e bridge bridge local
4d487dd906ea docker-compose_default bridge local
3e0477e26e5b docker-compose_mi-red bridge local
807c2153859e host host local
7d4afbc3d9a6 none null local
86. Indice
• Introducción a Docker
• Instalación de Docker
• Imágenes
• Contenedores
• Creación de imágenes
• Desde un contenedor
• Desde Dockerfile
• Volúmenes
• Redes
• Compose
• Anexo
87. Anexo
Enlaces de interés
• Docker: Página oficial: https://www.docker.com/
• Docker: Documentación: https://docs.docker.com/
• Docker: Arquitectura: https://docs.docker.com/engine/docker-overview/#docker-architecture
• Docker Hub: Imágenes: https://hub.docker.com/
• Docker Compose: Documentación: https://docs.docker.com/compose/
• Docker Compose: Referencia de comandos: https://docs.docker.com/compose/compose-file/
• ¿Qué es Docker? (sencillo): https://www.javiergarzas.com/2015/07/que-es-docker-sencillo.html
• Docker Vs VMWare: https://www.upguard.com/articles/docker-vs.-vmware-how-do-they-stack-up
88. Anexo
Libros
• Introduction to Docker:
https://learnitguide.tradepub.com/free/w_pacb29/
• Learning Docker:
https://riptutorial.com/Download/docker.pdf
89. Anexo
Libros
• Docker in action:
https://www.allitebooks.in/docker-in-action/
• Docker in practice:
https://www.allitebooks.in/docker-in-practice/
• Docker containerization cookbook:
https://learnitguide.tradepub.com/free/w_java39/