10 puntos por GN⁺ 2024-01-09 | 1 comentarios | Compartir por WhatsApp
  • Dive es una herramienta para explorar las capas y el contenido de archivos de imágenes Docker/OCI, y encontrar oportunidades para reducir el tamaño de la imagen
  • Se puede ejecutar dive <your-image-tag> con una etiqueta, ID o digest de imagen, o usar dive build -t <some-tag>. para realizar el análisis justo después del build en un solo paso
  • Al seleccionar una capa, muestra el árbol de archivos resultante de combinar esa capa con las anteriores, y permite ver en el árbol de archivos los archivos agregados, modificados y eliminados, además de los cambios acumulados
  • Con la métrica experimental de image efficiency, estima como puntuación y tamaño total el espacio desperdiciado por archivos duplicados, movimientos de archivos entre capas y archivos que no se eliminaron por completo
  • Con CI=true se puede omitir la UI y devolver aprobado/fallido según criterios de eficiencia de imagen y espacio desperdiciado, lo que permite automatizar la gestión del tamaño de imágenes en pipelines de CI

Qué hace Dive

  • Dive es una herramienta para explorar imágenes Docker, el contenido de sus capas y formas de reducir el tamaño de imágenes Docker/OCI
  • La ejecución básica consiste en pasar una etiqueta, ID o digest de imagen
    • dive <your-image-tag>
  • También se puede ejecutar como contenedor Docker; en ese caso hay que montar el socket de Docker
    • Usa la imagen docker.io/wagoodman/dive
    • Se presenta nginx:latest como imagen de ejemplo
  • Para analizar una imagen inmediatamente después de construirla, se puede usar el comando dive build con el mismo formato en lugar de docker build
    • dive build -t <some-tag> .
  • En macOS, el análisis de build ejecutado en contenedor solo es compatible con el motor de contenedores Docker
  • El estado del proyecto es de calidad beta, y las solicitudes de nuevas funciones o bugs pueden enviarse como issues

Exploración de capas y cambios en archivos

  • Al seleccionar una capa a la izquierda, a la derecha se muestra el árbol de archivos que combina esa capa con las capas anteriores
  • Se puede navegar por el árbol de archivos con las teclas de dirección
  • En cada capa, el estado de los archivos modificados se muestra en el árbol de archivos
    • Cambiado
    • Modificado
    • Agregado
    • Eliminado
  • La forma de mostrar los cambios se puede ajustar según una capa específica o según los cambios acumulados hasta esa capa

Eficiencia de imagen y estimación de espacio desperdiciado

  • El panel inferior izquierdo muestra información básica de las capas y la métrica experimental de image efficiency
  • Esta métrica estima el espacio desperdiciado dentro de la imagen
    • Duplicación de archivos entre capas
    • Movimiento de archivos entre capas
    • Archivos que no se eliminaron por completo
  • El resultado se entrega como score porcentual y como espacio total de archivos desperdiciado

Uso como criterio de aprobado/fallido en CI

  • Al ejecutarlo con la variable de entorno CI=true, Dive omite la UI, analiza la imagen y entrega un resultado pass/fail mediante el código de retorno
  • Con el archivo .dive-ci en la raíz del repositorio se pueden configurar 3 criterios
    • lowestEfficiency: falla si la eficiencia es menor que el porcentaje especificado
    • highestWastedBytes: falla si el espacio desperdiciado es igual o superior al tamaño especificado
    • highestUserWastedPercent: falla si el porcentaje de desperdicio en capas de usuario es igual o superior al porcentaje especificado
  • En el cálculo de highestUserWastedPercent, la base image layer no se incluye en el tamaño total de la imagen
  • La ruta del archivo de configuración de CI se puede sobrescribir con la opción --ci-config

Fuentes de imágenes y motores de contenedores

  • Con la opción --source se puede elegir desde dónde traer la imagen de contenedor
    • dive <your-image> --source <source>
    • dive <source>://<your-image>
  • Las opciones de source compatibles son las siguientes
    • docker: Docker engine, valor predeterminado
    • docker-archive: Docker Tar Archive en disco
    • podman: Podman engine, solo compatible con Linux

Instalación y formas de ejecución

  • En Ubuntu/Debian se puede instalar mediante paquete .deb o Snap
  • El método con Snap no se recomienda si Docker se instaló con apt-get, y se advierte que puede dañar el daemon de Docker existente
  • En RHEL/Centos se puede instalar mediante paquete .rpm
  • En Arch Linux está disponible en el extra repository y se puede instalar con pacman
  • En macOS se puede instalar con Homebrew, MacPorts o con el build para Darwin desde la releases page
  • En Windows se puede instalar con Chocolatey, scoop, winget o con el build para Windows desde la releases page
  • Para instalarlo con la herramienta de Go se requiere Go 1.10 o superior
    • go install github.com/wagoodman/dive@latest
    • Si se instala de esta forma, al ejecutar dive -v no se mostrará la versión correcta
  • También se ofrecen métodos de instalación con Nix/NixOS y x-cmd
  • Al ejecutarlo como imagen Docker, hay que incluir el archivo de socket de Docker
    • -v /var/run/docker.sock:/var/run/docker.sock
  • Según la versión local de Docker, puede ser necesaria una variable de entorno como DOCKER_API_VERSION=1.37
  • Si se usa un runtime alternativo como Colima, puede ser necesario especificar la variable de entorno DOCKER_HOST para traer imágenes locales

Controles y configuración de la UI

  • Los atajos de teclado principales permiten navegar, filtrar y alternar vistas entre la vista de capas y la vista de árbol de archivos
    • Ctrl+C o Q: salir
    • Tab: alternar entre vista de capas y vista de árbol de archivos
    • Ctrl+F: filtro de archivos
    • Ctrl+A: en la vista de capas, ver cambios acumulados de la imagen; en la vista de árbol de archivos, alternar la visualización de archivos agregados
    • Ctrl+L: ver cambios de la capa actual
    • Ctrl+R, Ctrl+M, Ctrl+U: alternar la visualización de archivos eliminados, modificados y sin cambios
    • Ctrl+B: alternar la visualización de atributos de archivos
  • No se necesita configuración aparte, pero los valores se pueden sobrescribir con un archivo de configuración YAML
  • Los elementos configurables incluyen el motor de contenedores, si se ignoran errores de parseo de archivos de imagen, logs, atajos de teclado, visualización de diff, ancho del árbol de archivos, estado predeterminado de directorios contraídos y visualización de cambios acumulados por capa
  • Las ubicaciones de búsqueda del archivo de configuración son las siguientes
    • $XDG_CONFIG_HOME/dive/*.yaml
    • $XDG_CONFIG_DIRS/dive/*.yaml
    • ~/.config/dive/*.yaml
    • ~/.dive.yaml
  • También se puede usar la extensión .yml en lugar de .yaml

1 comentarios

 
GN⁺ 2024-01-09
Opiniones en Hacker News
  • Cuando trabajas con imágenes y capas, crane es excelente, y su biblioteca base, go-containerregistry, también es buena.
    Puedes agregar una nueva capa a una imagen existente o modificar metadatos (env vars, labels, entrypoint, etc.), y también puedes “aplanar” imágenes de varias capas en una sola capa.
    También permite hacer “rebase”, es decir, volver a aplicar cambios sobre una nueva imagen base, y todo esto se procesa directamente en el registro, por lo que no necesitas Docker.
    https://github.com/google/go-containerregistry/blob/main/cmd...

    • Buena recomendación. A diferencia de Docker, crane funciona sin root ni daemon, así que es cómodo de usar en Nix, y en el repositorio de Nix también se ofrece con el nombre crane.
      Gracias a eso, con Nix puedes gestionar no solo dependencias de compilación (por ejemplo, Go), sino también herramientas de empaquetado y despliegue (por ejemplo, gnu tar, crane).
    • Me pregunto si tener menos capas trae ventajas de rendimiento. Entiendo que, aunque combines imágenes, el tamaño total sigue igual, así que fusionar capas en sí no aporta beneficios.
  • dive me resultó realmente útil para entender cómo funcionan las imágenes Docker y cómo escribir un Dockerfile eficiente.
    Leer la documentación también es importante, pero ver directamente cómo cambia la estructura de capas resultante después de modificar un Dockerfile fue clave para entenderlo.

  • Dive es excelente. Este tipo de herramientas es importante para aprender y tener confianza sobre qué estoy construyendo y desplegando exactamente.
    Dredge también es una herramienta que vale la pena mirar; la uso para comparar diferencias entre capas.
    https://github.com/mthalman/dredge/blob/main/docs/commands/i...

  • Puede ser una pregunta tonta, pero me pregunto por qué la mayoría de las herramientas de contenedores e infraestructura están escritas en Go.
    Me vienen a la mente Docker, Podman, nerdctl, Terraform y Kubernetes, y quisiera saber si Go ofrece alguna ventaja clara al crear este tipo de herramientas.

    • Puedo responder sobre Docker. El primer prototipo se escribió en Python, y la empresa también estaba centrada en Python.
      La razón principal para reescribirlo en Go fue subirse a la popularidad de Go, que en ese momento (2012) venía creciendo. Yo estuve ahí.
    • Go es el lenguaje más fácil para compilación cruzada y distribución, ofrece muy buen rendimiento en relación con la productividad, tiene buena concurrencia integrada, y las capacidades de red de su biblioteca estándar también son excelentes.
      La diferencia se nota si imaginas que Docker y Kubernetes hubieran sido escritos en otro lenguaje popular.
    • Creo que las herramientas de sistema, utilidades, herramientas de línea de comandos y software de redes son los ámbitos donde Go más brilla.
      Como alternativa moderna y madura, parece que solo está Rust.
    • Kubernetes está escrito en Go porque Google creó Go y también creó Kubernetes.
      Que haya muchos ingenieros de Go en los equipos internos se debe a la misma razón.
    • Al ejecutar contenedores, quieres preocuparte lo menos posible por el sistema subyacente, y Go facilita funcionar dentro de su propio pequeño mundo.
      Además, existe el efecto de ecosistema: puedes aprovechar directamente paquetes de otras implementaciones en partes de tu código.
  • Me gusta Dive y lo saco de mi caja de herramientas varias veces al mes.
    Sin embargo, me pregunto si hay una forma de ver directamente el contenido del archivo seleccionado. Muchas veces quiero comprobar si un archivo existe dentro de una capa y luego revisar su contenido, pero por ahora normalmente ejecuto el contenedor y uso cat, o extraigo el contenido y navego hasta la carpeta.

    • Con algo de maña se puede acceder a los archivos con rsync, pero no es muy distinto de usar cat.
  • Al extender varios contenedores Docker públicos, Dive me salvó varias veces mientras investigaba qué hacían por dentro.
    Es software de categoría A+.

  • Hay más excelentes herramientas TUI de terminal como dive. Se me vienen a la mente lazydocker y dry.
    También hay varias dentro de la categoría Docker.
    [0] https://terminaltrove.com/

    • Lazydocker tiene una función parecida, pero más simple.
      Al revisarlo, permite ver las capas, pero solo muestra el comando de cada capa.
  • Dive es una herramienta sorprendente en el ámbito de contenedores/Docker. Hace mucho más fácil depurar qué hay realmente dentro de un contenedor.
    Cuando empezamos Depot [0], recibíamos muchas preguntas sobre cómo reducir el tamaño de las imágenes y acelerar las compilaciones, así que escribí un artículo corto [1] sobre cómo resolver ese problema con Dive. Quizá hoy esté un poco desactualizado, pero puede servirle a alguien.
    Inspirados por Dive, también hicimos más fácil revelar qué hay realmente dentro del contexto de build en cada compilación, y lo lanzamos como una función de Depot hace unas semanas.
    [0] https://depot.dev
    [1] https://depot.dev/blog/reducing-image-size-with-dive
    [2] https://depot.dev/blog/build-context

  • Además de ser muy útil, Dive tiene una ventaja subestimada: su autor es un excelente desarrollador y una persona con la que da mucho gusto trabajar.

  • La herramienta de Google llamada container-diff también es realmente útil.
    La uso para comprobar qué le haría al sistema un script arbitrario que recomiendan ejecutar pasándolo por pipe a bash.

    • Aunque está algo menos relacionada con las utilidades generales de contenedores, uso mucho GoogleContainerTools/container-structure-test.
      Es una forma cómoda de ejecutar pruebas de integración sobre una app o imagen de contenedor.
      Es una lástima que estos proyectos open source de Google parezcan necesitar más atención, porque muchas de las personas que originalmente los mantenían ya se fueron. Cuando puedo, envío PR y de vez en cuando cierro issues. En especial, esta herramienta de pruebas es muy valiosa para mantener la cordura cuando se trabaja con muchas imágenes base que debemos mantener internamente.