De minuscules images Docker qui croyaient en elles-mêmes *

[référence au conte de fées américain pour enfants "Le petit moteur qui pourrait" - env. par.] *



Comment créer automatiquement de minuscules images de docker pour vos besoins


Obsession inhabituelle


Depuis quelques mois, je suis obsédé par une obsession: combien puis-je réduire l'image Docker pour que l'application fonctionne?


Je comprends que l'idée est étrange.


Avant de plonger dans les détails et les désastres techniques, je voudrais expliquer pourquoi ce problème m'a tellement accroché et comment il vous concerne.


Pourquoi la taille est importante


En raccourcissant le contenu de l'image Docker, nous raccourcissons la liste des vulnérabilités. De plus, nous rendons les images plus propres, car elles ne contiennent que ce dont vous avez besoin pour exécuter les applications.


Il y a un autre petit avantage - les images se téléchargent un peu plus vite, mais, pour moi, ce n'est pas si important.


Remarque: si vous vous souciez de la taille, les looks alpins sont petits en eux-mêmes et vous conviendront probablement.

Images sans distraction


Le projet Distroless propose une sélection d'images de base "sans distraction"; elles ne contiennent pas les gestionnaires de packages, les shells ou autres utilitaires que vous avez l'habitude de voir sur la ligne de commande. Par conséquent, l'utilisation de gestionnaires de packages comme pip et apt échouera:


 FROM gcr.io/distroless/python3 RUN pip3 install numpy 

Dockerfile utilisant une image sans distraction Python 3


 Sending build context to Docker daemon 2.048kB Step 1/2 : FROM gcr.io/distroless/python3 ---> 556d570d5c53 Step 2/2 : RUN pip3 install numpy ---> Running in dbfe5623f125 /bin/sh: 1: pip3: not found 

Pas de pip dans l'image


En règle générale, ce problème est résolu par une génération en plusieurs étapes:


 FROM python:3 as builder RUN pip3 install numpy FROM gcr.io/distroless/python3 COPY --from=builder /usr/local/lib/python3.7/site-packages /usr/local/lib/python3.5/ 

Assemblage en plusieurs étapes


Le résultat est une image de taille 130 Mo. Pas si mal! A titre de comparaison: l'image Python par défaut pèse 929 Mo et l'image «plus mince» ( 3,7-slim ) - 179 Mo, l'image alpine ( 3,7-alpine ) - 98,6 Mo, tandis que l'image sans distraction de base utilisée dans l'exemple est 50,9 Mo.


Nous pouvons à juste titre souligner que dans l'exemple précédent, nous copions tout le répertoire /usr/local/lib/python3.7/site-packages , qui peut contenir des dépendances inutiles pour nous. Bien qu'il soit clair que la différence de taille de toutes les images de base Python existantes varie.


Au moment d'écrire ces lignes, Google distroless ne prend pas en charge de nombreuses images: Java et Python sont encore au stade expérimental, et Python n'existe que pour 2.7 et 3.5.

De minuscules images


Revenons à mon obsession de créer de petites images.


En fait, je voulais voir comment fonctionnent les images sans distraction. Le projet sans distraction utilise l' bazel construction Google bazel. Cependant, pour installer Bazel et écrire vos propres images, j'ai dû transpirer (et pour être tout à fait honnête, réinventer la roue est amusant et instructif). Je voulais simplifier la création d'images réduites: l'acte de créer une image devait être extrêmement simple, banal . Pour ne pas avoir de fichiers de configuration, une seule ligne dans la console: il <> .


Donc, si vous voulez créer vos propres images, sachez: il y a une telle image unique de docker, scratch . Scratch est une image "vide", elle n'a pas de fichiers, bien qu'elle pèse par défaut - wow! - 77 octets.


 FROM scratch 

Scratch image


L'idée d'une image de travail est que vous pouvez y copier toutes les dépendances à partir de la machine hôte et les utiliser à l'intérieur du Dockerfile (c'est comment les copier dans apt et installer à partir de zéro), ou plus tard, lorsque l'image Docker est matérialisée. Cela vous permet de contrôler entièrement le contenu du conteneur Docker et, par conséquent, de contrôler complètement la taille de l'image.


Et maintenant, nous devons en quelque sorte collecter ces dépendances. Les outils existants comme apt vous permettent de télécharger des packages, mais ils sont liés à la machine actuelle et, au final, ne prennent pas en charge Windows ou MacOS.


Et j'ai donc entrepris d'assembler mon propre outil, qui assemblerait automatiquement l'image de base de la plus petite taille possible et de manière à pouvoir lancer n'importe quelle application. J'ai utilisé des paquets Ubuntu / Debian, fait une sélection (obtenir des paquets directement à partir des référentiels) et trouvé récursivement leurs dépendances. Le programme devrait télécharger automatiquement la dernière version stable du package, minimisant les risques de sécurité.


J'ai appelé l' fetchy , car il ... trouve et apporte ... ce dont vous avez besoin [ de l'anglais. "chercher", "apporter" - env. trans. ]. L'outil fonctionne via l'interface de ligne de commande, mais offre en même temps une API.


Afin de construire une image en utilisant fetchy (prenons une image Python cette fois), il vous suffit d'utiliser la CLI comme ceci: fetchy dockerize python . On peut vous demander le système d'exploitation cible et le nom de code, car fetchy n'utilise pour l'instant que des packages basés sur Debian et Ubuntu.


Vous pouvez maintenant choisir les dépendances qui ne sont pas du tout nécessaires (dans notre contexte) et les exclure. Par exemple, Python dépend de Perl, bien qu'il fonctionne très bien sans Perl installé.


Résultats


L'image Python créée avec la fetchy dockerize python3.5 ne pèse que 35 Mo (je suis plus que sûr qu'elle peut être encore plus facile à l'avenir). Il s'avère qu'avec une image sans distraction, nous avons réussi à «raser» 15 Mo supplémentaires.


Toutes les images actuellement collectées peuvent être consultées ici .


Le projet est ici .


Si vous n'avez pas assez de fonctions, créez simplement une application - je serai heureux de vous aider :) Encore plus, je travaille actuellement sur l'intégration d'autres gestionnaires de paquets dans fetchy, de sorte que le besoin de builds en plusieurs étapes n'est plus nécessaire.

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


All Articles