Las imágenes de Docker se crean a partir de un Dockerfile que define una imagen base y una serie de instrucciones que agregan sus propias capas del sistema de archivos. Sin embargo, ¿qué sucede si desea que el suyo tenga una «Imagen base»? Aquí se explica cómo empezar desde cero y crear un sistema de archivos contenedor completo desde cero.
¿Qué es una imagen?
Contenidos
Las imágenes de Docker a menudo usan una distribución Linux popular como imagen base. Si escribió FROM ubuntu:latest, FROM debian:latest o FROM alpine:latest, usó un sistema operativo como base. También puede usar una imagen preconfigurada para un marco o lenguaje de programación en particular, como FROM php:8.0 o FROM node:16.
Todas estas imágenes proporcionan un punto de partida útil para sus aplicaciones. Vienen con utilidades comunes de Unix y paquetes de software importantes. Sin embargo, todo esto aumenta el tamaño de la imagen final. Se debe construir una imagen verdaderamente mínima construyendo su propio sistema de archivos desde los primeros principios.
La imagen “cero”
Docker proporciona una imagen base especial que indica que desea controlar la primera capa del sistema de archivos. Esta es la capa inferior de su imagen, generalmente definida por la imagen base indicada por su instrucción FROM.
Cuando desee crear una imagen «desde cero», ¡escribir DESDE cero en su Dockerfile es la forma de hacerlo! Esto le da un sistema de archivos que es una pizarra en blanco para empezar.
DESDE cero
A continuación, debe usar el resto del Dockerfile de forma normal para completar el sistema de archivos del contenedor con los archivos binarios y las bibliotecas que necesita.
¿Qué es «cero»?
la «Imagen» cero se parece a una imagen normal de Docker. Es cierto listado en Docker Hub. scratch no es realmente una imagen, es una palabra clave reservada que denota la capa más baja del sistema de archivos de una imagen de trabajo. Todas las imágenes de Docker están en cero como base común.
No puede hacer docker pull scratch y no puede ejecutar contenedores usándolo. Representa una capa de imagen vacía, por lo que Docker no tiene nada que ejecutar. Las imágenes tampoco se pueden marcar como scratch debido a su naturaleza reservada.
¿Qué se puede agregar a las imágenes basadas en scratch?
No necesita mucho para construir una imagen de trabajo desde cero. Todo lo que necesita agregar es un binario de Linux compilado estáticamente que puede usar como su comando de imagen.
Aquí hay una demostración funcional que ejecuta un pequeño programa «hola mundo» compilado desde C:
#include
Compile su código C a un binario:
gcc -o holamundo hola.c
Ejecute su binario y observe que «hola mundo» está impreso en su terminal:
./Hola Mundo
Ahora puede crear un contenedor Docker basado en scratch que ejecute su binario:
DESDE cero COPIAR helloworld / CMD [«helloworld»]
Construye tu imagen:
docker build -t hola:último .
Inspeccionar la imagen con docker inspect mostrará que tiene una sola capa. El sistema de archivos de esta imagen contiene solo un archivo, el binario helloworld.
Ahora ejecuta un contenedor usando tu imagen:
ventana acoplable ejecutar hola: último
Verá «hola mundo» en su terminal mientras se ejecuta su binario compilado. Su imagen basada en cero solo contiene su binario, por lo que solo tendrá unos pocos KB de tamaño. El uso de cualquier imagen base del sistema operativo aumentaría esto a varios megabytes, incluso con una distribución mínima como Alpine.
Prácticamente todas las imágenes tendrán algunas dependencias además de un binario estático simple. Deberá agregarlos a su imagen como parte del Dockerfile. Tenga en cuenta que ninguna de las herramientas que cree que son correctas en las distribuciones estándar de Linux estará disponible hasta que las agregue manualmente al sistema de archivos de la imagen.
¿Cuándo usar Scratch?
La decisión de comenzar desde cero debe basarse en las dependencias de su aplicación y sus objetivos de portabilidad de imágenes. Las imágenes creadas desde cero son las más adecuadas para alojar archivos binarios compilados estáticamente donde el tamaño de la imagen y los tiempos de creación son importantes.
scratch proporciona una pizarra limpia para trabajar, por lo que requiere una inversión inicial para escribir correctamente su Dockerfile y mantenerlo a lo largo del tiempo. Algunos comandos de Docker, como adjuntar, no funcionarán de forma predeterminada, ya que no habrá ningún shell dentro de su contenedor a menos que agregue uno.
Usar scratch puede ser más problemático de lo que vale cuando usa lenguajes interpretados con fuertes dependencias ambientales. Deberá actualizar continuamente su imagen base para hacer referencia a las últimas versiones de estos paquetes. Por lo general, es más conveniente y fácil de mantener usar una versión mínima de una imagen base de Docker Hub existente.
Resumen
DESDE cero en un Dockerfile indica que desea comenzar desde un sistema de archivos vacío donde tiene el control de cada capa agregada. Facilita imágenes altamente simplificadas, despojadas de todo menos de las dependencias que necesita su aplicación.
Es probable que la mayoría de los desarrolladores no usen Scratch directamente, ya que no es adecuado para la mayoría de los casos de uso de contenedores. Puede optar por usarlo si desea contener archivos binarios estáticos autónomos con pocos requisitos ambientales.
scratch también funciona como un claro indicador de la diferencia entre «contenedores» y máquinas virtuales. Una imagen que contiene solo un archivo ejecutable es un contenedor de Docker utilizable, ya que el proceso se ejecuta en el kernel de su host. Una máquina virtual normal debe arrancar independientemente de su host, por lo que debe incluir un kernel de sistema operativo completo en su imagen.