Docker comme solution de virtualisation : les liaisons

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

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

Je continue ma série d’articles sur Docker afin de découvrir autour d’un cas concret comment utiliser Docker et comment transformer une application web classique en conteneur. Rappelez-vous précédemment, nous avions vu comment instancier une image Debian pour y ajouter notre application web (Nginx, PHP et le code source de l’application) pour enfin comprendre comment sauvegarder les changements apportés à l’image d’origine grâce aux commits.

Pour des raisons de simplicité je m’étais arrêté à la simple installation de Nginx pour vous montrer aussi comment faire dialoguer nos conteneurs avec le reste du monde grâce à la gestion de leurs ports d’écoute, et leur redirection entre conteneurs et l’hôte Docker.

Aujourd’hui nous allons terminer notre image Docker contenant Sonerezh et voir comment la lier à un conteneur qui offrira la base de données MySQL dont Sonerezh a besoin. Mais d’abord, revoyons comment j’ai créé l’image de Sonerezh.

Création de l’image Sonerezh

Cette section permet juste de faire une révision par rapport aux précédents articles, c’est pourquoi je ne commenterai pas ce que je fais.
C’est en faisant qu’on apprend, et en rédigeant cet article je me suis rendu compte que le conteneur Nginx / PHP n’était pas le plus simple à implémenter pour faire une démonstration de ce genre. J’ai en effet raisonné au départ de manière à croire qu’un conteneur = une machine virtuelle. Or Docker n’est pas de la virtualisation dans le sens où j’y ai été habitué jusqu’à maintenant. Docker permet simplement de cloisonner des services. Un conteneur = un service.

Partant de ce principe, il m’aurait fallu un conteneur pour Nginx, un pour PHP et un pour MySQL. Ça commence à être un peu tordu pour débuter… On va donc rester sur le bon vieux Apache (qui embarque PHP par défaut) !

$ docker run -t -i debian:jessie /bin/bash
Unable to find image 'debian:jessie' locally
jessie: Pulling from debian
 
3cb35ae859e7: Downloading [===========================================>       ] 44.56 MB/51.36 MB
41b730702607: Download complete
root@1426b082ab71:/ apt update
root@1426b082ab71:/ apt upgrade
root@1426b082ab71:/ apt install -y php5-gd php5-mysql php5 apache2 libav-tools git vim
root@1426b082ab71:/ vim /etc/php5/fpm/conf.d/00-local.ini
[date]
date.timezone = Europe/Paris
root@1426b082ab71:/ mkdir /www && cd /www
root@1426b082ab71:/ git clone --branch master https://github.com/Sonerezh/sonerezh.git
root@1426b082ab71:/ chown -R www-data: sonerezh
root@1426b082ab71:/ chmod -R 775 sonerezh
root@1426b082ab71:/ vim /etc/apache2/sites-available/000-default.conf
<VirtualHost *:80>
    ServerName      localhost
    DocumentRoot    /www/sonerezh
 
    <Directory /www/sonerezh>
        Options -Indexes
        AllowOverride All
        Require all granted
    </Directory>
 
    CustomLog   /var/log/apache2/sonerezh-access.log "Combined"
    ErrorLog    /var/log/apache2/sonerezh-error.log
</VirtualHost>
root@1426b082ab71:/ a2enmod php5
root@1426b082ab71:/ a2enmod rewrite
root@1426b082ab71:/ service apache2 restart
root@1426b082ab71:/ exit

Je n’ai perdu personne ?

Tu veux bien nous faire un petit résumé ?

J’ai tout simplement déployé Sonerezh dans mon conteneur à base de Debian ! Premièrement : installation et configuration d’Apache, PHP et Git (notez que le Virtual Host Apache par défaut a été effacé). Ensuite je clone le dépôt GitHub de Sonerezh dans /www/sonerezh.

Maintenant que mon conteneur est prêt, mais à l’arrêt puisque je l’ai quitté, profitons-en pour en faire une image, grâce à un commit :

$ docker commit --author="Guillaume <guillaume@sonerezh.bzh>" thirsty_mccarthy sonerezh/sonerezh:v0.9.0-beta
b3282df5ff60517432e44f56ede09f77cdda53d514b5aa0a91398fe0b4b0504d
$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED              VIRTUAL SIZE
sonerezh/sonerezh   v0.9.0-beta         8d7a0b0c64fb        About a minute ago   398.7 MB
debian              jessie              41b730702607        8 days ago           125.1 MB

Et voilà le travail ! Je peux maintenant transporter et déployer Sonerezh très facilement avec un simple docker run !

Non, il manque la base de données !

Exact, et c’est là que l’article prend tout son intérêt. Les applications que nous plaçons dans des conteneurs fonctionnent rarement seules, surtout en matière de web où il est très souvent nécessaire d’avoir une base de données à portée de main. Nous l’avons vu avec Docker il est très facile d’instancier des conteneurs et on se retrouver vite avec un bordel sans nom où il devient compliquer de faire communiquer tout ce petit monde.

Heureusement, Docker propose des mécanismes pour lier plusieurs conteneurs entre eux lorsqu’on les exécute. Comme cela se passe-t-il ? Tout bêtement avec les fichiers /etc/hosts des conteneurs, que Docker va aller modifier en fonction des arguments que nous passerons lors du lancement d’un conteneur. Exemple.

Lier plusieurs conteneurs entre eux

Récupérer une image MariaDB

Pour le coup je vais faire plus simple que précédemment en récupérant directement l’image de MariaDB sur le dépôt officiel.

$ docker run --name sonerezh-mariadb -e MYSQL_ROOT_PASSWORD=sonerezh -d mariadb:latest

Rappelez-vous l’option -d a placé le conteneur en arrière plan mais il fonctionne bien :

$ docker ps
CONTAINER ID        IMAGE               COMMAND                CREATED             STATUS              PORTS               NAMES
ae15f2411af2        mariadb:latest      "/docker-entrypoint.   52 seconds ago      Up 50 seconds       3306/tcp            sonerezh-mariadb

On remarque d’ailleurs qu’il écoute sur le port standard de MySQL (3306), on peut essayer de s’y connecter depuis l’hôte :

$ docker inspect --format "{{.NetworkSettings.IPAddress}}" sonerezh-mariadb
172.17.0.2
$ mysql -h172.17.0.2 -uroot -psonerezh
 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 4
Server version: 10.0.17-MariaDB-1~wheezy-log mariadb.org binary distribution
 
Copyright (c) 2000, 2015, Oracle, MariaDB Corporation Ab and others.
 
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
 
MariaDB [(none)]>

On pourrait même en profiter pour créer l’utilisateur sonerezh !

CREATE DATABASE sonerezh;
GRANT ALL PRIVILEGES ON sonerezh.* TO 'sonerezh'@'localhost' IDENTIFIED BY 'password';
FLUSH PRIVILEGES;
exit;

Lier les conteneurs sonerezh-app et sonerezh-mariadb

La liaison se fait avec l’option --link (ou -l) et prend en argument nom_du_conteneur:alias où là encore l’alias reste à votre appréciation. Nous allons relancer l’image préalablement créée en lui demandant d’y exécuter Apache (et donc Sonerezh), sans oublier la liaison avec sonerezh-mariadb. Oh et n’oublions pas de demander au conteneur Apache d’écouter le port 80 !

$ docker run --link sonerezh-mariadb:mariadb -d -p 80 --name sonerezh-app sonerezh/sonerezh:v0.9.0-beta /usr/sbin/apache2ctl -D FOREGROUND
163ceac2c1573590f1ad5bfabf85d81b92ceb666378c366addb7143ed17fee8a

Je vous laisse relire cette commande deux ou trois fois pour bien comprendre ce qu’il s’y passe.

$ docker ps
CONTAINER ID        IMAGE                           COMMAND                CREATED             STATUS              PORTS                   NAMES
1eaafc9d9f66        sonerezh/sonerezh:v0.9.0-beta   "/usr/sbin/apache2ct   3 seconds ago       Up 2 seconds        0.0.0.0:32771->80/tcp   sonerezh-app        
ae15f2411af2        mariadb:latest                  "/docker-entrypoint.   35 minutes ago      Up 35 minutes       3306/tcp                sonerezh-mariadb

Vérification

Quoi de mieux pour vérifier que de tenter d’installer Sonerezh ? D’après le ps ci-dessus, mon hôte Docker redirige son port 32771 vers le port 80 de mon conteneur sonerezh-app, celui-là même lié au conteneur sonerezh-mariadb.

J’accède donc, via mon navigateur, à mon hôte Docker (192.168.100.240:32771) :

Mon hôte Docker m'a bien retourné l'instance de Sonerezh du conteneur sonerezh-app !

Mon hôte Docker m’a bien retourné l’instance de Sonerezh du conteneur sonerezh-app !

Comment mon conteneur sonerezh-app peut-il contacter le conteneur sonerezh-mariadb ? Grâce à l’alias que j’ai utilisé avec l’option --link. Pour l’installation j’ai donc comme configuration :

J'utilise l'alias du conteneur sonerezh-mariadb...

J’utilise l’alias du conteneur sonerezh-mariadb…

Sonerezh - Docker Installation

Ce que permet aussi --link

En fait, pour que ces alias fonctionnent, Docker est allé modifier le fichier /etc/hosts de mes conteneurs, voyez plutôt, ici sur sonerezh-app :

root@1eaafc9d9f66:/# cat /etc/hosts
172.17.0.3	1eaafc9d9f66
127.0.0.1	localhost
::1	localhost ip6-localhost ip6-loopback
fe00::0	ip6-localnet
ff00::0	ip6-mcastprefix
ff02::1	ip6-allnodes
ff02::2	ip6-allrouters
172.17.0.2	mariadb ae15f2411af2 sonerezh-mariadb

De plus, on trouve tout un tas de nouvelles variables d’environnements qui pourraient être très pratiques dans des scripts par exemple :

root@1eaafc9d9f66:/# env
MARIADB_ENV_MARIADB_VERSION=10.0.17+maria-1~wheezy
HOSTNAME=1eaafc9d9f66
MARIADB_PORT=tcp://172.17.0.2:3306
TERM=xterm
MARIADB_PORT_3306_TCP=tcp://172.17.0.2:3306
MARIADB_PORT_3306_TCP_PORT=3306
MARIADB_ENV_MYSQL_ROOT_PASSWORD=sonerezh
MARIADB_PORT_3306_TCP_PROTO=tcp
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
SHLVL=1
HOME=/root
MARIADB_NAME=/sonerezh-app/mariadb
MARIADB_ENV_MARIADB_MAJOR=10.0
MARIADB_PORT_3306_TCP_ADDR=172.17.0.2
_=/usr/bin/env

Pas mal non ? 🙂

Nous avons encore bien avancé dans la découverte de Docker et nous pouvons maintenant commencer à créer de belles petites architectures ! Maintenant que Sonerezh est prête sous forme d’image Docker, je vais pouvoir l’exploiter et la distribuer facilement via le Hub Docker ! Nous verrons tout cela un peu plus tard.

Avant cela, il va falloir que Sonerezh accède à ma musique. Or je ne vais pas copier ma musique dans mon conteneur cela n’aurait aucun sens. L’idéal serait que mon conteneur sonerezh-app puisse accéder à un dossier de mon hôte qui contiendrait ma musique. C’est ce que nous ferons dans le prochain article où nous verrons comment gérer les volumes dans Docker. D’ici là, amusez-vous bien !

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