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. voie]*

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

Comment créer automatiquement de petites images Docker pour vos besoins

Obsession inhabituelle

Au cours des derniers mois, j'ai été obsédé par la taille d'une image Docker et l'application est toujours en cours d'exécution ?

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

Avant d'entrer dans les détails et les aspects techniques, j'aimerais vous expliquer pourquoi ce problème m'a tant dérangé et en quoi il vous concerne.

Pourquoi la taille est importante

En réduisant le contenu de l'image Docker, nous réduisons ainsi la liste des vulnérabilités. De plus, nous rendons les images plus propres, car elles contiennent uniquement ce qui est nécessaire pour exécuter les applications.

Il y a encore un petit avantage : les images sont téléchargées un peu plus rapidement, mais, à mon avis, ce n'est pas si important.

Remarque : si vous êtes préoccupé par la taille, l'Alpine semble taille petite et vous conviendra certainement.

Images sans dispersion

Projet Distroless propose une sélection d'images de base « sans distribution », elles ne contiennent pas de gestionnaires de packages, de shells et d'autres utilitaires que vous avez l'habitude de voir sur la ligne de commande. Par conséquent, utilisez des gestionnaires de packages comme pip и apt ne fonctionnera pas:

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

Dockerfile utilisant une image sans distribution 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

Pip n'est pas dans l'image

Habituellement, ce problème est résolu par une construction 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 130 Mo. Pas mal! A titre de comparaison : l'image Python par défaut pèse 929 Mo, et celle « plus fine » (3,7-slim) - 179 Mo, image alpine (3,7-alpine) fait 98,6 Mo, tandis que l'image de base sans distribution utilisée dans l'exemple fait 50,9 Mo.

Il est juste de souligner que dans l'exemple précédent, nous copions un répertoire entier /usr/local/lib/python3.7/site-packages, qui peut contenir des dépendances dont nous n’avons pas besoin. Bien qu'il soit clair que la différence de taille de toutes les images de base Python existantes varie.

Au moment de la rédaction de cet article, Google distroless ne prend pas en charge beaucoup d'images : Java et Python sont encore au stade expérimental, et Python n'existe que pour les versions 2,7 et 3,5.

De petites images

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

En général, je voulais voir comment les images sans distribution sont construites. Le projet distroless utilise l'outil de construction de Google bazel. Cependant, installer Bazel et écrire vos propres images a demandé beaucoup de travail (et pour être honnête, réinventer la roue est amusant et éducatif). Je voulais simplifier la création d'images plus petites : l'acte de créer une image doit être extrêmement simple, banal. Pour qu'il n'y ait pas de fichiers de configuration à votre disposition, juste une ligne dans la console : просто собрать образ для <приложение>.

Donc, si vous souhaitez créer vos propres images, sachez : il existe une image Docker tellement unique, scratch. Scratch est une image « vide », elle ne contient aucun fichier, même si elle pèse par défaut - wow ! - 77 octets.

FROM scratch

Image à gratter

L'idée d'une image de travail est que vous pouvez y copier toutes les dépendances de la machine hôte et soit les utiliser dans un Dockerfile (c'est comme les copier dans apt et installer à partir de zéro), ou plus tard lorsque l'image Docker est matérialisée. Cela permet de contrôler totalement le contenu du conteneur Docker, et ainsi de contrôler totalement la taille de l'image.

Nous devons maintenant collecter ces dépendances d'une manière ou d'une autre. Des outils existants comme apt vous permettent de télécharger des packages, mais ils sont liés à la machine actuelle et, après tout, ne prennent pas en charge Windows ou MacOS.

J'ai donc décidé de créer mon propre outil qui créerait automatiquement une image de base de la plus petite taille possible et exécuterait également n'importe quelle application. J'ai utilisé des packages Ubuntu/Debian, effectué une sélection (obtention des packages directement à partir des référentiels) et trouvé de manière récursive leurs dépendances. Le programme était censé télécharger automatiquement la dernière version stable du package, minimisant autant que possible les risques de sécurité.

J'ai nommé l'outil fetchy, parce qu'il... trouve et apporte... ce dont il a besoin [de l'anglais "aller chercher", "apporter" - env. voie]. L'outil fonctionne via une interface de ligne de commande, mais propose en même temps une API.

Pour assembler une image en utilisant fetchy (prenons cette fois une image Python), il vous suffit d'utiliser la CLI comme ceci : fetchy dockerize python. Il se peut que l'on vous demande le système d'exploitation cible et le nom de code car fetchy utilise actuellement uniquement des packages basés sur Debian et Ubuntu.

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

résultats

Image Python créée à l'aide de la commande fetchy dockerize python3.5 ne pèse que 35 Mo (je suis plus que sûr qu'à l'avenir, il pourra être rendu encore plus léger). Il s'avère que nous avons réussi à supprimer 15 WW supplémentaires de l'image sans distribution.

Vous pouvez voir toutes les images collectées jusqu'à présent ici.

Projet - ici.

S'il vous manque des fonctionnalités, créez simplement une demande - je serai heureux de vous aider :) De plus, je travaille actuellement sur l'intégration d'autres gestionnaires de packages dans fetchy, afin qu'il n'y ait pas besoin de builds en plusieurs étapes.

Source: habr.com

Ajouter un commentaire