Este artículo describe una de las últimas tendencias en el mundo de los contenedores: se llama contenedores sin distribución.
Los contenedores son el método preferido para implementar aplicaciones comerciales en todos los sectores comerciales, por lo que la optimización de cómo las empresas usan los contenedores tiene un impacto directo en sus infraestructuras de aplicaciones críticas.
Nuestra encuesta también muestra el dominio de los contenedores .
¿Por qué reducir el tamaño de los contenedores de imágenes acoplables? Las computadoras son más rápidas y tienen más recursos, así que tal vez no sea tan importante. La respuesta es simple: por rendimiento y seguridad. Si necesita más, aquí hay otra razón: dinero.
Actuación
Las imágenes de Docker son copiadas, transmitidas y lanzadas por los administradores de flotas de contenedores. Todo lleva tiempo, tiempo invertido en una E/S de disco y una E/S de red.
Y hay máquinas con especificaciones mínimas que son baratas en la nube, por lo que colocar más contenedores en una máquina significa menos generación de máquinas.
Seguridad
La superficie de ataque se puede explicar en pocas palabras: cualquiera que sea la imagen de la ventana acoplable puede ser atacada, y cuanto más tenga, más probable es que sea atacada. Es así de simple. Por lo general, las imágenes de la ventana acoplable basadas en la distribución de Linux contienen toneladas de cosas que nunca necesitará, pero los piratas informáticos pueden usarlas para piratear su sistema.
Dinero
Recuerda tu proveedor de nube favorito y su oferta. Imaginemos que desea pagar solo por una máquina de baja especificación con solo 1 GB de RAM. Si el tamaño de su imagen es de 500 MB, puede colocar dos, pero si puede reducirlo a 100 MB, puede colocar diez contenedores. ¡Realmente importa! Incluso si no es un gigante de Internet como Google o Netflix, e incluso si tiene aplicaciones relativamente pequeñas con muchos menos usuarios, los costos se acumulan con el tiempo.
Una imagen sin distro es una imagen de distribución de Linux reducida más el tiempo de ejecución de la aplicación, lo que da como resultado el conjunto mínimo de dependencias binarias requeridas para que la aplicación se ejecute.
Las imágenes sin distribución se basan en distribuciones de Linux; distroless no es una imagen desnuda (sin nada). Por ejemplo, las imágenes de Google actuales (marzo de 2020) se basan en Debian, pero minimizan las distribuciones de Debian reducidas.
Contenido
Los contenedores no son máquinas virtuales, no necesita archivos binarios enormes para que el sistema operativo ejecute su aplicación. No necesita ls o grep find cat o incluso bash en su contenedor para ejecutar la aplicación java/go/node. Si está acostumbrado a iniciar sesión en las imágenes de su contenedor y jugar con bash como root, no tiene suerte en general (no es muy recomendable), pero con distroless es simplemente imposible.
¿Realmente necesita grep, ls o bash en su imagen de contenedor de producción?
Booo, ¡aquí no hay shell de Linux! Simplemente ejecuta aplicaciones Java sobre una instancia reducida de Debian.
Un contenedor típico consta de:
El contenedor optimizado se ve así:
Un contenedor aún más optimizado se ve así (la optimización del tiempo de ejecución es un tema de otro artículo, pero vale la pena señalar que también puede reducir el tiempo de ejecución de Java JRE o Python):
Tamaño
Compara los tamaños de las imágenes por un segundo.
Seguridad
Es una práctica recomendada, y más aún una práctica simplemente obligatoria (cumplimiento, etc.), escanear los contenedores en busca de vulnerabilidades conocidas utilizando escáneres.
Una mejor relación señal-ruido para los escáneres de seguridad de contenedores es una de las razones importantes para los contenedores sin distribución, también menos archivos para escanear y menos E/S y consumo de CPU para escanear también. ¿Qué significa esto realmente?
Por lo general, las distribuciones predeterminadas vienen con decenas de advertencias y problemas de seguridad, que a menudo se ignoran, lo cual es una estrategia arriesgada porque entre ellos (ruido) pueden haber algunos problemas de seguridad importantes que pueden poner en peligro la seguridad de su aplicación.
Con imágenes de contenedores más limpias, que generan casi cero advertencias y errores durante el proceso de escaneo, puede ver claramente las cosas que importan, por lo que la relación señal/ruido es mucho mayor.
Escaneemos nuestras imágenes usando un escáner clair.
docker run - d --name db arminc/clair- db
docker run -p 6060:6060 --link db :postgres - d --name clair arminc/clair- local -scan
La imagen oficial de openjdk y la imagen distroless no tienen vulnerabilidades detectadas, otras imágenes tienen múltiples vulnerabilidades detectadas.
Hazlo tu mismo
Las imágenes sin distribución están aquí. Google, que pareció iniciar este movimiento, está publicando sus propias imágenes sin distribución para Java, Python, Go y C++.
Tenga en cuenta que (generalmente) no tiene el administrador de paquetes en una imagen base sin distribución (lo que puede ser impactante al principio). Nuevamente, no hay apt ni pip, debe instalar las dependencias de otra manera. Una forma alternativa es usar una compilación de varias etapas, una característica de Docker que nos permitirá los efectos (archivos) creados por un administrador de paquetes para nuestro objetivo de una imagen basada en distroless.
Así que podemos tener tanto el administrador de paquetes temporal en una imagen acoplable temporal como el sistema de archivos aplanado que da como resultado una imagen más pequeña.
Como todo lo que haces tú mismo, surge la cuestión del mantenimiento. ¿Quién, cuándo y cómo actualizará su imagen distroless local? Esto debe abordarse, de lo contrario, sin el mantenimiento adecuado y las actualizaciones de las dependencias básicas, se oxidará muy rápidamente y anulará el propósito de su creación.
Linux alpino
Alpine Linux es una distribución de Linux muy pequeña que solo tiene un tamaño de 4 MB.
Alpine musl libc y busybox carecen de soporte GNU glibc y la falta de soporte GNU glibc significa problemas.
Por ejemplo, JDK no se ejecuta en musl libc, hay un puerto llamado Portola, pero ciertamente no está tan bien probado ni es tan confiable como las distribuciones oficiales de JDK. Es difícil imaginar ejecutar aplicaciones comerciales críticas en prototipo. Por supuesto, hay noticias de que la nueva versión está funcionando o estará funcionando pronto.
Alpine significaba, por ejemplo, que los contenedores de Python tenían que descargar todas las dependencias y, como consecuencia, se han vuelto más grandes con la imagen base de Alpine que sin ella (¡sic!).
Además, la imagen de Alpine Linux contiene herramientas de busybox, apk (administrador de paquetes) y otros archivos binarios que simplemente no necesita para ejecutar su aplicación.
¿Alpino con glibc? Sí, hay contenedores basados en bibliotecas Alpine plus glibc. Aún así, no es tan fácil como les gustaría a los fanáticos de Alpine.
Imágenes delgadas
Como puede ver en el ejemplo anterior, existen versiones 'delgadas' fácilmente disponibles de las imágenes oficiales para cualquier tiempo de ejecución de idioma dado, que vale la pena investigar. Sin embargo, a menudo tienen un shell y herramientas de comando que no son buenas para la seguridad de los contenedores.
A veces pueden contener binarios en exceso que no necesita, y no tienen los que sí necesita, lo que puede romper sus dependencias de tiempo de ejecución.
Minimizar el tamaño de la imagen usando herramientas
Otro enfoque es usar una imagen base estándar (no minimizada) y luego usar herramientas automáticas para detectar dependencias y eliminar archivos que no son necesarios. Por ejemplo, un análisis de minicon existente en los contenedores brinda algunas sugerencias, por ejemplo, los comandos EJECUTAR y otros comandos que se requerirán, y en base a eso, las sugerencias pueden reducir significativamente el tamaño de la imagen del contenedor.
Sin embargo, el riesgo es que los hallazgos de dependencia automatizados puedan fallar y dar como resultado que un contenedor de tiempo de ejecución no pueda ejecutar su aplicación. Soporté tediosos esfuerzos de prueba y error para corregir errores de tiempo de ejecución (archivo no encontrado, biblioteca dependiente faltante, etc.) agregando bibliotecas faltantes, archivos de configuración y configuraciones de entorno.
Según la investigación, he identificado las siguientes respuestas típicas al problema del tamaño del contenedor y la optimización de la superficie de ataque:
Por supuesto que depende del problema específico, proyecto, etc. Pero hay estadísticas y práctica. Identifique su campamento y explique por qué.
Nuestros expertos que trabajan para soluciones complejas en los sectores farmacéutico, de seguros, bancario e industrial comparten sus puntos de vista.
Felix Hassert, Avenga, Director de Productos y Alojamiento
En el entorno Go(lang), las imágenes sin distro han existido durante bastante tiempo. Go generalmente compila binarios gordos vinculados 'casi estáticamente'. Esto hace que sea especialmente fácil usar contenedores sin distribución.
Para nuestros componentes basados en Go en https://wao.io , usamos compilaciones acoplables de varias etapas: la compilación Go se lleva a cabo en un
golang:<version>
imagen; el binario producido se copia posteriormente en una imagen borrador.La directiva `FROM SCRATCH` no solo no tiene distribución, sino que está literalmente vacía. Menos huella en términos de tamaño y la superficie de ataque ni siquiera es posible.
En una época en la que todos impulsan sus sucursales temprano y con frecuencia y CI/CD está en su lugar, las descargas más rápidas y el uso de menos espacio en Docker Registry son una ventaja por sí solos. Pero más importantes son los efectos positivos de la disciplina forzada:
Si no hay nada en la imagen base, debe traer todo lo necesario deliberadamente. No hay dependencias ocultas. Su software no fallará si lib A lo obliga a actualizar la imagen base que podría venir con una versión incompatible de lib B.
También es mucho más fácil seguir las mejores prácticas de seguridad. Sin archivos, no hay problemas con los permisos de archivos. Simplemente ejecute su punto de entrada con una identificación de usuario sin privilegios y haga que la carpeta raíz no se pueda escribir. Esto evitará toda una clase de errores relacionados con el sistema de archivos. Simplemente no puede escribir en un disco sin un volumen de Docker. No existe la tentación de escribir registros en ningún otro lugar que no sea stdout/stderr.
Sin embargo, incluso para el software Go, puede ser complicado ejecutarlo en un contenedor temporal. Por ejemplo, si necesita procesar el tráfico HTTPS, debe traer los certificados de CA usted mismo. La depuración también puede ser complicada, porque no tiene un shell para ejecutar, pero Docker le permite iniciar un contenedor de depuración completo (con shell, strace y otras herramientas útiles) y adjuntarlo al espacio de proceso del contenedor de muestras.
docker run -it --rm --pid =container:<go-container> --cap- add SYS_PTRACE alpine sh
Dicho esto, la tendencia distroless es absolutamente la dirección correcta.
Vladyslav Litovka, experto en DevOps
En proyectos recientes, pasamos a usar compilaciones de varias etapas y contenedores minificados; en su mayoría de base alpina pero también sin distorsión. En algunos casos fue forzado por los requisitos del cliente (como dijo Andriy), y en algunos casos fue nuestra decisión. De todos modos, en todo el proyecto puedo decir que en la mayoría de los casos es la opción 1, en algunos la opción 2 y 3.
Excelente artículo. Buenas y sencillas explicaciones. Contiene la cantidad exacta de detalles técnicos que nos permiten comprender el propósito principal y la dirección de implementación en solo 15 minutos del tiempo del lector.
Andrew Petryk, gerente de ingeniería de Java
Nosotros, en Avenga , hemos usado contenedores sin distribución en entornos de producción durante más de 3 meses y ya estamos usando compilaciones de varias etapas. No estuvimos allí desde el principio, pero las restricciones de seguridad de nuestro cliente nos obligaron a hacerlo. Y funcionó a las mil maravillas (por supuesto, con la orquestación adecuada y la gestión de registro).
En general, parece ser una tendencia: todo se está volviendo más pequeño. Recuerdo los días en que implementar .war en un servidor de aplicaciones web de Java era una tarea de varios minutos en la que ahora los micromarcos luchan por un tiempo de inicio de menos de un segundo. Hemos progresado bastante bien allí. Lo mismo ocurre con las imágenes de la ventana acoplable, pero la lucha es por MB en lugar de segundos.
No puedo decir que estoy sólidamente en uno de los campamentos que Jacek mencionó anteriormente (excepto el campamento 1 :)) porque, como suele suceder en TI, depende de muchos factores. Pero seguro, las imágenes sin distribución son una cosa y definitivamente deberías intentarlo.
Los contenedores están en todas partes y saber cómo usarlos de manera eficiente es una habilidad clave para todas las organizaciones tecnológicas. Nos complace compartir una introducción sin distribución y las opiniones de nuestros "expertos" sobre el tema.
Si eres nuevo en el tema, espero que ahora veas que vale la pena probar distroless, si desde hace algún tiempo ya eres fanático de distroless, definitivamente no estás solo.
Descubra qué más está haciendo Avenga aquí y consulte también nuestro perfil de LinkedIn .