Búsqueda de sitios web

Cómo crear imágenes eficientes de Python Docker


Las imágenes de Docker son una herramienta poderosa para distribuir sus proyectos de Python, pero es importante que las mantenga lo más sencillas posible.

Docker es el software estándar de la industria para empaquetar e implementar aplicaciones en contenedores. Las imágenes de Docker son la piedra angular sobre la que puedes crear y ejecutar tus aplicaciones.

Para desbloquear todo el potencial de Docker, necesita optimizar sus imágenes para lograr eficiencia, seguridad y rendimiento de los recursos. Esto garantizará que sus aplicaciones funcionen sin problemas dentro del ecosistema Docker.

Aprenda cómo hacer esto con un ejemplo del mundo real que muestra cómo contener una aplicación de calculadora Python.

Comenzando con una imagen base mínima

Uno de los factores que afecta la eficiencia de una imagen Docker es la elección de la imagen base. Debe comenzar con una imagen mínima que incluya solo los componentes esenciales necesarios para ejecutar su aplicación.

La imagen que utilice también debe provenir de una fuente confiable que proporcione actualizaciones y parches de seguridad. Debe tener una comunidad activa y buena documentación. Esto resulta útil a la hora de solucionar problemas o buscar ayuda.

Para la aplicación de calculadora, elegir python:3.11-slim-bookworm, que es una imagen mínima, reduce el tamaño de la imagen. Esto, a su vez, minimiza el consumo de recursos y acelera las descargas e implementaciones de imágenes.

# Starting With a Minimal Base Image
FROM python:3.11-slim-bookworm AS builder

Puede utilizar una imagen de Alpine Linux aún más pequeña, optando por python:3.11-alpine. Sin embargo, esta imagen no incluye un intérprete de Python, un administrador de paquetes ni bibliotecas comunes de Python.

Ejecutar aplicaciones como usuarios no root

La ejecución de contenedores Docker como usuario root puede plantear importantes riesgos de seguridad. Si un actor malintencionado obtiene acceso a un contenedor que se ejecuta como root, puede explotar las vulnerabilidades en el software del contenedor para aumentar sus privilegios. Luego pueden usar estos privilegios para ejecutar comandos con control total sobre el sistema host.

La solución es ejecutar sus aplicaciones como usuario no root. El ejemplo de calculadora crea y configura la calculadora del usuario.

# Set non-root user for security
RUN adduser calculator --system
# Add the user to the calculator group
RUN addgroup calculator && adduser calculator calculator

Crear un usuario dedicado para su aplicación limita los permisos disponibles para posibles atacantes. Esto hace que sea más difícil explotar las vulnerabilidades.

Copiar archivos necesarios y crear un entorno virtual

La creación de un entorno virtual dentro de un contenedor Docker aísla las dependencias. Esto evita conflictos con paquetes de todo el sistema y otras aplicaciones. También garantiza la compatibilidad de versiones, ya que puede instalar las versiones exactas de las dependencias que necesita su aplicación, sin afectar al resto del sistema.

Copie los archivos necesarios en el contenedor. Luego, cree un entorno virtual para la aplicación de calculadora utilizando el módulo venv integrado de Python.

# Set working directory and copy necessary files
WORKDIR /app
COPY app.py .
COPY requirements.txt .
COPY config.json ./
# Copy config.json from the local directory
# Create a virtual environment and install dependencies
RUN python -m venv /venv
ENV PATH="/venv/bin:$PATH"
RUN /venv/bin/pip install --upgrade pip --no-cache-dir --requirement requirements.txt

Los entornos virtuales son livianos y eficientes, ya que no duplican paquetes de todo el sistema. Esto ayuda a mantener el tamaño de la imagen de Docker más pequeño y reduce el consumo de recursos cuando el contenedor se está ejecutando.

Minimizar capas para lograr eficiencia

Cada instrucción en un Dockerfile crea una nueva capa en la imagen resultante. Docker utiliza un mecanismo de copia en escritura para administrar estas capas. Reducir la cantidad de capas en la imagen de Docker mejora significativamente el tamaño de la imagen y el rendimiento de la compilación. Una forma de reducir las capas es consolidar varios comandos en una única instrucción EJECUTAR.

# Minimizing Layers for Efficiency
# Combine commands to reduce the number of layers
RUN echo "Build process goes here" && \
   /venv/bin/python -m compileall . && \
   rm -rf __pycache__

La combinación de los comandos anteriores reduce la cantidad de capas intermedias creadas durante el proceso de creación de la imagen.

Manejo seguro de la configuración

El manejo de información confidencial dentro de una imagen de Docker plantea un riesgo de seguridad. Para mejorar la seguridad, debe utilizar variables ambientales y archivos de configuración externos. En el ejemplo de la aplicación de calculadora, puede crear un directorio llamado /config para almacenar su archivo de configuración y establecer la propiedad adecuada.

# Securing Configuration Handling
RUN mkdir /config && chown calculator:calculator /config

Luego copie el archivo config.json en este directorio, asegurándose de que permanezca separado del código de la aplicación.

# Copy the config.json file into the container
RUN cp config.json /config/config.json
ENV CONFIG_PATH=/config/config.json

Segregar los datos de configuración del código y aplicar los permisos adecuados mejora la seguridad general de su imagen de Docker. Garantiza que solo los procesos o usuarios autorizados tengan acceso a los datos de configuración críticos.

Uso de compilaciones de varias etapas

Las compilaciones de varias etapas le permiten separar el entorno de compilación de la imagen final. Esto da como resultado imágenes de producción más pequeñas y enfocadas. También mejora la seguridad al excluir herramientas y archivos relacionados con la compilación de la imagen final. Esto reduce la superficie de ataque y minimiza los posibles riesgos de seguridad asociados con componentes innecesarios.

# Leveraging Multi-Stage Builds
FROM python:3.11-slim-bookworm
COPY --from=builder /etc/passwd /etc/passwd
COPY --from=builder /etc/group /etc/group
COPY --from=builder /venv /venv
COPY --from=builder /config /config
COPY --from=builder /app /app
# Copy the application code

El código anterior solo copia los artefactos necesarios de la etapa de construcción (constructor) en la imagen final. Esto reduce el tamaño de la imagen al excluir herramientas y archivos relacionados con la compilación que no son necesarios para ejecutar la aplicación de calculadora.

Mejora de la seguridad con escaneo de imágenes

Para mejorar aún más la seguridad de sus imágenes de Docker, utilice herramientas de escaneo de imágenes como Trivy o Clair. Estas herramientas están diseñadas para identificar vulnerabilidades en las capas y dependencias de sus imágenes. Utilice Trivy para la aplicación de calculadora para realizar un escaneo de vulnerabilidades.

# Install Trivy for Debian/Ubuntu
RUN apt-get update && \
   apt-get install -y wget apt-transport-https gnupg lsb-release && \
   wget -qO - https://aquasecurity.github.io/trivy-repo/deb/public.key | apt-key add - && \
   echo "deb https://aquasecurity.github.io/trivy-repo/deb bookworm main" \
   | tee -a /etc/apt/sources.list.d/trivy.list && \
   apt-get update && \
   apt-get install -y trivy

Agregar el escaneo de vulnerabilidades de Trivy a su imagen de Docker es crucial. Esto se debe a que utiliza la base de datos de vulnerabilidades y exposiciones comunes (CVE), que se actualiza periódicamente con información sobre vulnerabilidades conocidas. Esto le ayuda a mantener sus imágenes actualizadas con los últimos parches de seguridad y proteger sus aplicaciones de vulnerabilidades conocidas.

Para obtener un informe de vulnerabilidad de su imagen, utilice el siguiente comando.

docker run --rm `
 -v /var/run/docker.sock:/var/run/docker.sock `
 -v $HOME/Library/Caches:/root/.cache/ `
 aquasec/trivy:0.18.3 `
 <your image name>

El comando anterior tardará algún tiempo en ejecutarse. Una vez que haya terminado, generará un informe como el que se muestra a continuación.

Cuanto mayor sea la gravedad, más rápido deberá abordar la vulnerabilidad identificada.

Ejecutar aplicaciones como usuarios no root

Para mejorar la seguridad, ejecute la aplicación como usuario de la calculadora para limitar posibles vulnerabilidades.

# Running Applications as Non-Root Users
WORKDIR /app
USER calculator
# Activate the virtual environment and run the application
CMD ["/bin/bash", "-c", "source /venv/bin/activate && python app.py"]

Cambiar a un usuario no root minimiza la superficie de ataque.

Contenedor de aplicaciones que no son Python

La contenedorización Docker de aplicaciones impulsadas por otros lenguajes es un poco diferente. Debería familiarizarse con cómo contener diferentes tipos de aplicaciones. Esto le ayudará a decidir la mejor estrategia a adoptar según el tipo de lenguaje que utiliza su aplicación.