Comment créer un Dockerfile à partir d'une image existante

0
172

Les images Docker sont créées en créant des Dockerfiles. Le processus de construction exécute les instructions du Dockerfile pour créer les couches du système de fichiers qui forment l'image finale.

Et si vous avez déjà une image ? Pouvez-vous récupérer le Dockerfile à partir duquel il a été construit ? Dans cet article, nous examinerons deux méthodes permettant d'y parvenir.

L'objectif

Lorsque vous créez vos propres images Docker, vous devez stocker vos Dockerfiles en tant que fichiers contrôlés par version dans votre référentiel source. Cette pratique vous permet de toujours récupérer les instructions utilisées pour assembler vos images.

Parfois, vous n'aurez pas accès à un Dockerfile. Vous utilisez peut-être une image qui se trouve dans un registre public, mais dont le référentiel source est inaccessible. Ou vous pourriez travailler avec des instantanés d'images qui ne correspondent pas directement à un Dockerfile versionné. Dans ces cas, vous avez besoin d'une technique capable de créer un Dockerfile à partir d'une image sur votre machine.

Docker n'offre aucune fonctionnalité intégrée pour y parvenir. Les images construites n'ont pas d'association avec le Dockerfile à partir duquel elles ont été créées. Cependant, vous pouvez désosser le processus de construction pour produire une bonne approximation du Dockerfile d'une image à la demande.

La commande Docker History

La commande docker history révèle l'historique des calques d'une image. Il montre la commande utilisée pour construire chaque couche de système de fichiers successive, ce qui en fait un bon point de départ lors de la reproduction d'un Dockerfile.

Voici un Dockerfile simple pour une application Node.js :

nœud FROM :16 COPIER app.js . RUN app.js –init CMD [“app.js”]

Construire l'image en utilisant docker build :

$ docker build -t node-app:latest .

Inspectez maintenant l'historique des calques de l'image avec l'historique Docker :

$ docker history node-app:latest IMAGE CRÉÉE CRÉÉE PAR TAILLE COMMENTAIRE c06fc21a8eed Il y a 8 secondes /bin/sh -c #(nop) CMD [“app.js”] 0B 74d58e07103b Il y a 8 secondes /bin/sh -c ./app .js –init 0B 22ea63ef9389 Il y a 19 secondes /bin/sh -c #(nop) COPY file:0c0828d0765af4dd… 50B 424bc28f998d Il y a 4 jours /bin/sh -c #(nop) CMD [“nœud”] 0B &lt ;manquant> Il y a 4 jours /bin/sh -c #(nop) ENTRYPOINT [“docker-entry… 0B …

L'historique comprend la liste complète des calques de l'image, y compris ceux hérités de l'image de base node:16. Les calques sont classés de manière à ce que le plus récent soit le premier. Vous pouvez repérer où les couches créées par l'exemple Dockerfile commencent en fonction de l'heure de création. Celles-ci affichent la représentation interne de Docker des instructions COPY et CMD utilisées dans le Dockerfile.

La sortie de l'historique Docker est plus utile lorsque le tableau se limite à afficher chaque couche. la commande. Vous pouvez également désactiver la troncature pour afficher la commande complète associée à chaque couche :

$ docker history node-app:latest –format “{{.CreatedBy}}” –no-trunc /bin/sh -c #(nop) CMD [“app.js”] /bin/sh -c ./app.js –init /bin/sh -c #(nop) COPIER le fichier : 0c0828d0765af4dd87b893f355e5dff77d6932d452f5681dfb98fd9cf05e8eb1 dans . /bin/sh -c #(nop) CMD [“node”] /bin/sh -c #(nop) ENTRYPOINT [“docker-entrypoint.sh”] …

A partir de cette liste de commandes, vous pouvez avoir un aperçu des étapes suivies pour assembler l'image. Pour des images simples comme celle-ci, cela peut être une information suffisante pour reproduire avec précision un Dockerfile.

Automatisation de l'extraction de couches avec Whaler et Dfimage

Copier des commandes à partir de l'historique du menu fixe est un processus laborieux. Vous devez également supprimer le /bin/sh -c au début de chaque ligne, car Docker a traité chaque instruction comme un commentaire Bash sans opération.

Heureusement, il existe des outils communautaires disponibles qui peuvent automatiser la création de Dockerfile à partir de l'historique des calques d'une image. Pour les besoins de cet article, nous allons nous concentrer sur Whaler qui est intégré à l'image Docker alpine/dfimage (Dockerfile-from-Image) par l'organisation Alpine.

Exécution de l'image dfimage et fourniture une balise Docker produira un Dockerfile qui peut être utilisé pour reproduire l'image référencée. Vous devez lier le socket Docker de votre hôte au conteneur dfimage afin qu'il puisse accéder à votre liste d'images et extraire la balise si nécessaire.

$ docker run –rm -v /var/run/docker.sock:/var/run/docker.sock alpine/dfimage node-app:latest Analyse node-app:latest Version Docker : 20.10.13 GraphDriver : overlay2 Variables d'environnement |PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin |NODE_VERSION=16.14.2 |YARN_VERSION=1.22.18 Utilisateur de l'image |L'utilisateur est root Dockerfile : … ENTRYPOINT [“docker-entrypoint.sh”] CMD [“noeud”] COPIER le fichier : bcbc3d5784a8f1017653685866d30e230cae61d0da13dae32525b784383ac75f dans . app.js RUN ./app.js –init CMD [“app.js”]

Le Dockerfile créé contient tout ce dont vous avez besoin pour passer de zéro (un système de fichiers vide) à la couche finale de l'image spécifiée. Il comprend toutes les couches qui proviennent de l'image de base. Vous pouvez les voir dans les premières instructions ENTRYPOINT et CMD dans l'exemple de sortie ci-dessus (les autres calques d'image de base ont été omis par souci de brièveté).

À l'exception de COPY, les instructions spécifiques à notre image correspondent à ce qui était écrit dans le Dockerfile d'origine. Vous pouvez maintenant copier ces instructions dans un nouveau Dockerfile, soit en utilisant l'intégralité de la sortie dfimage, soit en ne prenant que la partie qui se rapporte à l'image finale. Cette dernière option n'est possible que si vous connaissez l'identité de l'image de base d'origine afin que vous puissiez ajouter une instruction FROM en haut du fichier.

Les limitations< /h2>

Dans de nombreux cas, dfimage pourra assembler un Dockerfile utilisable. Néanmoins, ce n'est pas parfait et une correspondance exacte n'est pas garantie. L'étendue des écarts par rapport au Dockerfile d'origine de l'image variera en fonction des instructions utilisées.

Toutes les instructions ne sont pas capturées dans l'historique des couches. Ceux qui ne sont pas pris en charge seront perdus et vous ne pourrez pas déterminer ce qu'ils étaient. La meilleure précision est obtenue avec des instructions de commande et de métadonnées telles que RUN, ENV, WORKDIR, ENTRYPOINT et CMD. Les instructions RUN peuvent toujours être manquantes si leur commande n'entraîne pas de modifications du système de fichiers, ce qui signifie qu'aucune nouvelle couche d'image n'a été créée.

Les instructions COPY et ADD présentent des défis uniques. L'historique ne contient pas le chemin du fichier hôte qui a été copié dans le conteneur. Vous pouvez voir qu'une copie s'est produite, mais le chemin source fait référence au hachage du fichier qui a été copié dans l'image à partir du contexte de construction.

Lorsque vous obtenez la destination finale, cela peut suffire à vous aider à déterminer ce qui a été copié et pourquoi. Vous pouvez ensuite utiliser ces informations pour interpoler un nouveau chemin source dans le Dockerfile que vous pourrez utiliser pour les futures versions. Dans d'autres cas, l'inspection du fichier à l'intérieur de l'image peut aider à révéler le but de la copie afin que vous puissiez déterminer un nom de fichier significatif pour le chemin de l'hôte.

Résumé

< p>Les images Docker n'incluent pas de moyen direct de revenir au Dockerfile à partir duquel elles ont été créées. Cependant, il est toujours possible de reconstituer le processus de construction. Pour les images simples avec peu d'instructions, vous pouvez souvent travailler les instructions manuellement en consultant la colonne CREATED BY dans la sortie de la commande docker history.

Les images plus grandes avec des processus de construction plus complexes sont mieux analysées par des outils comme dfimage. Cela fait le travail difficile d'analyser la sortie détaillée de l'historique Docker pour vous, produisant un nouveau Dockerfile qui correspond au mieux à l'original probable.

Les efforts d'ingénierie inverse ne sont pas parfaits et certains Les instructions Dockerfile sont perdues ou mutilées pendant le processus de construction. Par conséquent, vous ne devez pas supposer que les Dockerfiles créés de cette manière sont une représentation exacte de l'original. Vous devrez peut-être également apporter des ajustements manuels aux instructions ADD et COPY, en ressuscitant les chemins de fichiers hôtes qui ont été convertis en références de contexte de construction.

LIRE LA SUITE

  • › “Apportez votre propre conducteur vulnérable” Les attaques cassent Windows
  • &rsaquo ; Test du Google Pixel 6a : un excellent téléphone de milieu de gamme un peu court
  • &rsaquo ; Vous pouvez placer votre téléviseur à l'extérieur
  • &rsaquo ; 10 fonctionnalités Mac cachées que vous devriez utiliser
  • › 7 conseils pour empêcher votre technologie de surchauffer
  • &rsaquo ; 10 fonctionnalités Chromebook que vous devriez utiliser