Docker comme solution de virtualisation : les commits

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

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

Bienvenue dans la quatrième partie de mes articles nous emmenant à la découverte de Docker !

Après avoir étudié les principes de Docker et commencé à jouer avec les conteneurs, il est maintenant grand temps de mettre réellement en place une application digne de ce nom !

Ça tombe bien puisque la sortie de la première bêta de Sonerezh est imminente, je vous propose de voir comment est-ce que nous pourrions « dockeriser » une application PHP classique.

Reprenons où nous en étions restés :

docker ps --all
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS                    PORTS               NAMES
a0018e7b5dd3        debian:latest       "/bin/sh -c 'while t"  3 weeks ago         Exited (-1) 3 weeks ago                       determined_bell  
82a7a75b7d25        debian:latest       "/bin/bash"            3 weeks ago         Exited (0) 3 weeks ago                        insane_kowalevski 
c8367cbba7ff        debian:latest       "/bin/echo 'Hello Wo"  3 weeks ago         Exited (0) 3 weeks ago                        suspicious_feynman

Nous nous étions amusés à lancer quelques conteneurs pour voir comment les manipuler. Comme base pour notre application web, qui se compose d’un serveur web, de PHP et d’une base de données, je vous propose de réutiliser le conteneur avec le shell. Et pour plus de commodité, je vais renommer ce conteneur en « sonerezh ».

docker rename insane_kowalevski sonerezh
docker start sonerezh
docker attach sonerezh
root@82a7a75b7d25:/#
Je travaille maintenant dans mon conteneur, les commandes passées à l’hôte seront précédées de guillaume@docker, et celles passées au conteneur par root@646c9d0d39a0:/#.

Mettons à jour notre image de Debian.

root@646c9d0d39a0:/# apt-get update && apt-get upgrade
[...]

Vous vous souvenez quand je vous avais dis que lorsque vous instanciiez un conteneur, Docker ajoutais au dessus de celui-ci une couche accessible en lecture et écriture ? Il est possible de voir les différences qui ont été apportées par rapport à votre image d’origine avec la commande :

guillaume@docker:~$ docker diff sonerezh
C /root
A /root/.bash_history
C /var
C /var/lib
C /var/lib/apt
[...]

Les lignes précédées d’un A représentent les ajouts, d’un C les modification et D les suppressions.

Je vous propose maintenant d’installer Nginx, avec un simple :

oot@646c9d0d39a0:/# apt-get install nginx
oot@646c9d0d39a0:/# service nginx start

Et c’est tout ! Nginx est démarré sur notre conteneur ! Vous ne me croyez pas ? Plusieurs moyens de le vérifier :

Depuis le conteneur

root@646c9d0d39a0:/# ls -ld /proc/[0-9]* | grep www-data
dr-xr-xr-x 9 www-data www-data 0 Feb 10 20:51 /proc/598
dr-xr-xr-x 9 www-data www-data 0 Feb 10 20:51 /proc/599
dr-xr-xr-x 9 www-data www-data 0 Feb 10 20:51 /proc/600
dr-xr-xr-x 9 www-data www-data 0 Feb 10 20:51 /proc/601

Depuis l’hôte :

guillaume@docker:~$ docker top sonerezh
UID                 PID                 PPID                C                   STIME               TTY                 TIME                CMD
root                6294                6084                0                   21:38               pts/1               00:00:00            /bin/bash
root                6933                6294                0                   21:50               ?                   00:00:00            nginx: master process /usr/sbin/nginx
www-data            6934                6933                0                   21:50               ?                   00:00:00            nginx: worker process
www-data            6935                6933                0                   21:50               ?                   00:00:00            nginx: worker process
www-data            6936                6933                0                   21:50               ?                   00:00:00            nginx: worker process
www-data            6937                6933                0                   21:50               ?                   00:00:00            nginx: worker process

Et enfin, vous pouvez aussi le vérifier en accédant directement à l’adresse du conteneur :

guillaume@docker:~$ wget -q -O - http://172.17.0.4 
<html>
<head>
<title>Welcome to nginx!</title>
</head>
<body bgcolor="white" text="black">
<center><h1>Welcome to nginx!</h1></center>
</body>
</html>
Pour connaître l’adresse IP d’un conteneur :

root@646c9d0d39a0:/# ip -4 -o a show eth0
14: eth0    inet 172.17.0.4/16 scope global eth0\       valid_lft forever preferred_lft forever

côté conteneur, ou :

guillaume@docker:~$ docker inspect --format "{{.NetworkSettings.IPAddress}}" sonerezh
172.17.0.4

depuis l’hôte.

Je vous passe l’installation de PHP et compagnie puisqu’à partir de là tout est comme si vous étiez sur une Debian classique… puisque vous êtes sur une image de Debian !

À ce stade, nous avons donc un conteneur avec Nginx qui fonctionne. Sauf qu’il n’est pas très élégant de proposer un service de cette manière, directement avec l’adresse IP du conteneur, qui a fortiori, est difficilement accessible depuis une machine extérieure. L’idéal serait de pouvoir faire de la redirection de port. Que l’hôte Docker qui reçoit une requête la transmette directement au conteneur adéquat.

Que nous dit la documentation à ce propos ? Argh il aurait fallu utiliser l’option -p, ou --publish avec la commande docker run ! D’ailleurs si vous vous souvenez bien, il y a une colonne intitulée « PORTS » en sortie de la commande docker ps.

Han ça veut dire que je dois relancer un conteneur et me retaper toute la configuration de PHP ?! 0o

Oui… et non ! On peut très bien recommencer, mais on peut aussi transformer note conteneur en image, afin de pouvoir la réutiliser avec la commande run. Cette action s’appelle un commit, et n’est pas sans rappeler le commit de Git. Et les similitudes ne s’arrêtent pas là, regardez plutôt comment on fait pour créer un commit d’un conteneur :

guillaume@docker:~$ docker commit sonerezh sonerezh-nginx
ecb48406a489ba67885f9ec3fdd98b606da701791fa2db06646a84b766bda204

Une nouvelle image a été créé à partir des modifications que nous avons apporté à l’image debian:latest.

guillaume@docker:~$ docker images 
REPOSITORY          TAG                 IMAGE ID            CREATED              VIRTUAL SIZE
sonerezh-nginx      latest              ecb48406a489        About a minute ago   155.4 MB
debian              latest              4d6ce913b130        3 weeks ago          84.98 MB
ubuntu              14.04               b39b81afc8ca        3 weeks ago          188.3 MB

Cette image a été affectée par défaut du tag « latest », que vous pouvez modifier avec la commande tag.

guillaume@docker:~$ docker tag sonerezh-nginx:latest sonerezh-nginx:0.9.0-beta
guillaume@docker:~$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             VIRTUAL SIZE
sonerezh-nginx      latest              ecb48406a489        5 minutes ago       155.4 MB
sonerezh-nginx      0.9.0-beta          ecb48406a489        5 minutes ago       155.4 MB
debian              latest              4d6ce913b130        3 weeks ago         84.98 MB
ubuntu              14.04               b39b81afc8ca        3 weeks ago         188.3 MB
Oulala ! J’ai deux images Sonerezh de 155.4 MB du coup ! Mon stockage va diminuer très vite à ce rythme là.

Mais non pas de panique. Rappelez-vous ce que je vous avais dit lors de nos premiers pas avec les images : les tags sont seulement un moyen efficace et facile d’identifier une image, or si vous regardez l’ID de l’image sonerezh-nginx, c’est le même sur les deux lignes. On parle donc bien de la même image, qui ne prend qu’une fois 155.4MB.

D’ailleurs, il faut soustraire à ces 155.4 MB les 84.98 MB de l’image debian sur laquelle elle se base. Et oui ! Elles sont cela en commun !

guillaume@docker:~$ docker history sonerezh-nginx 
IMAGE               CREATED             CREATED BY                                      SIZE
ecb48406a489        9 minutes ago       /bin/bash                                       70.47 MB
4d6ce913b130        3 weeks ago         /bin/sh -c #(nop) CMD [/bin/bash]               0 B
d0a18d3b84de        3 weeks ago         /bin/sh -c #(nop) ADD file:4a58c36173b61e8a7b   84.98 MB
511136ea3c5a        20 months ago

Vous comprenez mieux pourquoi Docker est vraiment séduisant sur bien des aspects ? 🙂

Revenons maintenant à la redirection de port avant de refermer ce chapitre. Je vous le disais, nous allons utiliser l’option -p :

guillaume@docker:~$ docker run -d -p 80 sonerezh-nginx /usr/sbin/nginx -g "daemon off;"
2fb71867a9eabf18731352b20deda2da517c1e283ca7c904088d2ba02f51658e
guillaume@docker:~$ docker ps -l
CONTAINER ID        IMAGE                       COMMAND                CREATED             STATUS              PORTS                   NAMES
2fb71867a9ea        sonerezh-nginx:0.9.0-beta   "/usr/sbin/nginx -g    59 seconds ago      Up 58 seconds       0.0.0.0:49155->80/tcp   cranky_morse

On voit que le port 49155 de l’hôte Docker (ma machine) a été redirigé vers le port 80 du conteneur cranky_morse, qui est une instance de l’image sonerezh-nginx. Vous pouvez essayer d’accéder à votre machine depuis une autre, avec son IP, sur le port adéquat. Par exemple mon hôte Docker ayant l’IP 192.168.100.51, je tape depuis une autre machine de mon réseau local :

wget -q -O - http://192.168.100.51:49155
<html>
<head>
<title>Welcome to nginx!</title>
</head>
<body bgcolor="white" text="black">
<center><h1>Welcome to nginx!</h1></center>
</body>
</html>

Pas mal non ? 😀

Le Docker Hub

À l’instar d’un GitHub où vous allez pouvoir envoyer et partager vos codes sources, le Docker Hub est un site en ligne qui va vous permettre d’envoyer et partager vos images. Il est au cœur de la communauté Docker puisque c’est ici que vous allez retrouver tous les dépôts et images officiels. Docker interroge d’ailleurs ce site lorsque nous utilisons les commandes docker pull ou docker search.

En plus d’être joli, le site propose tout un tas d’informations très précises sur les différentes versions d’images qui pourraient vous intéresser, par exemple pour Debian :

Dépôt officiel de Debian, sur le Docker Hub

Dépôt officiel de Debian, sur le Docker Hub

N’hésitez pas à l’explorer 😉

Comme mes images ne sont pas tout à fait prêtes je ne vais pas les envoyer maintenant sur le Docker Hub, nous aurons tous le temps de voir cela une fois Sonerezh proprement dockerisée !

Conclusion pour aujourd’hui

Nous progressons tranquillement dans la mise en place de Sonerezh sous Docker. Nous avons une image, qui embarque Nginx, PHP et Sonerezh. Que nous manque-t-il ? Une base de données, qui fera l’objet d’un autre conteneur. Ça sera l’occasion de voir comment nous pouvons lier plusieurs conteneurs entre eux.

Ensuite Sonerezh a besoin d’accéder à des fichiers audios. Il faudrait que les conteneurs Sonerezh puissent accéder aux fichiers audios présents sur mon hôte. Ça sera là aussi l’occasion d’un prochain article où nous verrons comment gérer les volumes avec Docker.

Il reste encore du travail donc, et j’espère que vous serez au rendez-vous ! N’hésitez pas à vous emparer du formulaire des commentaires si vous avez des suggestions ou des remarques 😉

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

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

Twitter Facebook Google Plus email