Pequeñas imágenes de Docker que creían en sí mismas *

[referencia al cuento de hadas infantil estadounidense "El pequeño motor que podría" - aprox. por.] *



Cómo crear automáticamente pequeñas imágenes acoplables para sus necesidades


Obsesión inusual


Durante los últimos meses he estado obsesionado con una obsesión: ¿cuánto puedo reducir la imagen de Docker para que la aplicación funcione?


Entiendo que la idea es extraña.


Antes de profundizar en los detalles y la naturaleza técnica, me gustaría explicar por qué este problema me ha enganchado tanto y cómo le concierne.


Por qué importa el tamaño


Al acortar el contenido de la imagen de Docker, estamos acortando la lista de vulnerabilidades. Además, hacemos imágenes más limpias, ya que contienen solo lo que necesita para ejecutar aplicaciones.


Hay otra pequeña ventaja: las imágenes se descargan un poco más rápido, pero, para mí, esto no es tan importante.


Tenga en cuenta: si le importa el tamaño, el aspecto alpino es pequeño en sí mismo y probablemente sea adecuado para usted.

Imágenes sin distro


El proyecto Distroless ofrece una selección de imágenes básicas "distroless", que no contienen los administradores de paquetes, shells u otras utilidades que está acostumbrado a ver en la línea de comandos. Como resultado, el uso de administradores de paquetes como pip y apt fallará:


 FROM gcr.io/distroless/python3 RUN pip3 install numpy 

Dockerfile usando una imagen sin distorsiones de Python 3


 Sending build context to Docker daemon 2.048kB Step 1/2 : FROM gcr.io/distroless/python3 ---> 556d570d5c53 Step 2/2 : RUN pip3 install numpy ---> Running in dbfe5623f125 /bin/sh: 1: pip3: not found 

No hay pip en la imagen.


Por lo general, este problema se resuelve mediante una compilación de varias etapas:


 FROM python:3 as builder RUN pip3 install numpy FROM gcr.io/distroless/python3 COPY --from=builder /usr/local/lib/python3.7/site-packages /usr/local/lib/python3.5/ 

Ensamblaje de etapas múltiples


El resultado es una imagen de tamaño 130 MB. ¡No tan mal! A modo de comparación: la imagen de Python por defecto pesa 929 MB, y la imagen "más delgada" ( 3,7-slim ) - 179MB, la imagen alpina ( 3,7-alpine ) - 98.6MB, mientras que la imagen básica sin distro utilizada en el ejemplo es 50.9MB.


Podemos señalar con razón que en el ejemplo anterior estamos copiando todo el directorio /usr/local/lib/python3.7/site-packages , que puede contener dependencias innecesarias para nosotros. Aunque está claro que la diferencia de tamaño de todas las imágenes base de Python existentes varía.


Al momento de escribir estas líneas, Google Distroless no admite muchas imágenes: Java y Python todavía están en la etapa experimental, y Python existe solo para 2.7 y 3.5.

Imágenes minúsculas


Volvamos a mi obsesión por crear imágenes pequeñas.


En realidad, quería ver cómo funcionan las imágenes sin distro. El proyecto distroless utiliza la bazel compilación Google Bazel. Sin embargo, para instalar Bazel y escribir sus propias imágenes, tuve que sudar (y para ser completamente honesto, reinventar la rueda es divertido e informativo). Quería simplificar la creación de imágenes reducidas: el acto de crear una imagen debería ser extremadamente simple, banal . Para que no tenga ningún archivo de configuración, solo una línea en la consola: <> .


Entonces, si desea crear sus propias imágenes, entonces sepa: hay una imagen acoplable tan única, desde scratch . Scratch es una imagen "vacía", no tiene archivos, aunque pesa por defecto, ¡guau! - 77 bytes.


 FROM scratch 

Imagen de rascar


La idea de una imagen reutilizable es que puede copiar cualquier dependencia del equipo host en ella y usarla dentro del Dockerfile (así es como copiarla en apt e instalarla desde cero), o más tarde, cuando se materializa la imagen Docker. Esto le permite controlar completamente el contenido del contenedor Docker y, por lo tanto, controlar completamente el tamaño de la imagen.


Y ahora necesitamos recopilar de alguna manera estas dependencias. Las herramientas existentes como apt permiten descargar paquetes, pero están vinculados a la máquina actual y, al final, no son compatibles con Windows o MacOS.


Y entonces me comprometí a ensamblar mi propia herramienta, la cual ensamblaría automáticamente la imagen básica del tamaño más pequeño posible y aún así lanzaría cualquier aplicación. Usé paquetes Ubuntu / Debian, hice una selección (obteniendo paquetes directamente de los repositorios) y recursivamente encontré sus dependencias. El programa debe descargar automáticamente la última versión estable del paquete, minimizando los riesgos de seguridad.


Llamé a la fetchy , porque ... encuentra y trae ... lo que necesita [ del inglés. "buscar", "traer" - aprox. trans. ] La herramienta funciona a través de la interfaz de línea de comandos, pero al mismo tiempo ofrece una API.


Para construir una imagen usando fetchy (tomemos una imagen de Python esta vez), solo necesita usar la CLI de esta manera: fetchy dockerize python . Es posible que se le fetchy sistema operativo de destino y el nombre del código, ya que fetchy solo usa paquetes basados ​​en Debian y Ubuntu hasta ahora.


Ahora puede elegir qué dependencias no son necesarias (en nuestro contexto) y excluirlas. Por ejemplo, Python depende de perl, aunque funciona muy bien sin Perl instalado.


Resultados


La imagen de Python creada con el fetchy dockerize python3.5 pesa solo 35 MB (estoy más que seguro de que se puede hacer aún más fácil en el futuro). Resulta que con una imagen sin distorsiones logramos "afeitar" otros 15 MB.


Todas las imágenes recopiladas actualmente se pueden ver aquí .


El proyecto ya está aquí .


Si no tiene suficientes funciones, simplemente cree una aplicación. Estaré encantado de ayudar :) Aún más, actualmente estoy trabajando en la integración de otros gestores de paquetes en fetchy, de modo que ya no sea necesaria la creación de compilaciones en varias etapas.

Source: https://habr.com/ru/post/469947/


All Articles