10 points par GN⁺ 2024-01-09 | 1 commentaires | Partager sur WhatsApp
  • Dive est un outil qui permet d’explorer les couches et le contenu des fichiers des images Docker/OCI, et de repérer les possibilités de réduction de la taille des images
  • Il est possible d’exécuter dive <your-image-tag> avec un tag, un ID ou un digest d’image, ou d’utiliser dive build -t <some-tag>. pour effectuer l’analyse juste après le build en une seule commande
  • Lorsqu’on sélectionne une couche, l’outil affiche l’arborescence de fichiers résultant de la fusion de cette couche avec les couches précédentes, ce qui permet de voir les fichiers ajoutés, modifiés, supprimés ainsi que les changements cumulés
  • Son indicateur expérimental d’image efficiency estime, sous forme de score et de volume total, l’espace gaspillé dû aux fichiers dupliqués, aux déplacements de fichiers entre couches et aux fichiers non complètement supprimés
  • Avec CI=true, il est possible d’ignorer l’interface et d’obtenir un résultat de réussite/échec selon des seuils d’efficacité de l’image et d’espace gaspillé, afin d’automatiser la gestion de la taille des images dans un pipeline CI

Ce que fait Dive

  • Dive est un outil d’exploration des images Docker, du contenu des couches et des moyens de réduire la taille des images Docker/OCI
  • L’exécution de base consiste à lui passer un tag, un ID ou un digest d’image
    • dive <your-image-tag>
  • Il peut aussi être exécuté dans un conteneur Docker, auquel cas il faut monter le socket Docker
    • utilisation de l’image docker.io/wagoodman/dive
    • l’image nginx:latest est donnée comme exemple cible
  • Pour analyser une image immédiatement après sa construction, on peut utiliser la commande dive build au lieu de docker build, avec la même forme
    • dive build -t <some-tag> .
  • Sur macOS, l’analyse de build exécutée en conteneur ne prend en charge que le moteur de conteneurs Docker
  • Le projet est actuellement en beta quality, et les demandes de nouvelles fonctionnalités ou les bugs peuvent être signalés via des issues

Exploration des couches et des changements de fichiers

  • Lorsqu’on sélectionne une couche à gauche, l’arborescence de fichiers combinant cette couche et les couches précédentes s’affiche à droite
  • Il est possible de parcourir l’arborescence avec les touches fléchées
  • L’état des fichiers modifiés dans chaque couche est affiché dans l’arborescence
    • modifié
    • altéré
    • ajouté
    • supprimé
  • L’affichage des changements peut être ajusté pour se baser soit sur une couche donnée, soit sur les changements cumulés jusqu’à cette couche

Efficacité de l’image et estimation de l’espace gaspillé

  • Le panneau en bas à gauche affiche les informations de base sur les couches ainsi que l’indicateur expérimental d’image efficiency
  • Cet indicateur estime l’espace gaspillé dans l’image
    • duplication de fichiers entre les couches
    • déplacement de fichiers entre les couches
    • fichiers non complètement supprimés
  • Le résultat est fourni sous la forme d’un score en pourcentage et d’un volume total d’espace occupé par des fichiers inutiles

Utilisation dans CI comme critère de réussite/échec

  • En l’exécutant avec la variable d’environnement CI=true, Dive ignore l’interface, analyse l’image puis renvoie un code de retour indiquant le résultat pass/fail
  • Le fichier .dive-ci à la racine du dépôt permet de définir 3 critères
    • lowestEfficiency : échec si l’efficacité est inférieure au pourcentage indiqué
    • highestWastedBytes : échec si l’espace gaspillé atteint ou dépasse le volume indiqué
    • highestUserWastedPercent : échec si le pourcentage de gaspillage des couches utilisateur atteint ou dépasse le pourcentage indiqué
  • Dans le calcul de highestUserWastedPercent, la base image layer n’est pas incluse dans la taille totale de l’image
  • Le chemin du fichier de configuration CI peut être remplacé via l’option --ci-config

Sources d’images et moteur de conteneurs

  • L’option --source permet de choisir d’où récupérer l’image de conteneur
    • dive <your-image> --source <source>
    • dive <source>://<your-image>
  • Les options source prises en charge sont les suivantes
    • docker : moteur Docker, valeur par défaut
    • docker-archive : archive Tar Docker sur disque
    • podman : moteur Podman, pris en charge uniquement sous Linux

Installation et modes d’exécution

  • Sous Ubuntu/Debian, l’installation peut se faire via un paquet .deb ou Snap
  • La méthode Snap n’est pas recommandée si Docker a été installé avec apt-get, car elle peut perturber le daemon Docker existant
  • Sous RHEL/Centos, l’installation peut se faire via un paquet .rpm
  • Sous Arch Linux, le paquet est disponible dans le extra repository et peut être installé avec pacman
  • Sous macOS, l’installation est possible via Homebrew, MacPorts ou le build Darwin disponible sur la releases page
  • Sous Windows, l’installation est possible via Chocolatey, scoop, winget ou le build Windows disponible sur la releases page
  • Pour une installation avec l’outil Go, Go 1.10 ou supérieur est requis
    • go install github.com/wagoodman/dive@latest
    • avec cette méthode, dive -v n’affiche pas la bonne version
  • Des méthodes d’installation pour Nix/NixOS et x-cmd sont également proposées
  • Lors de l’exécution via une image Docker, il faut inclure le fichier du socket Docker
    • -v /var/run/docker.sock:/var/run/docker.sock
  • Selon la version locale de Docker, une variable d’environnement comme DOCKER_API_VERSION=1.37 peut être nécessaire
  • Si vous utilisez un runtime alternatif comme Colima, il peut être nécessaire de définir la variable d’environnement DOCKER_HOST pour récupérer les images locales

Commandes et configuration de l’interface

  • Les principaux raccourcis clavier permettent de naviguer entre la vue des couches et l’arborescence de fichiers, ainsi que de filtrer et d’activer ou désactiver certains affichages
    • Ctrl+C ou Q : quitter
    • Tab : basculer entre la vue des couches et l’arborescence de fichiers
    • Ctrl+F : filtre de fichiers
    • Ctrl+A : dans la vue des couches, basculer l’affichage des changements cumulés de l’image ; dans l’arborescence, afficher ou masquer les fichiers ajoutés
    • Ctrl+L : afficher les changements de la couche actuelle
    • Ctrl+R, Ctrl+M, Ctrl+U : afficher ou masquer les fichiers supprimés, modifiés et inchangés
    • Ctrl+B : afficher ou masquer les attributs des fichiers
  • Aucune configuration séparée n’est nécessaire, mais il est possible de surcharger les valeurs via un fichier de configuration YAML
  • Les éléments configurables incluent le moteur de conteneurs, l’ignorance des erreurs d’analyse des archives d’images, les logs, les raccourcis clavier, l’affichage des diff, la largeur de l’arborescence, l’état replié par défaut des répertoires et l’affichage des changements cumulés des couches
  • Les emplacements de recherche des fichiers de configuration sont les suivants
    • $XDG_CONFIG_HOME/dive/*.yaml
    • $XDG_CONFIG_DIRS/dive/*.yaml
    • ~/.config/dive/*.yaml
    • ~/.dive.yaml
  • L’extension .yml peut aussi être utilisée à la place de .yaml

1 commentaires

 
GN⁺ 2024-01-09
Commentaires sur Hacker News
  • crane est excellent pour manipuler des images et des couches, et sa bibliothèque sous-jacente go-containerregistry est elle aussi très bonne
    On peut ajouter une nouvelle couche à une image existante ou modifier des métadonnées (variables d’environnement, labels, entrypoint, etc.), et aussi « aplatir » une image à plusieurs couches en une seule couche
    Il est également possible de faire un « rebase », c’est-à-dire réappliquer les changements sur une nouvelle image de base, le tout directement depuis le registre sans avoir besoin de Docker
    https://github.com/google/go-containerregistry/blob/main/cmd...

    • Excellente recommandation. Contrairement à Docker, crane fonctionne sans root ni démon, ce qui le rend pratique avec Nix, et il est aussi disponible sous le nom crane dans le dépôt Nix
      Cela permet de gérer avec Nix non seulement les dépendances de build (par ex. Go), mais aussi les outils de packaging et de déploiement (par ex. gnu tar, crane)
    • Je me demande s’il y a un avantage en termes de performances quand le nombre de couches est faible. Même si on fusionne les images, la taille totale reste la même, donc je comprends qu’il n’y a pas de gain particulier à fusionner les couches en soi
  • dive m’a été vraiment utile pour comprendre comment fonctionnent les images Docker et comment écrire un Dockerfile efficace
    Lire la documentation est important, mais voir directement comment la structure des couches change après avoir modifié le Dockerfile a été décisif pour ma compréhension

  • Dive est formidable. Ce genre d’outil est important pour apprendre exactement ce que je construis et déploie, et pour en être certain
    Dredge est aussi un outil qui vaut le détour, que j’utilise pour comparer les différences entre couches
    https://github.com/mthalman/dredge/blob/main/docs/commands/i...

  • C’est peut-être une question idiote, mais je me demande pourquoi la plupart des outils de conteneurs et d’infrastructure sont écrits en Go
    Je pense à Docker, Podman, nerdctl, Terraform et Kubernetes, et j’aimerais savoir si Go apporte des avantages particulièrement nets pour ce type d’outils

    • Je peux répondre pour Docker. Le premier prototype était écrit en Python, et l’entreprise était aussi très orientée Python
      La raison principale de la réécriture en Go était de profiter de la popularité croissante de Go à l’époque (2012). J’y étais
    • Go est le langage le plus simple pour la compilation croisée et le déploiement, avec un excellent rapport performance/productivité, une bonne concurrence native et de très bonnes capacités réseau dans la bibliothèque standard
      La différence saute aux yeux si on imagine Docker et Kubernetes écrits dans d’autres langages populaires
    • À mon avis, les outils système, utilitaires, outils en ligne de commande et logiciels réseau sont précisément les domaines où Go brille le plus
      La seule alternative moderne vraiment mature qui me vient à l’esprit est Rust
    • Kubernetes est écrit en Go parce que Google a créé Go, et a aussi créé Kubernetes
      Le fait qu’il y ait beaucoup d’ingénieurs Go dans les équipes internes vient de la même raison
    • Quand on exécute des conteneurs, on veut en général se soucier le moins possible du système sous-jacent, et Go facilite le fonctionnement dans son propre petit monde
      Il y a aussi un effet d’écosystème : on peut réutiliser directement des paquets d’autres implémentations dans certaines parties du code
  • J’aime Dive et je le sors de ma boîte à outils plusieurs fois par mois
    Je me demande simplement s’il existe un moyen d’afficher directement le contenu du fichier sélectionné. Souvent, après avoir vérifié qu’un fichier existe dans une couche, j’aimerais en inspecter le contenu ; aujourd’hui je lance généralement le conteneur pour utiliser cat, ou j’extrais le contenu puis je vais chercher dans les dossiers

    • Avec un peu d’astuce, on peut accéder au fichier avec rsync, mais ce n’est pas très différent d’utiliser cat
  • En étendant plusieurs conteneurs Docker publics, Dive m’a sauvé plus d’une fois pour disséquer ce qu’ils faisaient à l’intérieur
    C’est vraiment un logiciel de niveau A+

  • Il existe d’autres excellents outils TUI de terminal comme dive. Je pense à lazydocker et dry
    Il y en a aussi quelques-uns dans la catégorie Docker
    [0] https://terminaltrove.com/

    • Lazydocker a une fonction similaire, mais plus simple
      Je viens de vérifier : on peut voir les couches, mais il n’affiche que les commandes de chaque couche
  • Dive est un outil incroyable dans l’univers des conteneurs/Docker. Il rend le débogage de ce qu’il y a réellement dans un conteneur bien plus facile
    Quand nous avons lancé Depot [0], on nous demandait souvent comment réduire la taille des images et accélérer les builds, donc j’ai résumé dans un court billet [1] comment résoudre ce problème avec Dive. C’est peut-être un peu daté maintenant, mais ça peut encore aider quelqu’un
    Inspirés par Dive, nous avons aussi rendu beaucoup plus visible ce qu’il y a réellement dans le contexte de build à chaque build, et nous l’avons lancé comme fonctionnalité Depot il y a quelques semaines
    [0] https://depot.dev
    [1] https://depot.dev/blog/reducing-image-size-with-dive
    [2] https://depot.dev/blog/build-context

  • Au-delà de son utilité évidente, Dive a aussi un avantage sous-estimé. Son auteur est un excellent développeur et quelqu’un avec qui il est vraiment agréable de travailler

  • L’outil container-diff de Google est lui aussi très utile
    Je m’en sers pour voir ce que va réellement faire au système un script arbitraire qu’on recommande d’exécuter en le passant dans un pipe bash

    • C’est un peu moins lié aux utilitaires de conteneurs en général, mais j’utilise énormément GoogleContainerTools/container-structure-test
      C’est un moyen pratique d’exécuter des tests d’intégration sur une application ou une image de conteneur
      C’est dommage que beaucoup de ces projets open source de Google semblent avoir besoin d’attention, puisque nombre de leurs mainteneurs d’origine sont partis. J’essaie d’envoyer des PR quand je peux, et de fermer parfois quelques issues. Cet outil de test en particulier est extrêmement précieux pour garder la tête froide quand on gère en interne un grand nombre d’images de base à maintenir