Exploration de Docker, partie 4: réduction de la taille des images et accélération de leur assemblage

Dans cette partie de la traduction de la série Docker, nous parlerons de la façon d'optimiser les tailles d'image et d'accélérer l'assemblage. Dans les documents précédents, nous avons comparé les images Docker avec de la pizza, les termes avec des beignets et les instructions Dockerfile avec des bagels. Aujourd'hui, il n'y aura pas de cuisson. Il est temps de suivre un régime.

Partie 1: les bases
Partie 2: termes et concepts
Partie 3: Fichiers Dockerfile
Partie 4: réduire la taille des images et accélérer leur assemblage
Partie 5: équipes
Partie 6: travailler avec des données


Afin de comprendre de quoi nous allons parler ici, il vous sera utile de rafraîchir la mémoire de ce qui a été discuté dans la troisième partie de cette série de documents. À savoir, nous avons parlé des instructions sur les fichiers Dockerfile. Connaître ces instructions et les fonctionnalités de Docker dont nous discutons aujourd'hui vous aidera à optimiser les fichiers image Docker.

Mise en cache


L'une des forces de Docker est la mise en cache. Grâce à ce mécanisme, l'assemblage des images est accéléré.

Lors de l'assemblage d'une image Docker, il suit les instructions du Dockerfile, en les suivant dans l'ordre. Dans le processus d'analyse des instructions, Docker vérifie son propre cache pour les images, ce que nous obtenons aux étapes intermédiaires de l'assemblage d'autres images. Si de telles images peuvent être trouvées, le système peut les utiliser sans perdre de temps à les recréer.

Si le cache est invalidé, l'instruction pendant laquelle il s'est produit s'exécute, créant une nouvelle couche sans utiliser le cache. La même chose se produit lors de l'exécution des instructions qui la suivent.

Par conséquent, si lors de l'exécution des instructions du Dockerfile, il s'avère que l'image de base est dans le cache, alors cette image du cache est utilisée. C'est ce qu'on appelle un accès au cache. Si l'image de base n'est pas dans le cache, alors tout le processus d'assemblage d'images se déroulera sans utiliser le cache.

Ensuite, l'instruction suivante est comparée à toutes les images du cache, qui sont basées sur la même image de base qui se trouve déjà dans le cache. Chaque image intermédiaire mise en cache est vérifiée pour voir si elle contient ce qui a été créé par la même instruction. Si aucune correspondance ne peut être trouvée, cela s'appelle un «échec de cache» et le cache est considéré comme invalide. La même chose se produit jusqu'à ce que le Dockerfile entier soit traité.

La plupart des nouvelles instructions sont simplement comparées à celles déjà présentes dans les images intermédiaires. Si le système parvient à trouver une correspondance, l'assembly utilise ce qui se trouve déjà dans le cache.

L'utilisation d'un cache peut accélérer l'assemblage d'images, mais il y a un problème. Par exemple, si une instruction RUN pip install -r requirements.txt se trouve dans le Dockerfile, Docker recherche la même instruction dans son cache local d'images intermédiaires. Toutefois, le contenu des anciennes et nouvelles versions du fichier requirements.txt n'est pas comparé.

Cela peut entraîner des problèmes si des informations sur les nouveaux packages ont été ajoutées à requirements.txt , après quoi, lors de la création de l'image mise à jour, pour installer un nouvel ensemble de packages, vous devez exécuter à nouveau l'instruction d' RUN pip install . Nous parlerons bientôt de la façon de traiter ce problème.

Contrairement à d'autres instructions Docker, lors de l'exécution des instructions ADD et COPY , Docker doit vérifier le contenu du ou des fichiers pour déterminer s'il est possible d'utiliser le cache lors de la création de l'image. A savoir, la somme de contrôle des fichiers mentionnés dans ces instructions est comparée à la somme de contrôle des fichiers qui se trouvent dans les images intermédiaires qui sont déjà dans le cache. Si le contenu des fichiers ou leurs métadonnées a changé, le cache est invalidé.

Voici quelques conseils pour tirer parti du cache Docker:

  • La mise en cache peut être désactivée en passant le commutateur --no-cache=True à la docker build .
  • Si vous souhaitez apporter des modifications aux instructions Dockerfile, chaque couche créée par les instructions venant après celles modifiées sera réassemblée assez souvent, sans utiliser de cache. Pour tirer parti de la mise en cache, placez les instructions susceptibles de changer le plus près possible de la fin du Dockerfile.
  • Combinez les commandes RUN apt-get update et apt-get install en chaînes pour éviter les problèmes associés à une mauvaise utilisation du cache.
  • Si vous utilisez des gestionnaires de packages, comme pip , avec le fichier requirements.txt , respectez le schéma ci-dessous pour exclure l'utilisation d'images intermédiaires obsolètes du cache contenant l'ensemble des packages répertoriés dans l'ancienne version du fichier requirements.txt . Voici à quoi ça ressemble:

     COPY requirements.txt /tmp/ RUN pip install -r /tmp/requirements.txt COPY . /tmp/ 

Si vous connaissez d'autres façons de traiter le «problème requirements.txt», vous pouvez en parler dans les commentaires.

Réduire la taille des images


▍ Sélection rigoureuse de l'image de base


Les images Docker peuvent être assez volumineuses. Cela contredit le désir bien fondé de la personne qui les crée de les rendre aussi compacts que possible, ce qui facilitera leur téléchargement à partir d'un référentiel distant et aura un effet bénéfique sur la quantité d'espace libre sur l'ordinateur sur lequel ils sont chargés. Parlons de la façon de réduire leur taille.


Au lieu de bagels et beignets, nous allons maintenant manger des verts

Une façon de réduire la taille des images est de sélectionner soigneusement les images de base et leur réglage ultérieur.

Par exemple, l'image Alpine de base est une distribution complète d'un système d'exploitation de type Linux, contenant un minimum de packages supplémentaires. Sa taille est d'environ 5 mégaoctets. Cependant, la construction de votre propre image basée sur Alpine nécessitera beaucoup de temps pour l'équiper de tout le nécessaire pour assurer le fonctionnement d'une certaine application.

Il existe également des versions spécialisées de l'image alpine de base. Par exemple, l'image correspondante du référentiel python dans laquelle le script print("hello world") est conditionné pèse environ 78,5 Mo. Voici le Dockerfile pour construire une telle image:

 FROM python:3.7.2-alpine3.8 COPY . /app ENTRYPOINT ["python", "./app/my_script.py", "my_var"] 

Dans le même temps, le Docker Hub indique que cette image de base a une taille de 29 Mo. La taille d'une image basée sur cette image de base est augmentée en téléchargeant et en installant Python.

En plus d'utiliser des images de base basées sur Alpine, vous pouvez réduire la taille des images grâce à l'utilisation de la technologie d'assemblage en plusieurs étapes.

▍ Assemblage d'images en plusieurs étapes


Le Dockerfile, qui décrit l'assemblage en plusieurs étapes d'une image, utilise plusieurs instructions FROM . Le créateur d'une telle image peut configurer la copie sélective de fichiers appelés artefacts de génération d'un niveau de génération à un autre. En même temps, il devient possible de se débarrasser de tout ce qui n'est pas nécessaire dans l'image finie. Grâce à cette méthode, vous pouvez réduire la taille de l'image finie.

Voici comment fonctionne chaque instruction FROM :

  • Elle commence une nouvelle étape de construction.
  • Cela ne dépend pas de ce qui a été créé à l'étape de génération précédente.
  • Elle peut utiliser une image de base différente de celle utilisée à l'étape précédente.

Voici un exemple modifié d'un Dockerfile de la documentation Docker décrivant une construction en plusieurs étapes.

 FROM golang:1.7.3 AS build WORKDIR /go/src/github.com/alexellis/href-counter/ RUN go get -d -v golang.org/x/net/html COPY app.go . RUN CGO_ENABLED=0 GOOS=linux go build -a -installsuffix cgo -o app . FROM alpine:latest RUN apk --no-cache add ca-certificates WORKDIR /root/ COPY --from=build /go/src/github.com/alexellis/href-counter/app . CMD ["./app"] 

Veuillez noter que nous avons donné le nom de la première étape de l'assemblage, en le spécifiant après la déclaration FROM . Nous nous référons à la phase de construction nommée dans l' COPY --from= ci-dessous dans le Dockerfile.

L'utilisation du processus d'assemblage d'images en plusieurs étapes est logique dans certains cas lorsque vous devez créer de nombreux conteneurs pour l'environnement de production. L'assemblage en plusieurs étapes vous permet de minimiser la taille de l'image finie. Mais parfois cette approche complique le support des images. Par conséquent, vous n'utiliserez probablement pas d'assemblage d'images en plusieurs étapes dans les cas où vous pouvez vous en passer. Vous pouvez découvrir les caractéristiques de cette technologie ici et ici .

Comme vous pouvez le voir, l'assemblage en plusieurs étapes est une technologie intéressante, mais elle ne convient pas à tous les cas. La même manière de réduire la taille des images, dont nous parlerons ci-dessous, peut être recommandée à tout le monde.

▍ Fichier .dockerignore


Absolument tous ceux qui veulent apprendre Docker doivent connaître les fichiers .dockerignore . Ces fichiers sont similaires aux fichiers .gitignore . Ils contiennent une liste de fichiers et de dossiers, sous forme de noms ou de modèles que Docker doit ignorer lors de l'assemblage d'images.

Ce fichier est placé à l'emplacement du Dockerfile et de tout le reste inclus dans le contexte de l'assemblage d'image.

Lorsque vous exécutez la docker build , qui lance l'assemblage de l'image, Docker vérifie la présence du fichier .dockerignore dans le dossier. Si un tel fichier peut être trouvé, ce fichier est analysé et les règles de la fonction Match() du package filepath Go et certaines de ses propres règles Docker sont utilisées pour déterminer la liste des fichiers à ignorer.

Ainsi, par exemple, si un modèle de la forme *.jpg trouvé dans le fichier .dockerignore , alors lors de la création d'une image, les fichiers avec n'importe quel nom et avec l'extension .jpg seront ignorés. Si la chaîne videos dans le fichier, le système ignorera le dossier videos et tout son contenu.

Lors de la compilation d'un fichier .dockerignore , vous pouvez le commenter à l'aide du symbole # .

Voici ce que le fichier .dockerignore donne à quiconque crée des images Docker:

  • Cela vous permet d'exclure des fichiers image contenant des informations sensibles comme les connexions et les mots de passe.
  • Cela vous permet de réduire la taille de l'image. Plus les fichiers de l'image sont petits, plus sa taille sera petite et plus il sera rapide de travailler avec elle.
  • Cela permet de réduire le nombre de raisons d'invalider le cache lors de l'assemblage d'images similaires. Par exemple, si pendant le réassemblage de l'image certains fichiers de service du projet changent, comme les fichiers journaux, en raison desquels les données stockées dans le cache sont, par essence, déraisonnablement invalides, cela ralentit l'assemblage des images.

.dockerignore pouvez en savoir plus sur le fichier .dockerignore dans la documentation Docker.

Recherche sur la taille de l'image


Voyons comment utiliser les outils de ligne de commande pour connaître les tailles d'images et de conteneurs Docker.

  • Pour connaître la taille approximative d'un conteneur en cours d'exécution, vous pouvez utiliser une commande du formulaire docker container ls -s .
  • La docker image ls affiche docker image ls tailles d' docker image ls .
  • Vous pouvez utiliser la commande docker image history my_image:my_tag connaître les tailles d'images intermédiaires à partir desquelles une certaine image est assemblée.
  • La commande docker image inspect my_image:tag vous permet de trouver des informations détaillées sur l'image, y compris la taille de chacun de ses calques. Les calques sont légèrement différents des images intermédiaires qui composent l'image finie, mais, dans la plupart des cas, ils peuvent être considérés comme des entités identiques. Voici du bon matériel sur les détails de la structure interne des images Docker.
  • Afin d'examiner le contenu des conteneurs, vous pouvez installer le package de plongée .

Maintenant que nous avons discuté des possibilités de réduire la taille des images, j'attire votre attention sur huit recommandations concernant la réduction de la taille des images et l'accélération du processus d'assemblage.

Recommandations pour réduire la taille des images et accélérer le processus d'assemblage


  1. Dans la mesure du possible, utilisez des images officielles comme images de base. Les images officielles sont régulièrement mises à jour, elles sont plus sûres que les images informelles.
  2. Afin de collecter des images aussi compactes que possible, utilisez des images de base basées sur Alpine Linux.
  3. Si vous utilisez apt , combinez les commandes apt-get update et apt-get install dans une seule instruction RUN . De plus, combinez les commandes d'installation des packages en une seule instruction. Liste les packages par ordre alphabétique sur plusieurs lignes, en séparant la liste par \ . Par exemple, cela pourrait ressembler à ceci:

     RUN apt-get update && apt-get install -y \   package-one \   package-two \   package-three && rm -rf /var/lib/apt/lists/* 

    Cette méthode réduit le nombre de couches à ajouter à l'image et permet de conserver le code du fichier sous une forme décente.
  4. Incluez une construction comme && rm -rf /var/lib/apt/lists/* à la fin de l'instruction RUN utilisée pour installer les packages. Cela apt cache apt et entraînera qu'il ne sera pas enregistré dans la couche formée par la commande RUN . Des détails à ce sujet peuvent être trouvés dans la documentation .
  5. Utilisez judicieusement vos capacités de mise en cache en plaçant dans le Dockerfile des commandes susceptibles de changer vers la fin du fichier.
  6. Utilisez le fichier .dockerignore .
  7. Jetez un œil à la dive , un excellent outil pour explorer les images Docker qui aide à réduire leur taille.
  8. N'installez pas de paquets dont vous pouvez vous passer.

Résumé


Vous savez maintenant comment assembler rapidement les images Docker, les charger rapidement à partir des référentiels et ne pas occuper trop d'espace informatique. La prochaine fois, nous parlerons des équipes Docker.

Chers lecteurs! Avez-vous rencontré des problèmes avec les mécanismes de mise en cache lors de la création d'images Docker?

Source: https://habr.com/ru/post/fr440658/


All Articles