Optimizar Imágenes
Ventajas
- Despliegues y registros más veloces;
- Reducir costos de almacenamiento en nube;
- Minimzar vulnerabilidades internas;
- Arranques de contenedores más veloces;
- Manejo de contenedores más eficiente.
Imágenes minimalistas
Un buen punto de partida consiste en elegir una imagen lo más reducida posible (minimal flavors) en cuanto a espacio ocupado y componentes internos.
Las distribuciones de Linux más habituales son Ubuntu, Debian y Alpine. Entre ellas, Alpine es con diferencia la más liviana y reducida:
sin embargo esta opción no da el mejor rendimiento para todos los lenguajes posibles, por ello debe ser usada con precaución.Una alternativa aún más compacta que alpine
es el uso de imágenes distroless, por ejemplo:
Dockerignore
El archivo oculto Dockerignore
se usa para
prevenir la copia de contenidos innecesarios
adentro de la imagen objetivo:
- carpetas de controles de versiones como Git (
.git
) o Subversion (.svn
); - paquetes descargados;
- archivos
.env
y claves SSH; - etc.
Se usa de idéntica manera que el archivo gitignore
de Git.
Ejemplo de uso:
# Control de versiones
.git
.svn
.gitignore
# Documentación Markdown
*.md
Construcción Multi-Stage
Con este recurso se construyen las imágenes en dos etapas:
- La primera etapa sirve para instalar todas las dependencias
y, de ser necesario, compilar archivos ejecutables.
A esta etapa se la suele llamar
builder
(constructora). - La segunda etapa consiste en copiar los archivos estrictamente necesarios a la imagen final, la cual está basada en una imagen compatible lo más minimalista posible.
Así se ve un Dockerfile multietapa:
# Etapa construccion
FROM imagen_builder AS builder
RUN comandos_instalacion
# ...
# Etapa final
FROM imagen_final
# ...
COPY --from=builder ruta_builder ruta_final
CMD ["comando", "argumento"]
Para que la imagen final funcione correctamente es necesario que la imagen final de referencia sea compatible con la imagen usada para la construcción. Por ejemplo, si la imagen final es una imagen de Alpine Linux es prudente elegir una imagen builder derivada de Alpine Linux.
# Etapa construccion
FROM golang:1.21-alpine AS builder
# ...
# Etapa final
FROM alpine:3.18
COPY -FROM=builder ruta_app
# ...
El mismo criterio se aplica para imágenes basadas en Debian y Ubuntu.
Otras etapas posibles: build
, dev
, test
, lint
.
Dockerfile con test
Si se crea la imagen en varias etapas y se desea incorporar una etapa de tests unitarios estos pueden tener su propia etapa:
Optimizar capas
Cada instrucción del Dockerfile crea una nueva capa (layer) de la nueva imagen.
Para minimizar las capas de la imagen final y optimizar su tamaño se pueden seguir varias estrategias complementarias.
Ordenar instrucciones
Para una mejor construcción es mejor colocar las instrucciones que cambian con menos frecuencia al final. De esta manera se reutilizan las capas preconstruidas en caso que no se detecten cambios.
Por ejemplo, las rutinas de programación cambian frecuentemente y por ello es mejor copiarlas adentro de la imagen al final, justo antes de ordenar la ejecución.
En cambio, las dependencias cambian con poca frecuencia y por eso se las instalaciones se hacen cerca del comienzo.
Combinar comandos RUN
Las instrucciones se instalación de dependencias múltiples se pueden combinar para dar forma a una única capa.
Por ejemplo,
si el archivo Dockerfile
tiene originalmente esta forma:
# instalación de dependencias
RUN instalar dependencia_1
RUN instalar dependencia_2
RUN ...
RUN instalar dependencia_n
# borrado de caché
RUN rm ruta_cache
&&
permite concatenar comandos
en tanto que
\
permite concatenar los argumentos de un mismo comando.
Limpiar layers
Es una buena práctica aprovechar cada instrucción RUN relacionada con la instalación de dependencias para eliminar los archivos descargados y desempaquetados dentro de la imagen.
Usar COPY
en vez de ADD
Comando history
El comando history
sirve para listar el historial de capas y sus cambios a lo largo del tiempo.
Comando scout
El comando scout
sirve para buscar vulnerabilidades conocidas en la imagen objetivo y reportarlas.
(Sólo disponible en Docker).
Referencias
DevDojo.com - Optimizing Docker Image Sizes: Advanced Techniques and Tools