Les formats d’image de conteneur sous le capot
Agata Krajewska
18 novembre 2020
0 minutes de lectureDepuis la sortie de Docker, ces dernières années, les conteneurs sont devenus un mécanisme de plus en plus standard pour la distribution des logiciels.
Nous voyons apparaître un nombre croissant de solutions basées sur les conteneurs. Si l’innovation dans ce domaine est évidemment bienvenue, il est nécessaire d’établir certaines normes concernant le format et le runtime.
Compte tenu de la croissance rapide du projet Docker, les images Docker sont devenues une norme pour de nombreux usages. Mais il existe un intérêt largement partagé pour une spécification de conteneur unique et ouverte, qui soit :
indépendante des constructions de plus haut niveau, comme un client ou une pile d’orchestration spécifique,
sans lien étroit avec un fournisseur commercial ou un projet en particulier,
portable sur un large éventail de systèmes d’exploitation, de matériels, d’architectures de processeur, de clouds publics, etc.
OCI (Open Container Initiative) est un projet de la Linux Foundation visant à concevoir des normes ouvertes pour la virtualisation au niveau du système d’exploitation, et en particulier pour les conteneurs Linux.
Divers outils de compilation open source prennent désormais en charge le format d’image OCI, notamment :
BuildKit : une réécriture optimisée du moteur de compilation de Docker
Podman : une implémentation alternative de l’outil en ligne de commande de Docker
Buildah : une alternative en ligne de commande à l’écriture de Dockerfiles
Snyk prend en charge tous les formats d’image de conteneur courants. Nous pouvons ainsi nous intégrer à un large éventail d’outils de l’écosystème. Dans cet article, nous allons en présenter quelques-uns et vous montrer comment Snyk fonctionne avec eux !
Archive Docker
Commençons par examiner le format d’archive Docker. Il fait partie de la version 1, désormais obsolète, de la spécification des images Docker. Vous trouverez la spécification complète ici. Lorsque vous exécutez docker save, il s’agit du format par défaut généré par le client Docker, utilisé pour assurer la rétrocompatibilité avec d’autres outils. Les registres de conteneurs utilisent un format plus récent pour stocker les images.
Si vous utilisez Docker en local avec l’interface de ligne de commande Snyk ou l’une de nos intégrations de conteneurs, nous utiliserons votre instance Docker locale pour extraire l’image, l’enregistrer sur le système de fichiers et lancer l’analyse.
Voyons à quoi ressemble cette archive et ce qu’elle contient d’intéressant pour Snyk !
Dans cet article, j’utiliserai l’image ubuntu:bionic. Commençons par enregistrer l’archive dans votre système de fichiers local :
docker save --output ubuntu-docker.tar ubuntu:bionic
La distribution bionic comporte trois couches d’image, que nous allons examiner de plus près.
Après avoir décompressé l’archive tar, nous pouvons en examiner le contenu :
Examinons le fichier manifest.json :
Ce fichier nous renvoie à la configuration du conteneur, où nous trouvons des informations très utiles, comme l’architecture, la configuration, les couches du système de fichiers racine, etc. Du point de vue de Snyk, l’élément le plus intéressant est sans doute la propriété Layers : elle pointe vers les couches réelles de l’image, qui ne sont que des répertoires dans l’archive. Si nous accédons à l’un de ces répertoires, nous pouvons voir ce qu’il contient :
Allons un peu plus loin et décompressons le fichier layer.tar :
Comme vous pouvez le voir ci-dessus, le fichier layer.tar contient simplement les modifications apportées au système de fichiers pour la couche d’image, avec toutes les dépendances et autres binaires, selon le contenu de l’image. Après avoir extrait et analysé le contenu
de ces couches, nous pouvons vous présenter la liste des chemins vulnérables.
Testons maintenant l’image d’archive Docker enregistrée avec snyk test. Pour tester une archive locale, indiquez le préfixe docker-archive: :
snyk container test docker-archive:ubuntu-docker.tar ou analysez l’image depuis votre dépôt Docker local :
snyk container test ubuntu:bionic
Les deux commandes produiront exactement le même résultat :
Image OCI
Au cours des derniers mois, nous avons également ajouté l’analyse des archives OCI aux fonctionnalités de l’interface de ligne de commande Snyk.
Examinons maintenant la spécification pour voir ce que contient l’archive ! Pour cette section, j’utiliserai également ubuntu:bionic.
Si vous souhaitez examiner vous-même une archive OCI au format tar, vous pouvez exécuter la commande suivante :
skopeo copy --override-os linux docker://ubuntu:bionic oci-archive:ubuntu.tar
J’utilise Skopeo ici pour enregistrer l’image. Cet outil cli facilite grandement diverses opérations sur les images.
Pour enregistrer une image ubuntu au format OCI, il suffit d’indiquer le préfixe oci-archive: pour la sortie tar.
Remarquez que j’utilise également l’option --override-os : c’est parce que je suis sur macOS et que les images Ubuntu de Docker Hub officielles ne sont disponibles que pour Linux. Nous parlerons également plus bas des images compatibles avec plusieurs architectures.
Une fois l’archive tar décompressée, nous pouvons en examiner le contenu :
Un fichier index.json intéressant se trouve à la racine. Examinons son contenu :
Il s’agit de notre manifeste de plus haut niveau (facultatif), qui nous oriente vers des manifestes d’image spécifiques. Il contient des informations sur un ensemble d’images pouvant couvrir plusieurs architectures et systèmes d’exploitation. Pour en savoir plus, consultez la spécification complète.
Examinons maintenant le manifeste propre à notre image, vers lequel index.json nous a orientés, dans le répertoire blobs/sha256 :
Nous commençons à voir des éléments intéressants, comme la configuration du conteneur, qui contient de nombreuses informations utiles sur l’architecture de l’image, les couches de l’image de base, la configuration, etc. Nous disposons également des informations sur les couches de l’image, qui pointent vers les couches disponibles dans notre image ubuntu:bionic.
Comme vous pouvez le voir ci-dessous, le contenu de la première couche est exactement le même que celui de l’archive Docker présentée plus haut.
Vous pouvez analyser votre archive OCI locale en exécutant :
snyk container test oci-archive:ubuntu.tar
Différentes plateformes et architectures
En examinant les manifestes d’archive Docker et d’image OCI, nous avons remarqué qu’ils contenaient tous deux des informations sur l’architecture. Revenons au contenu du manifeste de configuration de notre conteneur, dans le répertoire ubuntu-docker, où nous avons enregistré notre docker archive :
Parmi les autres informations, nous voyons l’architecture et le système d’exploitation, qui sont dans mon cas amd64 et linux. Qu’en est-il si notre image repose sur arm64 ou si nous utilisons la plateforme windows ?
Bonne nouvelle : Snyk prend également en charge d’autres plateformes. Il suffit de transmettre l’option -—platform à l’interface de ligne de commande Snyk.
Nous avons parlé du format d’archive docker save. Examinons maintenant le format v2 dans lequel les images sont stockées sur Docker Hub, qui recèle des aspects très intéressants. Il s’agit de la deuxième version du schéma v2, créée pour répondre à deux objectifs principaux. Selon la documentation Docker :
Le premier objectif est de permettre les images multi-architectures grâce à un « manifeste universel » qui référence les manifestes d’image des versions conçues pour des plateformes spécifiques. Le second est de faire évoluer le moteur Docker vers des images adressables par leur contenu, en prenant en charge un modèle d’image où la configuration de l’image peut être hachée pour générer un identifiant.
Avec notre instance Docker locale, nous pouvons d’abord examiner le « manifeste universel » de l’image qui nous intéresse afin de vérifier quelles variantes de plateforme sont disponibles. Comme expliqué ci-dessus, cela signifie qu’un même dépôt peut héberger plusieurs images pour différentes architectures.
docker manifest inspect ubuntu:bionic
Nous obtenons ainsi un tableau de manifestes :
Maintenant que nous avons établi que l’image ubuntu existe pour différentes plateformes, voyons comment analyser l’image ubuntu pour l’architecture de plateforme arm64.
Assurez-vous que les fonctionnalités expérimentales sont activées dans Docker sur votre hôte, puis exécutez :
snyk container test --platform=linux/arm64 ubuntu:bionic
Examinons le résultat :
Nous pouvons voir tous les chemins vulnérables détectés, ainsi que les informations de « Platform » dans le résultat de notre analyse.
Dans cet article, nous avons exploré les deux principaux formats d’image de conteneur, Docker et OCI, et montré comment Snyk peut interagir avec les deux, y compris sur plusieurs architectures.
Pour conclure, découvrez les bonnes pratiques de sécurité pour créer des images Docker optimales destinées aux applications Node.js et Java :
10 bonnes pratiques de sécurité pour Docker — découvrez les pratiques de sécurité à suivre lors de la création d’images Docker de base et de leur téléchargement, ainsi que la confiance dans le contenu Docker.
Vous développez en Java ? Cette ressource vous sera utile : Docker pour les développeurs Java : 5 choses à savoir pour ne pas compromettre votre sécurité
10 bonnes pratiques pour conteneuriser des applications web Node.js avec Docker - Si vous développez en Node.js, vous allez adorer ce guide détaillé qui vous montre comment créer des images Docker de base sécurisées et performantes pour vos applications Node.js.
Toutes ces fonctionnalités sont disponibles gratuitement dans Snyk — inscrivez-vous pour créer un compte.
Lancez-vous dans les compétitions Capture The Flag
Apprenez à résoudre des défis Capture The Flag en regardant à la demande notre atelier virtuel d’initiation.



