Recuperación e implementación local de una imagen de Docker existente
Docker es una tecnología que permite implementar aplicaciones y servicios de forma rápida y sencilla. Una aplicación de Docker se ejecuta con una imagen de Docker. Una imagen de Docker es un entorno previamente empaquetado que contiene el código de la aplicación y el entorno en el que se ejecuta el código.
En el escenario corporativo que se ha descrito antes, quiere investigar la viabilidad de empaquetar y ejecutar una aplicación con Docker. Decide compilar e implementar una imagen de Docker en la que se ejecuta una aplicación web de prueba.
En esta unidad, obtendrá información sobre los conceptos clave y los procesos implicados en la ejecución de una aplicación en contenedores almacenada en una imagen de Docker.
Información general de Docker
Docker es una herramienta para ejecutar aplicaciones en contenedores. Una aplicación en contenedores incluye la aplicación y el sistema de archivos que compone el entorno en el que se ejecuta. Por ejemplo, una aplicación en contenedores podría constar de una base de datos y de otra información relacionada de software y configuración necesaria para ejecutar la aplicación.
Normalmente, una aplicación en contenedores tiene una superficie de memoria mucho menor que una máquina virtual configurada para ejecutar la misma aplicación. Esta superficie de memoria más reducida se debe a que una máquina virtual tiene que facilitar el sistema operativo completo y el entorno de respaldo asociado. Un contenedor de Docker no tiene esta sobrecarga, porque Docker usa el kernel del sistema operativo del equipo host para alimentar el contenedor. La descarga y el inicio de una imagen de Docker son mucho más rápidos y más eficaces en lo que al espacio respecta que la descarga y ejecución de una máquina virtual que proporciona una funcionalidad similar.
Para crear una aplicación en contenedores, se compila una imagen que contiene un conjunto de archivos y una sección de información de configuración que usa Docker. Para ejecutar la aplicación, hay que pedir a Docker que inicie un contenedor basado en la imagen. Cuando el contenedor se inicia, Docker usa la configuración de la imagen para determinar qué aplicación se va a ejecutar dentro del contenedor. Docker proporciona los recursos del sistema operativo y la seguridad necesaria. Garantiza que los contenedores se ejecutan simultáneamente y permanecen relativamente aislados.
Importante
Docker no proporciona el nivel de aislamiento disponible con las máquinas virtuales. Una máquina virtual implementa el aislamiento en el nivel de hardware. Los contenedores de Docker comparten bibliotecas y recursos del sistema operativo subyacentes. Sin embargo, Docker impide que un contenedor acceda a los recursos de otro si esos contenedores no están configurados para ello.
Puede ejecutar Docker en el equipo de escritorio o portátil si realiza el desarrollo y las pruebas de forma local. Para los sistemas de producción, Docker está disponible para entornos de servidor, incluidas muchas variantes de Linux y Microsoft Windows Server 2016. Muchos proveedores también admiten Docker en la nube. Por ejemplo, puede almacenar imágenes de Docker en Azure Container Registry y ejecutar contenedores con Azure Container Instances.
En este módulo, usará Docker localmente para compilar y ejecutar una imagen. Posteriormente, cargará la imagen en Azure Container Registry y la ejecutará en Azure Container Instances. Esta versión de Docker es adecuada para el desarrollo local y las pruebas de imágenes de Docker.
Imágenes de Docker de Windows y Linux
Docker se desarrolló en principio para Linux y se ha ampliado después para admitir Windows. Las imágenes de Docker individuales se basan en Windows o Linux, pero no en ambos al mismo tiempo. El sistema operativo de la imagen determina qué tipo de entorno del sistema operativo se usa dentro del contenedor.
Los creadores de imágenes de Docker que quieran ofrecer una funcionalidad similar tanto en las imágenes basadas en Linux como en Windows pueden crear esas imágenes por separado. Por ejemplo, Microsoft ofrece imágenes de Docker para Windows y Linux con un entorno de ASP.NET Core que se puede usar como base para las aplicaciones ASP.NET Core en contenedores.
En los equipos Linux con Docker instalado solo se pueden ejecutar contenedores de Linux. En los equipos Windows con Docker instalado se pueden ejecutar los dos tipos de contenedores. Para ello, Windows usa una máquina virtual para ejecutar un sistema Linux y usa el sistema virtual de Linux para ejecutar los contenedores de Linux.
En este módulo, compilará y ejecutará una imagen basada en Linux.
Registros de Docker y Docker Hub
Las imágenes de Docker se almacenan y se ofrecen en registros. Un registro es un servicio web al que Docker se puede conectar para cargar y descargar imágenes de contenedor. El registro más conocido es Docker Hub, que es un registro público. Muchos usuarios y organizaciones publican imágenes en Docker Hub, y puede descargarlas y ejecutarlas con Docker si lo ejecuta en el escritorio, en un servidor o en la nube. Puede crear una cuenta de Docker Hub y cargar imágenes de forma gratuita.
Un registro se organiza como una serie de repositorios. Cada repositorio contiene varias imágenes de Docker que comparten un nombre común (y, por lo general, la misma finalidad y funcionalidad). Estas imágenes suelen tener versiones diferentes que se identifican con una etiqueta. Este mecanismo permite publicar y mantener varias versiones de imágenes por motivos de compatibilidad. Cuando descargue y ejecute una imagen, tendrá que especificar el registro, el repositorio y la etiqueta de versión de la imagen. Las etiquetas son etiquetas de texto, y puede usar su sistema de numeración (v1.0, v1.1, v1.2, v2.0, etc.).
Imagine que quiere usar la imagen de Docker de ASP.NET Core Runtime. Esta imagen está disponible en dos versiones:
mcr.microsoft.com/dotnet/core/aspnet:2.2
mcr.microsoft.com/dotnet/core/aspnet:2.1
Ahora, imagine que quiere usar las imágenes de Docker de ejemplo de .NET Core. Aquí tenemos cuatro versiones disponibles entre las que elegir:
mcr.microsoft.com/dotnet/samples:dotnetapp
mcr.microsoft.com/dotnet/samples:aspnetapp
Nota:
Una sola imagen puede tener varias etiquetas asignadas. Por convención, a la versión más reciente de una imagen se le asigna la etiqueta latest, además de otra que describe su número de versión. Cuando publique una nueva versión de una imagen, puede volver a asignar la etiqueta latest para hacer referencia a la nueva imagen.
Un repositorio también es la unidad de privacidad de una imagen. Si no quiere compartir una imagen, puede convertir en privado el repositorio. Puede conceder acceso a otros usuarios con los que quiera compartir la imagen.
Búsquedas en Docker Hub y extracción de una imagen
Nota:
No es necesario completar ninguno de los ejemplos ni ejecutar ninguno de los códigos de las secciones siguientes. Lo hará en la unidad siguiente.
A menudo encontrará que en Docker Hub hay una imagen que coincide con el tipo de aplicación que quiere incluir en contenedores. Puede descargar esa imagen y ampliarla con código de la aplicación.
Docker Hub contiene varios miles de imágenes. Puede buscar y examinar un registro mediante Docker desde la línea de comandos o desde el sitio web de Docker Hub. El sitio web permite buscar, filtrar y seleccionar imágenes por tipo y por publicador. En la imagen siguiente se muestra un ejemplo de la página de búsqueda.
Para recuperar una imagen, se usa el comando docker pull
con el nombre de la imagen. Docker descargará de forma predeterminada la imagen etiquetada con latest
desde ese repositorio en Docker Hub si solo se especifica el nombre del repositorio. Cabe decir que el comando se puede modificar para obtener diferentes etiquetas y desde distintos repositorios. En este ejemplo se captura la imagen con la etiqueta aspnetapp
del repositorio mcr.microsoft.com/dotnet/core/samples:aspnetapp. Esta imagen contiene una aplicación web de ASP.NET Core sencilla.
Nota:
Los ejemplos de esta unidad están diseñados para mostrar la sintaxis de los distintos comandos de Docker. No es necesario que los ejecute mientras lee esta unidad. En los ejercicios que siguen a esta unidad se le guiará por la forma de trabajar directamente con Docker.
docker pull mcr.microsoft.com/dotnet/samples:aspnetapp
Al capturar una imagen, Docker la almacena de forma local y la pone a disposición de los contenedores en ejecución. Puede ver las imágenes en el registro local con el comando docker image list.
docker image list
La salida se parece al ejemplo siguiente:
REPOSITORY TAG IMAGE ID CREATED SIZE
mcr.microsoft.com/dotnet/samples aspnetapp 6e2737d83726 6 days ago 263MB
Puede usar el identificador de nombre de imagen para hacer referencia a la imagen en otros muchos comandos de Docker.
Ejecución de un contenedor de Docker
Use el comando docker run
para iniciar un contenedor. Especifique la imagen que se va a ejecutar con su nombre o identificador. Si todavía no ha aplicado docker pull
a la imagen, Docker lo hará de forma automática.
docker run mcr.microsoft.com/dotnet/samples:aspnetapp
En este ejemplo, el comando responde con el mensaje siguiente:
warn: Microsoft.AspNetCore.DataProtection.KeyManagement.XmlKeyManager[35]
No XML encryptor configured. Key {d8e1e1ea-126a-4383-add9-d9ab0b56520d} may be persisted to storage in unencrypted form.
Hosting environment: Production
Content root path: /app
Now listening on: http://[::]:80
Application started. Press Ctrl+C to shut down.
Esta imagen contiene una aplicación web, por lo que ahora escucha las solicitudes que llegan en el puerto HTTP 80. Pero si abre un explorador web y va a http://localhost:80
, no verá la aplicación.
Docker no permite de forma predeterminada que las solicitudes de red entrantes lleguen al contenedor. Hay que indicar a Docker que asigne un número de puerto específico del equipo a un número de puerto específico del contenedor, agregando para ello la opción -p
a docker run
. Esta instrucción permite las solicitudes de red al contenedor en el puerto especificado.
Además, la aplicación web de esta imagen no está pensada para usarse de forma interactiva desde la línea de comandos. Cuando se inicia, la intención es que Docker la inicie en segundo plano y simplemente permita que se ejecute. Use la marca -d
para indicar a Docker que inicie la aplicación web en segundo plano.
Presione Ctrl+C para detener la imagen y, después, reiniciarla como se muestra en el siguiente ejemplo:
docker run -p 8080:80 -d mcr.microsoft.com/dotnet/samples:aspnetapp
El comando asigna el puerto 80 del contenedor al puerto 8080 del equipo. Si visita la página http://localhost:8080
en un explorador, verá la aplicación web de ejemplo.
Contenedores y archivos
Si un contenedor en ejecución realiza cambios en los archivos de su imagen, esos cambios solo existen en el contenedor donde se hayan realizado. A menos que realice pasos específicos para conservar el estado de un contenedor, estos cambios se pierden cuando se quite el contenedor. De forma similar, varios contenedores basados en la misma imagen que se ejecutan de forma simultánea no comparten los archivos de la imagen. Cada contenedor tiene su propia copia independiente. Los datos escritos por un contenedor en su sistema de archivos no son visibles para el otro.
Es posible agregar volúmenes grabables a un contenedor. Un volumen representa un sistema de archivos que puede montar el contenedor y está disponible para la aplicación que se ejecuta en el contenedor. Los datos de un volumen se conservan cuando se detiene el contenedor, y varios contenedores pueden compartir el mismo volumen. Los detalles para crear y usar volúmenes están fuera del ámbito de este módulo.
Se recomienda soslayar la necesidad de realizar cambios en el sistema de archivos de imagen de las aplicaciones implementadas con Docker. Úselo solo con archivos temporales que pueda permitirse perder.
Administración de contenedores de Docker
Puede ver los contenedores activos con el comando docker ps
.
docker ps
La salida incluye el estado del contenedor (Up si se está ejecutando, Exited si ha finalizado) entre otros valores, como las marcas de línea de comandos especificadas al iniciar la imagen y otra información. Docker permite ejecutar varios contenedores de forma simultánea a partir la misma imagen, por lo que a cada contenedor se le asigna un identificador único y un nombre legible único. La mayoría de los comandos de Docker que se usan para administrar contenedores individuales pueden utilizar el identificador o el nombre para hacer referencia a un contenedor específico.
En la siguiente salida, puede ver dos contenedores. El campo PORTS muestra que el contenedor con el identificador elegant_ramanujan
es la imagen que se ejecuta con el puerto 80 en el host de Docker asignado al puerto 8080 del equipo. La instancia de youthful_heisenberg
es el contenedor de la ejecución anterior de la imagen. El campo COMMAND muestra el comando que el contenedor ha ejecutado para iniciar la aplicación en la imagen. En este caso, es dotnet aspnetapp.dll en ambos contenedores. El identificador de imagen para los contenedores también es el mismo, ya que los contenedores ejecutan la misma imagen.
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
57b9587583e3 mcr.microsoft.com/dotnet/core/samples:aspnetapp "dotnet aspnetapp.dll" 42 seconds ago Up 41 seconds 0.0.0.0:8080->80/tcp elegant_ramanujan
d27071f3ca27 mcr.microsoft.com/dotnet/core/samples:aspnetapp "dotnet aspnetapp.dll" 5 minutes ago Up 5 minutes 0.0.0.0:8081->80/tcp youthful_heisenberg
Nota:
docker ps
es un acceso directo para docker container ls
. Los nombres de estos comandos se basan en las utilidades de Linux ps
y ls
, que enumeran los procesos en ejecución y los archivos, respectivamente.
Puede detener un contenedor activo con el comando docker stop
y especificar el identificador del contenedor.
docker stop elegant_ramanujan
Si ejecuta docker ps
de nuevo, verá que el contenedor elegant_ramanujan ya no aparece en la salida. El contenedor todavía existe, pero ya no hospeda un proceso en ejecución. Puede incluir los contenedores detenidos en la salida de docker ps
si incluye la marca -a
:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
57b9587583e3 mcr.microsoft.com/dotnet/core/samples:aspnetapp "dotnet aspnetapp.dll" 2 minutes ago Exited (0) 21 seconds ago elegant_ramanujan
d27071f3ca27 mcr.microsoft.com/dotnet/core/samples:aspnetapp "dotnet aspnetapp.dll" 7 minutes ago Up 7 minutes 0.0.0.0:8081->80/tcp youthful_heisenberg
Puede reiniciar un contenedor detenido con el comando docker start
. El proceso principal del contenedor se inicia de nuevo.
docker start elegant_ramanujan
Normalmente, cuando se detiene un contenedor, también se debe quitar. Al quitar un contenedor se limpian los recursos que deja. Una vez que quite un contenedor, los cambios realizados dentro del sistema de archivos de su imagen se perderán definitivamente.
docker rm elegant_ramanujan
No se puede quitar un contenedor en ejecución, pero se puede forzar la detención y eliminación de un contenedor con la marca -f en el comando docker rm
. Es una forma rápida de detener y quitar un contenedor, pero solo se debe usar si la aplicación incluida en el contenedor no tiene que realizar un cierre estable.
docker container rm -f elegant_ramanujan
Eliminación de imágenes de Docker
Puede eliminar una imagen del equipo local con el comando docker image rm
. Especifique el identificador de imagen de la imagen que se va a eliminar. En el ejemplo siguiente se quita la imagen de la aplicación web de ejemplo.
docker image rm mcr.microsoft.com/dotnet/core/samples:aspnetapp
Los contenedores que ejecuten la imagen tendrán que terminarse antes de que se pueda quitar la imagen. Si el contenedor sigue usando la imagen, obtendrá un mensaje de error como el que se muestra a continuación. En este ejemplo, el error se produce porque el contenedor youthful_heisenberg sigue usando la imagen.
Error response from daemon: conflict: unable to delete 575d85b4a69b (cannot be forced) - image is being used by running container c13165988cfe