Docker comme solution de virtualisation : les conteneurs

Source : Wikimédia. Image sous licence Apache 2.

Source : Wikimédia. Image sous licence Apache 2.

Bienvenue dans la troisième partie de mes articles nous emmenant à la découverte de Docker ! Après avoir expliqué ce qu’est Docker, nous avions récupéré notre première image et joué avec. Cette image était d’ailleurs une image d’Ubuntu.

Mais nous n’étions pas allés très loin et c’est dans ce troisième article que nous allons vraiment comprendre l’intérêt de Docker : lancer des conteneurs pour exécuter des applications.

Préparation

Voilà donc où nous en étions :

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
ubuntu              14.04               b39b81afc8ca        36 hours ago        188.3 MB

Sauf que finalement nous n’allons pas travailler sur une image d’Ubuntu, mais plutôt de Debian. Je vous rappelle que mon objectif ici est de créer une version dockerisée de Sonerezh, le lecteur audio HTML5 sur lequel je travaille depuis quelques temps maintenant, et dont la bêta ne devrait pus tarder à sortir.

Plutôt que de travailler avec une image d’Ubuntu, je vais lui préférer une image de Debian, deux fois moins lourde.

# Je récupère la dernière image de Debian (Stable 7.8 à l'heure actuelle)
$ docker pull debian:latest

Manipulation de nos premiers conteneurs

Mais au fait, c’est quoi déjà un conteneur ?

Pas de panique c’est très simple : un conteneur est une instance active d’une image. On lance un conteneur afin d’y exécuter un ou plusieurs processus, et ce avec la commande run.

$ docker run debian:latest /bin/echo 'Hello World!'
Hello World!
Félicitation, vous avez lancé votre premier conteneur !

Mais que s’est-il passé ?

Nous avons demandé à Docker de lancer un conteneur à partir de l’image debian:latest grâce à la commande run. Docker a donc cherché l’image debian:latest sur l’hôte local, ou l’aurait automatiquement téléchargée si elle n’avait pas été présente. Une fois le conteneur instancié, Docker a exécuté la commande /bin/echo 'Hello World!' à l’intérieur de celui-ci et nous a retourné le résultat : Hello World!

Qu’est-il arrivé à notre conteneur ensuite ?

Et bien Docker l’a tout simplement terminé. Retenez bien cela : la durée de vie d’un conteneur dépend directement du temps de vie des processus qui y sont exécutés ! Ici en l’occurrence, notre conteneur a « vécu » le temps que la commande /bin/echo 'Hello World!' s’exécute.

Essayons autre chose :

$ docker run -t -i debian:latest /bin/bash
root@82a7a75b7d25:/#

Nous avons passé deux options à la commande run : -t assigne un terminal à l’intérieur du conteneur, et -i nous autorise à nous y connecter en récupérant directement l’entrée standard (STDIN). Notre conteneur est donc lancé, et nous nous retrouvons avec un shell à l’intérieur. Essayez diverses commandes, vous verrez que c’est comme si vous étiez connectés à une Debian classique. Une fois vos expériences terminées, utilisez exit pour fermer le shell. La commande /bin/bash est terminée, et donc notre conteneur avec.

Des conteneurs qui exécutent des commandes et s’arrêtent une fois la commande terminée ? On m’explique l’intérêt ?

Ok, l’intérêt est limité pour le moment. C’était histoire de lancer un premier conteneur… Essayons de « daemoniser » notre Hello World! :

$  docker run -d debian:latest /bin/sh -c "while true; do echo hello world; sleep 1; done"
a0018e7b5dd3c93b056c4086ca811233881570058a2dd8011360a25e7e84f0b7

Le retour ressemble à tout sauf à « Hello World! ». C’est normal, remarquez que nous avons ajouté l’option -d, qui indique à Docker d’instancier un conteneur à partir de l’image debian:latest, et de le placer en arrière-plan, de le « daemoniser ». Le code retourné est juste l’identifiant unique de notre conteneur.

Tu veux dire que là j’ai un conteneur de démarré qui fait un /bin/echo 'Hello World!' toutes les secondes ?!

Exactement ! D’ailleurs, pour le vérifier, nous pouvons utiliser la commande docker ps, qui demande à Docker des informations à propos de tous les conteneurs en cours d’exécution.

$ docker ps
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS               NAMES
a0018e7b5dd3        debian:latest       "/bin/sh -c 'while t   3 minutes ago       Up 3 minutes                            determined_bell

Quelques remarques à propos du résultat :

  1. On retrouve bien l’ID de notre conteneur (a0018e7b5dd3)
  2. Ce conteneur a hérité d’un nom (determined_bell), automatiquement attribué par Docker, ceci afin de pouvoir manipuler notre conteneur plus facilement qu’avec son ID. Il est tout a fait possible de choisir un nom avec l’option --name
  3. Où sont passés les conteneurs précédents ? Ceux qui s’étaient arrêtés ?

L’option -a de la commande ps nous permet d’afficher tous les conteneurs, y compris ceux arrêtés :

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS                      PORTS               NAMES
a0018e7b5dd3        debian:latest       "/bin/sh -c 'while "   9 minutes ago       Up 9 minutes                                    determined_bell    
02a9b1d3cc9a        debian:latest       "/bin/bash"            19 minutes ago      Exited (0) 19 minutes ago                       thirsty_elion        
c8367cbba7ff        debian:latest       "/bin/echo 'Hello W"   32 minutes ago      Exited (0) 32 minutes ago                       suspicious_feynman

Mais revenons à notre Hello World daemonisé. Le conteneur est bien lancé, mais fait-il ce que nous lui avons demandé ? Pour le vérifier, nous allons utiliser la commande logs :

$ docker logs determined_bell
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
[...]

Cette commande retourne la sortie standard (STDOUT) d’un conteneur donné.

Quelques commandes pour manipuler nos conteneurs

Je profite d’avoir un conteneur lancé pour vous parler de quelques commandes utiles. Par exemple, il est tout à fait possible de mettre un conteneur en pause !

$ docker pause determined_bell
determined_bell
$ docker unpause determined_bell
determined_bell

Celui-ci se figera tant qu’il n’est pas sorti de pause, via la commande docker unpause.

Pour arrêter un conteneur, nous avons la commande docker stop (ou kill si vous souhaitez passer un code particulier) :

$ docker stop determined_bell
determined_bell
$ docker -l
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS                       PORTS               NAMES
a0018e7b5dd3        debian:latest       "/bin/sh -c 'while t   26 minutes ago      Exited (-1) 47 seconds ago                       determined_bell

Le conteneur est bien arrêté.

Il est aussi possible de redémarrer un conteneur arrêté. Prenons par exemple le conteneur où nous avions exécuté un shell interactif (il s’intitulait insane_kowalevski chez moi). Pour le démarrer, il y a la commande start

$ docker start insane_kowalevski
insane_kowalevski

La commande attach nous permet de nous reconnecter à ce conteneur :

$ docker attach insane_kowalevski
root@82a7a75b7d25:/#

Et la suite ?

Je vous propose d’y aller progressivement pour garder les idées claires, c’est pourquoi je vais m’arrêter ici pour cet article, même si j’ai moi aussi envie de continuer ! Car pour le moment nous découvrons simplement les concepts de Docker à travers quelques exemples simples. Avec ces bases, nous allons à présent pouvoir lancer des conteneurs, y démarrer des services réseaux, y ajouter des lecteurs et réellement lancer des services.

Je vous propose donc pour le prochain article de continuer à travailler sur notre image Debian, que nous allons transformer en petit serveur web, avant d’y déployer PHP, et Sonerezh 🙂

À très vite donc !

Cet article fait partie d’une suite :

  1. Docker comme solution de virtualisation : théorie
  2. Docker comme solution de virtualisation : installation
  3. Docker comme solution de virtualisation : les conteneurs
  4. Docker comme solution de virtualisation : les commits
  5. Docker comme solution de virtualisation : les liaisons
  6. Docker comme solution de virtualisation : les volumes


Sources :

Cet article vous a plu ? Partagez-le sur les réseaux sociaux !

Twitter Facebook Google Plus email