Los contenedores Docker están en aumento como una mejor práctica para implementar y administrar sistemas distribuidos nativos en la nube. Los contenedores son instancias de imágenes Docker. Resulta que hay mucho que saber y entender acerca de las imágenes..
En este tutorial de dos partes, estoy cubriendo las imágenes de Docker en profundidad. En la primera parte, discutí los principios básicos, las consideraciones de diseño y la inspección de las imágenes internas. En esta parte, me ocupo de crear sus propias imágenes, solucionar problemas y trabajar con repositorios de imágenes..
Cuando salga al otro lado, tendrá una sólida comprensión de qué son exactamente las imágenes de Docker y cómo utilizarlas de manera efectiva en sus propias aplicaciones y sistemas..
Hay dos formas de construir imágenes. Puede modificar un contenedor existente y luego confirmarlo como una nueva imagen, o puede escribir un Dockerfile y compilarlo en una imagen. Repasaremos ambos y explicaremos los pros y los contras..
Con las compilaciones manuales, usted trata su contenedor como una computadora normal. Instala paquetes, escribe archivos y, cuando todo está dicho y hecho, lo confirma y termina con una nueva imagen que utiliza como plantilla para crear muchos más contenedores idénticos o incluso basar otras imágenes en.
Comencemos con la imagen alpina, que es una imagen muy pequeña y espartana basada en Alpine Linux. Podemos ejecutarlo en modo interactivo para entrar en un shell. Nuestro objetivo es agregar un archivo llamado "sí" que contenga el texto "¡funciona!" al directorio raíz y luego crea una nueva imagen desde ella llamada "sí-alpino".
Aquí vamos. Bien, ya estamos en el directorio raíz. A ver que hay.
> docker run -it alpine / bin / sh / # ls bin dev etc inicio lib linuxrc media mnt proc root run sbin srv sys tmp usr var
¿Qué editor está disponible? No vim, no nano?
/ # vim / bin / sh: vim: no encontrado / # nano / bin / sh: nano: no encontrado
Oh bien. Solo queremos crear un archivo:
/ # eco "funciona!" > si / # cat si funciona!
Salí del shell interactivo y puedo ver el contenedor llamado "vibrant_spenc" con docker ps --todos
. los --todos
La bandera es importante porque el contenedor ya no se está ejecutando..
> docker ps - todos los ID DE CONTENEDORES COMANDO DE IMAGEN NOMBRES DE ESTADO CREADOS c8faeb05de5f alpine "/ bin / sh" hace 6 minutos Salió de vibrant_spence
Aquí, creo una nueva imagen del contenedor "vibrate_spence". Agregué el mensaje de confirmación "mío, mío, mío" por si acaso.
> docker commit -m "mío, mío, mío" vibrant_spence sí-alpino sha256: e3c98cd21f4d85a1428 ... e220da99995fd8bf6b49aa
Vamos a ver. Sí, hay una nueva imagen, y en su historia puedes ver una nueva capa con el comentario "mío, mío, mío".
> docker imagenes REPOSITORIO TAG ID DE IMAGEN TAMAÑO yeah-alpine ultimo e3c98cd21f4d 4.8 MB python ultimo 775dae9b960e 687 MB d4w / nsenter ult. 4e38e38c8ce0 4.8 MB nsqio / nsq último 2a82c70fe5e3 70.7 MB> historial de docker sí-alpino IMAGEN COMENTADO TAMAÑO COMENTARIO e3c98cd21f4d hace 40 segundos 66 B mina, mina, mina 4e38e38c8ce0 Hace 7 meses 4.8 MB
Ahora para la prueba real. Vamos a eliminar el contenedor y crear un nuevo contenedor a partir de la imagen. El resultado esperado es que el archivo "sí" estará presente en el nuevo contenedor.
> docker rm vibrant_spence vibrante_spence> docker run -it yeah-alpine / bin / sh / # cat sí funciona! / #
¿Qué puedo decir? Si funciona!
Crear imágenes a partir de contenedores modificados es genial, pero no hay responsabilidad. Es difícil hacer un seguimiento de los cambios y saber cuáles fueron las modificaciones específicas. La forma disciplinada de crear imágenes es construirlas usando un Dockerfile.
Dockerfile es un archivo de texto que es 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 su imagen en capas correctamente. El Dockerfile es un gran tema en sí mismo.
Aquí, solo mostraré un par de comandos para crear otra imagen, "oh-yeah-alpine", basada en un Dockerfile. Además de crear el infame archivo "sí", instalemos también vim. La distribución alpina de Linux utiliza un sistema de gestión de paquetes llamado "apk". Aquí está el Dockerfile:
DESDE alpine # Copie el archivo "yeah" del host. COPY yeah / yeah # Actualice e instale vim usando apk RUN apk update && apk agregue vim CMD cat / yes
La imagen base es alpina. Copia el archivo "sí" del mismo directorio de host donde se encuentra el archivo Docker (la ruta de acceso de contexto de compilación). Entonces, corre actualización de apk
e instala vim. Finalmente, establece el comando que se ejecuta cuando se ejecuta el contenedor. En este caso, se imprimirá en la pantalla el contenido del archivo "sí"..
DE ACUERDO. Ahora que sabemos en lo que nos estamos metiendo, construyamos esto. La opción "-t" establece el repositorio. No especifiqué una etiqueta, por lo que será la "última" predeterminada.
> Docker build -t oh-yes-alpine. Envío del contexto de compilación al demonio Docker 3.072 kB Paso 1/4: DESDE alpino ---> 4e38e38c8ce0 Paso 2/4: COPIA sí / sí ---> 1b2a228cc2a5 Eliminación del contenedor intermedio a6221f725845 Paso 3/4: RUN apk apk & apk apk vim ---> Se ejecuta en e2c0524bd792 fetch http://dl-cdn.alpinelinux.org/… /APKINDEX.tar.gz fetch http: //dl-cdn.alpinelinux.org… /x86_64/APKINDEX.tar.gz v3. 4.6-60-gc61f5bf [http://dl-cdn.alpinelinux.org/alpine/v3.4/main] v3.4.6-33-g38ef2d2 [http://dl-cdn.alpinelinux.org/… / v3. 4 / comunidad] OK: 5977 paquetes distintos disponibles (1/5) Instalación de lua5.2-libs (5.2.4-r2) (2/5) Instalación de ncurses-terminfo-base (6.0-r7) (3/5) Instalación ncurses-terminfo (6.0-r7) (4/5) Instalación de ncurses-libs (6.0-r7) (5/5) Instalación de vim (7.4.1831-r2) Ejecución de busybox-1.24.2-r9.trigger OK: 37 MiB en 16 paquetes ---> 7fa4cba6d14f Eliminación del contenedor intermedio e2c0524bd792 Paso 4/4: CMD cat / yes ---> Ejecutando en 351b4f1c1eb1 ---> e124405f28f4 Eliminando el contenedor intermedio 351b4f1c1eb1 Successf ully construido e124405f28f4
Se ve bien. Vamos a verificar que la imagen fue creada:
> imágenes docker | grep oh-sí oh-yeah-alpine última e124405f28f4 Hace aproximadamente un minuto 30.5 MB
Observe cómo la instalación de vim y sus dependencias aumentaron el tamaño del contenedor, desde los 4.8MB de la imagen alpina base hasta los 30.5MB masivos.!
Todo es muy bonito. Pero funciona?
> docker run oh-yeah-alpine funciona!
Oh si, funciona!
En caso de que aún desconfíes, entremos en el contenedor y examinemos el archivo "sí" con nuestro vim recién instalado.
> docker run -it oh-yes-alpine / bin / sh / # vim ¡sí, funciona! ~ ~… ~ "Sí" 1L, 10C
No te lo dije, pero al principio cuando intenté crear la imagen oh-yeah-alpine, solo se colgó durante varios minutos. El problema fue que acabo de poner el Dockerfile en mi directorio de inicio. Cuando Docker crea una imagen, primero empaqueta todo el directorio donde se encuentra el Dockerfile (incluidos los subdirectorios) y lo pone a disposición para los comandos COPY en el Dockerfile..
Docker no intenta ser inteligente y analizar sus comandos de COPIA. Sólo empaca todo. Tenga en cuenta que el contenido de la compilación no terminará en su imagen, pero ralentizará su comando de compilación si el contexto de compilación es innecesariamente grande.
En este caso, simplemente copié el Dockerfile y el "sí" en un subdirectorio y ejecuté el comando de construcción de la ventana acoplable en ese subdirectorio. Pero a veces tiene un árbol de directorios complicado desde el cual desea copiar subdirectorios y archivos específicos e ignorar otros. Ingrese el archivo .dockerignore.
Este archivo le permite controlar exactamente lo que entra en el contexto de compilación. Mi truco favorito es primero excluir todo y luego comenzar a incluir las partes y piezas que necesito. Por ejemplo, en este caso, podría crear el siguiente archivo .dockerignore y guardar el archivo Docker y el "sí" en mi directorio principal:
# Excluye TODO lo primero * # ¡Ahora incluye cosas de forma selectiva! Sí
No es necesario incluir el "Dockerfile" en sí o el archivo ".dockerignore" en el contexto de compilación.
Lo que necesita a veces es copiar archivos en la imagen, pero en otros casos es posible que desee que sus contenedores sean más dinámicos y que funcionen con archivos en el host. Aquí es donde entran en juego los volúmenes y las monturas..
Montar directorios de host es un juego de pelota diferente. Los datos son propiedad del host y no del contenedor. Los datos pueden ser modificados cuando se detiene el contenedor. El mismo contenedor se puede iniciar con diferentes directorios de host montados.
Etiquetar imágenes es muy importante si desarrolla un sistema basado en microservicios y genera muchas imágenes que a veces deben asociarse entre sí. Puedes agregar tantas etiquetas como quieras a una imagen.
Ya has visto la etiqueta "última" predeterminada. A veces, tiene sentido agregar otras etiquetas, como "probado", "versión 1.4", o la confirmación de git que corresponde a la imagen.
Puedes etiquetar una imagen durante una compilación o más tarde. Aquí se explica cómo agregar una etiqueta a una imagen existente. Tenga en cuenta que mientras se llama una etiqueta, también puede asignar un nuevo repositorio.
> etiqueta docker oh-yeah-alpine oh-yes-alpine: cool-tag> etiqueta docker oh-yes-alpine oh-yes-alpine-2> imágenes de docker | grep oh-sí oh-yeah-alpine-2 último e124405f28f4 30.5 MB oh-yes-alpine cool-tag e124405f28f4 30.5 MB oh-yes-alpine último e124405f28f4 30.5 MB
También puede desmarcar eliminando una imagen por su nombre de etiqueta. Esto da un poco de miedo porque si elimina la última etiqueta por accidente, pierde la imagen. Pero si construyes imágenes desde un Dockerfile, puedes simplemente reconstruir la imagen.
> docker rmi oh-yeah-alpine-2 Sin etiqueta: oh-yes-alpine-2: más reciente> docker rmi oh-yeah-alpine: cool-tag Sin etiqueta: oh-yeah-alpine: cool-tag
Si intento eliminar la última imagen etiquetada que queda, aparece un error porque es usado por un contenedor.
> docker rmi oh-yeah-alpine Respuesta de error del daemon: conflicto: no se pudo eliminar la referencia del repositorio "oh-yeah-alpine" (debe forzar) - el contenedor a1443a7ca9d2 está usando su imagen de referencia e124405f28f4
Pero si saco el contenedor ...
> RMI ventana acoplable oh-sí-alpino Untagged: Oh-Sí-alpino: últimas Eliminado: sha256: e124405f28f48e ... 441d774d9413139e22386c4820df Eliminado: sha256: 7fa4cba6d14fdf ... d8940e6c50d30a157483de06fc59 Eliminado: sha256: 283d461dadfa6c ... dbff864c6557af23bc5aff9d66de Eliminado: sha256: 1b2a228cc2a5b4 ... 23c80a41a41da4ff92fcac95101e Eliminado: sha256: fe5fe2290c63a0 … 8af394bb4bf15841661f71c71e9a> imágenes de la ventana acoplable | grep oh-sí
Sí. Se fue. Pero no te preocupes. Podemos reconstruirlo:
> Docker build -t oh-yes-alpine. > imágenes docker | grep oh-sí oh-yeah-alpine último 1e831ce8afe1 hace 1 minuto 30.5 MB
Yay, ha vuelto. Dockerfile para la victoria!
Las imágenes son muy similares en algunos aspectos a los repositorios de git. También se construyen a partir de un conjunto ordenado de confirmaciones. Puedes pensar en dos imágenes que usan las mismas imágenes base como ramas (aunque no hay fusión ni rebasado en Docker). Un registro de imágenes es el equivalente a un servicio de alojamiento de git central como GitHub. Adivina cuál es el nombre del registro de imágenes oficial de Docker? Así es, Docker Hub.
Cuando ejecuta una imagen, si no existe, Docker intentará extraerla de uno de sus registros de imágenes configurados. Por defecto, va a Docker Hub, pero puede controlarlo en su archivo "~ / .docker / config.json". Si usa un registro diferente, puede seguir sus instrucciones, que normalmente implican iniciar sesión con sus credenciales.
Vamos a eliminar la imagen de "hola mundo" y jalarla nuevamente usando el tirador
mando.
> imágenes dockere | grep hello-world hello-world última c54a2cc56cbb hace 7 meses 1.85 kB> docker rmi hello-world hello-world
Se fue. Vamos a tirar ahora.
> docker pull hello-world Uso de la etiqueta predeterminada: último último: Pulling from library / hello-world 78445dd45222: Pull complete Digest: sha256: c5515758d4c5e5e1e… 07e6f927b07d05f6d12a1ac8d7 Estado: Descargado la imagen más nueva para hello-world: grep hello-world hello-world última 48b5124b2768 Hace 2 semanas 1.84 kB
El último hello-mundo fue reemplazado por una versión más nueva..
Empujar imágenes es un poco más complicado. Primero debe crear una cuenta en Docker Hub (u otro registro). A continuación, inicie sesión. Luego deberá etiquetar la imagen que desea insertar de acuerdo con el nombre de su cuenta ("g1g1" en mi caso).
> Inicio de sesión de docker -u g1g1 -pInicio de sesión exitoso> etiqueta docker hello-world g1g1 / hello-world> imágenes docker | grep hello g1g1 / hello-world última 48b5124b2768 hace 2 semanas 1.84 kB hello-world última 48b5124b2768 hace 2 semanas 1.84 kB
Ahora, puedo empujar la imagen etiquetada g1g1 / hello-world.
> docker push g1g1 / hello-world El push se refiere a un repositorio [docker.io/g1g1/hello-world] 98c944e98de8: Montado desde la biblioteca / hello-world más reciente: digest: sha256: c5515758d4c5e… f6d12a1ac8d7 tamaño: 524
Las imágenes de Docker son las plantillas para tus contenedores. Están diseñados para ser eficientes y ofrecen una reutilización máxima mediante el uso de un controlador de almacenamiento de sistema de archivo de capas.
Docker proporciona muchas herramientas para enumerar, inspeccionar, crear y etiquetar imágenes. Puede extraer y enviar imágenes a registros de imágenes como Docker Hub para administrar y compartir fácilmente sus imágenes.