Unlimited Plugins, WordPress themes, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Code
  2. Docker

Docker Desde El Principio: Construyendo Imágenes

by
Difficulty:IntermediateLength:MediumLanguages:
This post is part of a series called Docker from the Ground Up.
Docker From the Ground Up: Understanding Images

Spanish (Español) translation by Ruben Solis (you can also view the original English article)

Los contenedores Docker están creciendo como una buena práctica para la implementación y administración de sistemas distribuidos nativos de la nube. Los contenedores son instancias de imágenes Docker. Resulta que hay mucho que saber y comprender acerca de las imágenes.

En este tutorial de dos partes, abordaré las imágenes de Docker en profundidad. En la primera parte traté los principios básicos, consideraciones de diseño y la inspección de las interioridades de una imagen. En esta parte, cubro la construcción de tus propias imágenes, la solución de problemas y el trabajo con los repositorios de imágenes.

Cuando finalices el tutorial, tendrás una sólida comprensión de lo que son exactamente las imágenes de Docker y cómo utilizarlas eficazmente en tus propias aplicaciones y sistemas.

Construyendo Imágenes

Hay dos formas de crear imágenes. Puedes modificar un contenedor existente y luego confirmarlo ('commit') como una nueva imagen, o puedes escribir un Dockerfile y construirlo como imagen. Trataremos ambos casos y explicaremos los pros y los contras.

Construcciones Manuales

Con las construcciones manuales, tratas tu contenedor como un ordenador normal. Instalas paquetes, escribes archivos y, cuando todo esta completado, lo confirmas ('commit') y acabas obteniendo una nueva imagen que usas como plantilla para crear muchos más contenedores idénticos o incluso como base para otras imágenes.

Comencemos con la imagen alpine, que es una imagen muy pequeña y espartana basada en Alpine Linux. Podemos ejecutarla en modo interactivo para entrar en un shell. Nuestro objetivo es agregar un archivo llamado "yeah" (sí) que contenga el texto "it works!" (¡funciona!) en el directorio raíz y luego crear una nueva imagen llamada "yeah-alpine".

Aquí vamos. Bien, ya estamos en el directorio raíz. Veamos qué hay ahí.

¿Qué editor está disponible? ¿Sin vim, sin nano?

Oh bien. Solo queremos crear un archivo:

Salí del shell interactivo y puedo ver el contenedor llamado "vibrant_spence" con docker ps --all. La marca --all es importante porque el contenedor ya no se está ejecutando.

Aquí, creo una nueva imagen del contenedor "vibrant_spence". Agregué el mensaje de commit "mine, mine, mine" por si acaso.

Vamos a ver. Sí, hay una nueva imagen, y en su historial se puede ver una nueva capa con el comentario "mine, mine, mine".

Ahora para la prueba real. Eliminemos el contenedor y creemos un nuevo contenedor a partir de la imagen. El resultado esperado es que el archivo "yeah" estará presente en el nuevo contenedor.

¿Qué puedo decir? ¡Sí, funciona!

Usando un Dockerfile

Crear imágenes a partir de contenedores modificados es genial, pero no hay una rendición de cuentas. Es difícil hacer un seguimiento de los cambios y saber cuáles fueron las modificaciones específicas. La manera ordenada de crear imágenes es hacerlo usando un Dockerfile.

El Dockerfile es un archivo de texto similar a un script de shell, pero admite varios comandos. Cada comando que modifica el sistema de archivos crea una nueva capa. En la primera parte discutimos la importancia de dividir correctamente tu imagen en capas. El Dockerfile es un gran tema en sí mismo.

Aquí, solo demostraré un par de comandos para crear otra imagen, "oh-yeah-alpine", basada en un Dockerfile. Además de crear el infame archivo "yeah", también instalaremos vim. La distribución de Alpine Linux utiliza un sistema de gestión de paquetes llamado "apk". Aquí está el Dockerfile:

La imagen base es alpine. Se copia el archivo "yeah" del mismo directorio de host donde está el Dockerfile (la ruta del build context). Luego, se ejecuta apk update y se instala vim. Finalmente, se establece el comando que se ejecuta cuando se ejecuta el contenedor. En este caso, imprimirá en la pantalla el contenido del archivo "yeah".

Ok. Ahora que sabemos en lo que nos estamos metiendo, construyamos nuestra imagen. La opción "-t" establece el repositorio. No especifiqué una etiqueta, por lo que será la predeterminada "latest".

Se ve bien. Verifiquemos que se creó la imagen:

¡Ten en cuenta cómo la instalación de vim y sus dependencias aumentó el tamaño del contenedor de los 4,8 MB de la imagen base alpine a los enormes 30,5 MB!

Todo está muy bien. ¿Pero funciona?

¡Oh, sí, funciona!

En caso de que todavía tengas sospechas, vayamos al contenedor y examinemos el archivo "yeah" con nuestro vim recién instalado.

El Build Context y el archivo .dockerignore

No te lo dije, pero originalmente, cuando traté de construir la imagen oh-yeah-alpine, se quedó colgada durante varios minutos. El problema fue que simplemente puse el Dockerfile en mi directorio de inicio. Cuando Docker crea una imagen, primero empaqueta todo el directorio donde está el Dockerfile (incluidos los subdirectorios) y lo pone a disposición para los comandos COPY en el Dockerfile.

Docker no está tratando de ser inteligente y analizar tus comandos COPY. Simplemente empaqueta todo. Ten en cuenta que el contenido del build no terminará en tu imagen, pero ralentizará tu comando de build si tu build context es innecesariamente grande.

En este caso, simplemente copié el Dockerfile y el "yeah" en un subdirectorio y ejecuté el comando docker build en ese subdirectorio. Pero a veces tienes un árbol de directorios complicado del que desea copiar archivos y subdirectorios específicos e ignorar otros. Ingresa al archivo .dockerignore.

Este archivo le permite controlar exactamente lo que entra en el build context. Mi truco favorito es primero excluir todo y luego comenzar a incluir las partes que necesito. Por ejemplo, en este caso podría crear el siguiente archivo .dockerignore y mantener el archivo Docker y el "yeah" en mi directorio de inicio:

No es necesario incluir el "Dockerfile" en sí mismo o el archivo ".dockerignore" en el build context

Copia frente a montaje

A veces, lo que necesitas es copiar archivos en la imagen, pero en otros casos es posible que desees que tus contenedores sean más dinámicos y funcionen con archivos en el host. Aquí es donde entran en juego los volúmenes y los montajes.

Montar directorios de host es un juego diferente. Los datos son propiedad del host y no del contenedor. Los datos se pueden modificar cuando se detiene el contenedor. El mismo contenedor se puede iniciar con diferentes directorios de host montados.

Etiquetado de imágenes

Etiquetar imágenes es muy importante si desarrollas un sistema basado en microservicios y generas muchas imágenes que a veces deben asociarse entre sí. Puedes agregar tantas etiquetas como desees a una imagen.

Ya has visto la etiqueta predeterminada "latest". A veces, tiene sentido agregar otras etiquetas, como "tested", "release-1.4" o el git commit que corresponde a la imagen.

Puedes etiquetar una imagen durante un build o más tarde. A continuación, se explica cómo agregar una etiqueta a una imagen existente. Ten en cuenta que mientras una etiqueta es llamada, también puedes asignar un nuevo repositorio.

También puedes quitar la etiqueta eliminando una imagen por su nombre de etiqueta. Esto da un poco de miedo porque si quitas la última etiqueta por accidente, pierdes la imagen. Pero si creas imágenes a partir de un Dockerfile, puedes simplemente reconstruir la imagen.

Si trato de eliminar la última imagen etiquetada restante, aparece un error porque es utilizada por un contenedor.

Pero si quito el contenedor ...

Sí. Se fue. Pero no te preocupes. Podemos reconstruirlo:

Sí, está de vuelta. ¡Dockerfile para la victoria!

Trabajar con registros de imágenes

Las imágenes son muy similares en algunos aspectos a los repositorios de git. También se crean a partir de un conjunto ordenado de commits. Puedes pensar en dos imágenes que usen las mismas imágenes base como ramas (aunque no hay merge ni rebase en Docker). Un registro de imágenes es el equivalente a un servicio de alojamiento central de git como GitHub. ¿Adivina cuál es el nombre del registro de imágenes oficial de Docker? Así es, Docker Hub.

Haciendo pull de imágenes

Cuando ejecutas una imagen, si no existe, Docker intentará extraerla de uno de sus registros de imágenes configurados. De forma predeterminada, va a Docker Hub, pero puedes controlarlo en tu archivo "~/.docker/config.json". Si usas un registro diferente, puedes seguir sus instrucciones, que generalmente implican iniciar sesión con sus credenciales.

Eliminemos la imagen "hello-world" y hagamos pull de ella nuevamente usando el comando docker pull.

Se ha ido. Hagamos pull ahora.

El último hello-world fue reemplazado por una versión más nueva.

Haciendo push de imágenes

Hacer push de imágenes es un poco más complicado. Primero debes crear una cuenta en Docker Hub (u otro registro). A continuación, inicia sesión. Luego, debes etiquetar la imagen que deseas enviar de acuerdo con el nombre de tu cuenta ("g1g1" en mi caso).

Ahora, puedo enviar la imagen etiquetada g1g1/hello-world.

Conclusión

Las imágenes de Docker son las plantillas de sus contenedores. Están diseñadas para ser eficientes y ofrecer la máxima reutilización mediante el uso de un controlador de almacenamiento del sistema de archivos en capas.

Docker proporciona muchas herramientas para enumerar, inspeccionar, crear y etiquetar imágenes. Puedes extraer y enviar imágenes a registros de imágenes como Docker Hub para administrar y compartir fácilmente tus imágenes.

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.