Alpine ou comment faire une image Docker très légère

01/02/2016

Puisque ces temps-ci je met à profit mes compétences CoreOS/Docker de manière plus soutenue, je me suis dit que quelques articles sur mon blog pour partager quelques astuces pourrait être de bon allois (t’as vu !). Alors aujourd’hui, je vais parler de Alpine, une distribution pour conteneur très légère et pourtant très fournie.

L’un des soucis majeurs avec Docker c’est bien l’espace nécessaire pour une image. Certes, le fait de partir d’une même image de base (debian, fedora, centos…) ne va pas dupliquer l’espace (parce que Docker utilise un système d’union fs) mais tout de même… Quand on se retrouve à vouloir fournir une image qui contient un seul binaire de 1 ou 2 Mo, on a une image de 100Mo voir 200Mo à fournir. Et j’exagère à peine.

L’idée est donc de réduire un maximum l’espace nécessaire. Il y a, en premier lieu, des astuces simples à connaitre:

  • tenter de faire un maximum de chose en une seule commande “RUN”
  • supprimer les fichiers inutiles (cache apt, yum…) très rapidement et surtout dans la commande qui génère ces fichiers; par exemple, supprimer le cache et faire un “autoremove” juste après un “apt-get install” ou un “dnf install”

Mais quoiqu’il arrive, une distribution “commune” telle que debian, fedora, centos, etc. ont la facheuse tendance à installer, de base, pas mal d’outils inutiles dans une image Docker. Ce n’est pas de leur faute, loin de là, elle ne sont juste pas optimisée pour ça. Ces fichiers sont présents parce que ces distributions sont faite pour “booter” sur une machine (virtuelle ou physique).

Busybox - la base

Il existe deux distributions (si on peut les appeler comme ça) faites pour de l’embarqué et les images Docker. La première est très légère: busybox. Cette distribution embarque réellement le strict minimum et, à moins que vous ne vouliez embarquer que des binaire statiquement compilés ou ne l’utiliser que pour faire un conteneur “data only”, elle ne vous sera pas très utile. Personnellement je m’en sers pour des outils développés en Go qui n’ont pas besoin d’enregistrement libc particulier, donc sitôt que je fais un binaire qui utilise du réseau, je me retrouve avec un binaire qui ne veut pas s’exécuter sur busybox.

Heureusement pour moi, une autre distribution embarquée existe, basée sur busybox.

Alpine - la solution

Alpine est une distribution qui n’occupe que quelques megaoctets (4 Mo). La différence entre busybox et celle-ci est que Alpine propose un gestionnaire de paquet qui, en plus, propose pas mal d’outils paquagés, allant de Mysql et Mongo à Nginx en passant par Java, Go et Python.

L’outil se nomme “apk” et il est assez simple à utiliser. Tentons l’expérience.

$ docker run --rm -it alpine sh

/ # python
sh: python: not found

/ # apk add --update python
... 
OK: 51 MiB in 21 packages

/ # python
Python 2.7.11 (default, Jan 23 2016, 12:34:14) 
[GCC 5.3.0] on linux2
Type "help", "copyright", "credits" or "license" for more information.

L’option “--update” permet de ne pas passer par deux commandes “alpine update; alpine add python”.

Donc, dans un Dockerfile, on aura le loisir d’installer des outils et de les supprimer si nécessaire.

Par exemple, si je veux compiler un binaire de mon projet Go, je n’ai qu’à faire:

  • deposer mes sources dans l’image
  • installer go
  • compiler mes sources
  • déplaccer le ou les binaires dans /usr/bin/
  • supprimer go (puisque j’ai compilé mes binaires)

Voilà un exemple:

FROM alpine:latest
MAINTAINER Patrice FERLET <metal3d@gmail.com>

ADD src/ /opt/src

RUN set -xe;                \
    apk add --update go     \
    cd /opt/src;            \
    go build;               \
    mv macommande /usr/bin; \
    cd /; rm -rf /opt/src;  \
    apk del --purge go;     \
    rm -rf /var/cache/apk/* 

CMD macommande

Pour résumer, après compilation, je supprime mes sources (inutile en fait puisque le layer précédent utilis ADD et que les sources sont donc préservées) puis je supprime “go” (en purgant si nécessaire) et je vire le cache “apk” qui n’a plus d’utilité.

Et le tout se fait en une commande RUN afin de ne pas avoir un layer chargé de fichiers qui seraient préservés. Donc, le principe est finalement le même qu’avec n’importe quel autre gestionnaire de paquet.

Par contre, la taille de mon image passe de 120Mo avec une Debian, à 10Mo avec Alpine.

Bilan

Voilà pour ce premier petit article parlant de Alpine. Le prochain va vous présenter CoreOS et quelques méthodes de balancing automatique. Pour l’heure, pensez à Alpine si vous voulez créer des images Docker rapidement, allégée, et ce pour des service NodeJS, Go, Java, PHP, Ruby… car le dépot apk est bien fourni

Ça peut vous intéresser aussi


Docker, Xvfb et links

Un conteneur = un service, c’est une règle qui ...


Rendre homogène une équipe de dev avec docker et docker-compose

Quand on veut bosser avec Docker sur des projets plus ...


docker - arrêtez d'utiliser des conteneurs data-only

Le voilà le titre racoleur. Et en le lisant vous ...


Docker Apache Mysql PHP

Ce matin un collègue me demande “comment tu ferais ...

Merci de m'aider à financer mes services

Si vous avez apprécié cet article, je vous serai reconnaissant de m'aider à me payer une petite bière :)

Si vous voulez en savoir plus sur l'utilisation de flattr sur mon blog, lisez cette page: Ayez pitié de moi

Commentaires

Ajouter un commentaire

Metal3d - 24/02/2016

@Jekester merci, je note ! et je vais tester :)

Ajouter un commentaire

(*) Votre e-mail ne sera ni revendu, ni rendu public, ni utilisé pour vous proposer des mails commerciaux. Il n'est utilisé que pour vous contacter en cas de souci avec le contenu du commentaire, ou pour vous prévenir d'un nouveau commentaire si vous avez coché la case prévue à cet effet.