Nous avons le bloc suivant dans notre Dockerfile
:
RUN yum -y update
RUN yum -y install epel-release
RUN yum -y groupinstall "Development Tools"
RUN yum -y install python-pip git mysql-devel libxml2-devel libxslt-devel python-devel openldap-devel libffi-devel openssl-devel
On m'a dit que nous devrions unir ces RUN
commandes pour réduire les couches de docker créées:
RUN yum -y update \
&& yum -y install epel-release \
&& yum -y groupinstall "Development Tools" \
&& yum -y install python-pip git mysql-devel libxml2-devel libxslt-devel python-devel openldap-devel libffi-devel openssl-devel
Je suis très nouveau dans Docker et je ne suis pas sûr de bien comprendre les différences entre ces deux versions de spécification de plusieurs commandes RUN. Quand unirait-on des RUN
commandes en une seule et quand est-il logique d'avoir plusieurs RUN
commandes?
docker
dockerfile
alecxe
la source
la source
Réponses:
Une image Docker est en fait une liste liée de couches de système de fichiers. Chaque instruction dans un Dockerfile crée une couche de système de fichiers qui décrit les différences dans le système de fichiers avant et après l'exécution de l'instruction correspondante. La
docker inspect
sous-commande peut être utilisée sur une image Docker pour révéler sa nature d'être une liste liée de couches de système de fichiers.Le nombre de couches utilisées dans une image est important
Cela a plusieurs conséquences sur la façon dont les images doivent être construites. Le premier et le plus important conseil que je puisse donner est:
La raison en est que toutes les étapes précédentes seront mises en cache et que les couches correspondantes n'auront pas besoin d'être téléchargées encore et encore. Cela signifie des versions plus rapides et des versions plus rapides, ce qui est probablement ce que vous voulez. Chose intéressante, il est étonnamment difficile de faire un usage optimal du cache docker.
Mon deuxième conseil est moins important mais je le trouve très utile du point de vue de la maintenance:
Un Dockerfile suivant ce conseil ressemblerait à
etc. L'avis de lier plusieurs commandes avec
&&
n'a qu'une portée limitée. Il est beaucoup plus facile d'écrire avec des scripts, où vous pouvez utiliser des fonctions, etc. pour éviter la redondance ou à des fins de documentation.Les personnes intéressées par les pré-processeurs et désireuses d'éviter les petits frais généraux causés par les
COPY
étapes et génèrent en fait à la volée un Dockerfile où leles séquences sont remplacées par
où
…
est la version encodée en base64 deapt_setup.sh
.Mon troisième conseil s'adresse aux personnes qui souhaitent limiter la taille et le nombre de couches au prix possible de constructions plus longues.
Un fichier ajouté par une instruction docker et supprimé par une instruction ultérieure n'est pas présent dans le système de fichiers résultant mais il est mentionné deux fois dans les couches docker constituant l'image docker en construction. Une fois, avec le nom et le contenu complet dans la couche résultant de l'instruction qui l'ajoute, et une fois comme avis de suppression dans la couche résultant de la suppression de l'instruction.
Par exemple, supposons que nous ayons temporairement besoin d'un compilateur C et d'une image et considérons le
(Un exemple plus réaliste consisterait à construire des logiciels avec le compilateur au lieu de simplement affirmer sa présence avec l'
--version
indicateur.)L'extrait Dockerfile crée trois couches, la première contient la suite complète de gcc de sorte que même si elle n'est pas présente dans le système de fichiers final, les données correspondantes font toujours partie de l'image de la même manière et doivent être téléchargées, téléchargées et décompressées chaque fois que le l'image finale est.
Le
with
-idiom est une forme courante dans la programmation fonctionnelle pour isoler la propriété des ressources et la libération des ressources de la logique l'utilisant. Il est facile de transposer cet idiome en script shell, et nous pouvons reformuler les commandes précédentes comme le script suivant, à utiliser avecCOPY & RUN
comme dans le conseil # 2.Les commandes complexes peuvent être transformées en fonction afin de pouvoir être introduites dans le
with_c_compiler
. Il est également possible de chaîner les appels de plusieurswith_whatever
fonctions, mais ce n'est peut-être pas très souhaitable. (En utilisant des fonctionnalités plus ésotériques du shell, il est certainement possible de fairewith_c_compiler
accepter des commandes complexes, mais il est préférable à tous égards d'envelopper ces commandes complexes dans des fonctions.)Si nous voulons ignorer le conseil n ° 2, l'extrait de Dockerfile résultant serait
ce qui n'est pas si facile à lire et à entretenir à cause de l'obscurcissement. Voyez comment la variante shell-script met l'accent sur la partie importante
gcc --version
tandis que la&&
variante enchaînée enterre cette partie au milieu du bruit.la source
Chaque instruction que vous créez dans votre Dockerfile entraîne la création d'un nouveau calque d'image. Chaque couche apporte des données supplémentaires qui ne font pas toujours partie de l'image résultante. Par exemple, si vous ajoutez un fichier dans un calque, mais que vous le supprimez dans un autre calque plus tard, la taille de l'image finale inclura la taille de fichier ajoutée sous la forme d'un fichier spécial "blanc" bien que vous l'ayez supprimé.
Disons que vous disposez du Dockerfile suivant:
La taille d'image résultante sera
Comme ci-contre, avec Dockerfile "similaire":
La taille d'image résultante sera
Vous obtiendrez une taille encore plus petite si vous nettoyez le cache yum dans une seule instruction RUN.
Vous voulez donc garder un équilibre entre lisibilité / facilité d'entretien et nombre de couches / taille d'image.
la source
Les
RUN
instructions représentent chaque couche. Imaginez que l'on télécharge un package, l'installe et souhaite le supprimer. Si l'on utilise troisRUN
instructions, la taille de l'image ne diminuera pas car il existe des calques séparés. Si l'on exécute toutes les commandes à l'aide d'une seuleRUN
instruction, la taille de l'image disque pourrait être réduite.la source