Image VS Conteneur
Avant de rentrer dans le vif du sujet, quelques éléments de vocabulaire qui vont nous aider à nous y retrouver
Fondamental : Image Docker
Une image Docker est un ensemble de fichiers constituant une application. Cette collection comprend l'application elle-même, ainsi que toutes les bibliothèques (libraries), les fichiers binaires et d'autres dépendances, telles que les fichiers de configurations, nécessaires à l'exécution de l'application.
Lorsque l'on construit une nouvelle image, on se rend compte que tous les fichiers contenus dans l'image Docker sont en lecture seule et par conséquent, le contenu de l'image ne peut pas être modifié. Si vous choisissez de modifier le contenu de votre image, la seule option permise par Docker est d'ajouter une autre couche (un layer) avec les nouvelles modifications. En d'autres termes, une image Docker est composée layers que vous pouvez réviser. La commande docker history,
permet de lister tous ces layers et de savoir ce qu'ils contiennent.
~ docker history mon-conteneur
IMAGE CREATED CREATED BY SIZE COMMENT
3e12e812ffba 3 days ago bash 19B
de8b49d4b0b3 2 weeks ago /bin/sh -c #(nop) CMD ["bash"] 0B
<missing> 2 weeks ago /bin/sh -c #(nop) ADD file:da71baf0d22cb2ede... 101MB
L'architecture des images Docker tire efficacement parti de ce concept de superposition pour ajouter de manière transparente des fonctionnalités supplémentaires aux images existantes. Ce système permet également de mutualiser certains layers et ainsi de réutiliser les layers identiques entre plusieurs images.
En d'autres termes, des fonctionnalités peuvent être ajoutées aux images existantes en ajoutant des layers supplémentaires par-dessus une image existante donnant naissance à une nouvelle image.
Les images Docker ont une relation parent-enfant et l'image la plus basse est appelée image de base. L'image de base est une image spéciale sans parent.
Exemple :
Comme vous pouvez le voir dans la figure ci-contre, on utilise une image de base. Dans cet exemple, il s'agit de Debian. Dans un premier layer, on ajoute le paquet wget
. Ce layer fait référence à l'image Debian en tant que parent. Dans la couche suivante, une instance du serveur d'applications Apache 2
est ajoutée et fait référence à l'image wget
en tant que parent.
Chaque ajout apporté à l'image de base d'origine est stocké dans un layer séparé.
La construction d'une image donne naissance à un identifiant unique qui regroupe tous les layers et qu'il est ensuite possible de partager au travers d'un registre comme le Docker Hub
Fondamental : Conteneur Docker
Les images Docker sont donc des modèles d'application composés de layer et qui sont en lecture seule.
Le conteneur Docker est dérivé de l'image Docker auquel il ajoute un layer de lecture-écriture au-dessus des layers d'image statiques. En programmation-objet, on pourrait comparer l'image a une classe alors qu'un conteneur est une instance de cette classe.
L'image Docker définit le comportement du conteneur Docker, par exemple le processus à exécuter lors du démarrage du conteneur. Ce sont les images Docker qui vont par la suite définir le comportement du conteneur une fois lancé.
Comme l'illustre la figure ci-contre, lorsque le conteneur est créé, un layer en écriture (lecture-écriture) est ajoutée au-dessus de l'image afin de conserver l'état de l'application. Il pourrait y avoir plusieurs images en lecture seule sous la couche conteneur (en écriture).
Remarque : Réutilisation des layers et cache
Docker possède un système intelligent de cache qui est en mesure d'utiliser des layers déjà existant si les instructions ainsi que les images de base sont les mêmes.
Ce principe permet de limiter la taille des images sur les registy en utilisant au maximum la déduplication. Il permet également d'accélérer le build des images en ne rejouant pas systématiquement les actions des layers lors de la construction des images.