4 juin 2014

Docker - Présentation

Présentation de Docker

Docker permet de simuler l'exécution de plusieurs machines Linux sur une même machine Linux sans avoir besoin d'utiliser de machines virtuelles.

Cependant, contrairement aux machines virtuelles, Docker ne simule pas de ressources matérielles ni de systèmes d'exploitation différents de ceux de la machine hôte.

Dans Docker, un conteneur définit un contexte d'exécution des processus qui est différent de celui de la machine Linux hôte.

Un conteneur est un environnement virtuel d'exécution de processus sur Linux.

Un conteneur dispose de ses propres ressources systèmes :
  • système de fichiers
  • interfaçage réseau
  • liste de processus en cours d'exécution
  • nom de la machine
  • CPU
  • mémoire
  • etc.
Nous avons un principe d'isolation des ressources systèmes au niveau du conteneur :
  • les processus d'un conteneur :
    • n'ont accès qu'aux ressources systèmes de ce conteneur
    • n'ont pas accès aux ressources systèmes de la machine hôte
    • n'ont pas accès aux ressources systèmes des autres conteneurs
Docker permet ainsi de simuler un environnement Linux différent au niveau de chaque conteneur.

Cependant, Docker partage certaines ressources systèmes entre le conteneur et la machine hôte
, avec par exemple :
  • la machine hôte voit les processus lancés dans les conteneurs
  • la configuration réseau d'un conteneur se base par défaut sur la configuration réseau de la machine hôte
Nous avons donc des ressources partagées entre les conteneurs et la machine hôte.

Evolution du noyau de Linux

Le cloisonnement des ressources systèmes est possible dans Linux grâce à une évolution en 2013 du noyau Linux : nouvelle version des control groups (cgroup) et introduction des espaces de nommage (namespaces). Ensemble ces deux fonctionnalités permettent de définir des ressources systèmes spécifiques à un groupe de processus.

Linux Containers (LXC) s'appuie sur ces nouvelles fonctionnalités du noyau et apporte le concept de conteneurs pour avoir un environnement virtuel d'exécution des processus.

Enfin Docker s'appuie lui-même sur Linux Containers en simplifiant l'usage au niveau du cycle de vie des conteneurs, de la gestion de l'exécution des conteneurs.

Composants et éléments de Docker

Image de conteneur

Une image de conteneur contient :
  • le paramétrage des ressources systèmes :
    • système de fichier
    • interfaçage réseau
  • les fichiers qui seront disponibles dans l'environnement virtuel d'exécution au lancement du conteneur.
Un conteneur s'exécute à partir d'une image.

Une image peut se baser sur une autre image parente afin d'en réutiliser le contenu et son paramétrage.

Par exemple, pour un conteneur fonctionnant sur Ubuntu, l'image parente de l'image de ce conteneur sera l'image Ubuntu fourni sur le repository officiel de Docker.

Fichier Dockerfile

Dockerfile est un fichier texte qui décrit comment construire une image de conteneur Docker.

Il dispose d'une syntaxe particulière expliquée dans la documentation : Dockerfile reference

Registry : référentiel d'images de conteneur

Le registry de Docker permet d'avoir un référentiel d'images de conteneurs pour l'entreprise.

Le registry permet de versionner et de partager des images de conteneurs afin de démarrer des conteneurs à partir de ces images sur des environnements différents : développement, intégration, qualification, production.

Docker a un registry public nommé Docker Hub registry contenant les images officielles ainsi que les images fournies par la communauté.

De plus, Docker permet de créer son propre registry privé pour indexer ses images privées.
Pour cela, il propose l'image registry pour démarrer rapidement son propre registry dans un conteneur docker.

Démon, client et services REST Docker

Le démon linux Docker gère les images et l'exécution des conteneurs :
  • construction des images
  • envoi et réception des images au registry Docker
  • export et import d'image depuis un fichier Tar compressé
  • démarrage d'un conteneur à partir d'une image
  • arrêt d'un conteneur
  • destruction d'une image ou d'un conteneur
Le client Docker docker en ligne de commandes Linux permet de dialoguer avec le démon Docker pour gérer les conteneurs.

Il est également possible d'utiliser des services REST pour dialoguer avec le démon Docker afin de gérer les conteneurs via des URL et sans avoir besoin d'accès SSH.

Cycle de vie

Avec Docker, on part d'un fichier Dockerfile pour construire une image de conteneur. Cette image servira à démarrer des conteneurs qui utiliseront le contenu de cette image.


Voici un schéma illustrant le cycle de vie d'un conteneur avec les commandes via le client Docker :


Exécution des conteneurs


Un conteneur s'exécute à partir d'une image.

La commande docker run <image> indique au démon Docker de récupérer l'image en question et de démarrer un conteneur sur cette image.

Système de fichiers dans un conteneur

Le conteneur en cours d'exécution utilise le contenu de l'image, mais n'en copie ni n'en modifie le contenu.

Le conteneur ne conserve en local que le delta des modifications avec cette image.

Par exemple, dans le cas d'un fichier présent dans l'image qui a été modifié, supprimé ou ajouté dans le conteneur en cours d'exécution, ce conteneur conservera la nouvelle version du fichier, mais l'image ni les autres conteneurs utilisant cette image n'auront ces modifications.

Ainsi cela évite de copier le contenu de l'image pour chaque conteneur utilisant cette image. Cela permet d'isoler les différences entre les conteneurs reposant sur une même image.

Il est possible d'appliquer les modifications qui sont en local dans un conteneur pour l'appliquer à l'image qui sera ainsi modifiée. Ceci est possible via la commande Docker : docker commit.

Montage de volumes partagés

Les fichiers modifiés au sein d'un conteneur sont perdus lors de la suppression de ce conteneur via la commande docker rm.

Pour conserver ces fichiers, il est nécessaire de définir des répertoires partagés avec le système de fichiers de la machine hôte. Ces répertoires sont montés dans le conteneur à son démarrage.

Ces répertoires sont définis au niveau du fichier Dockerfile :

Interfaçage réseau

La commande de lancement d'un conteneur peut avoir des arguments concernant les ressources systèmes, comme la redirection de port entre la machine hôte et le port du conteneur.

Par exemple, pour un conteneur qui a un port public 8080, on indique que ce port sera redirigé sur le port 8083 de la machine hôte. Ainsi une requête qui arrive sur le port 8083 de la machine hôte sera redirigé vers le port 8080 du conteneur.
Nous pouvons avoir plusieurs conteneurs ayant le même port public 8080 mais qui sont redirigés vers d'autres ports au niveau de la machine hôte.

Pour plus d'informations :

Conclusion

Docker permet de simuler plusieurs machines Linux au sein d'une seule machine Linux ce qui apporte un gain en ressources matérielles.

Avant, nous avions autant de VM que de conteneur. Avec Docker, nous pouvons avoir une machine Linux qui tourne ou non dans une VM et avec Docker. Nous gagnons de la mémoire et de la ressource CPU.

D'autre part, les conteneurs et leurs images ne contiennent qu'une partie des fichiers de l'OS Linux nécessaires pour lancer les processus du serveur et de l'application.

Par ailleurs, l'image peut contenir directement le code de l'application : nous livrons ainsi pas uniquement l'application mais également l'environnement qui va avec. Ceci permet de déployer l'application et son environnement d'exécution en intégration, en qualification voir même en production, sur des machines Linux où docker est installé.

Références