Le précédent billet faisait une introduction à Docker en présentant quelques commandes de base. Docker propose d’autres outils permettant de construire des conteneurs de manière automatique. C’est là qu’interviennent les Dockerfiles et docker-compose.
Nous allons recréer la même infrastructure présentée dans le précédent article. Un conteneur ayant la fonction de load balancer répartissant la charge sur deux autres conteneurs portant un serveur web.
La création d’image personnalisée avec Dockerfile
Tout d’abord, nous allons créer deux images personnalisés nous permettant de savoir sur quel serveur web on se trouve lorsqu’on fait une requête HTTP.
Créons une arborescence pour organiser nos fichiers :
$ mkdir -p plateforme/web1 plateforme/web2`
Créons un fichier Dockerfile qui comportera les instructions afin de créer une image personnalisée :
$ vi plateforme/web1/Dockerfile
FROM nginx:alpine
COPY index.html /usr/share/nginx/html/
- FROM indique qu’on utilise l’image nginx:alpine
- COPY copie un fichier venant de la machine hôte vers l’image à créer. Ici on souhaite copier un fichier HTML vers le répertoire par défaut dans lequel se trouvent les pages web du serveur Nginx.
N’oublions pas de créer notre page web index.html relative au serveur web1 :
$ vi plateforme/web1/index.html
WEB1
Nous pouvons faire la même chose pour le serveur 2 sans oublier de spécifier dans son fichier index.html le terme WEB2.
On devrait avoir quelque chose ressemblant à cette arborescence à partir du répertoire plateforme :
$ tree
.
├── web1
│ ├── Dockerfile
│ └── index.html
└── web2
├── Dockerfile
└── index.html
On va créer également une image personnalisée pour notre load balancer qui intégrera directement le fichier de configuration haproxy :
$ mkdir plateforme/haproxy
$ vi plateforme/haproxy.cfg
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
defaults
log global
mode http
option httplog
option dontlognull
timeout connect 5000
timeout client 50000
timeout server 50000
default-server port 80 maxconn 250 on-error fail-check slowstart 60s inter 1m fastinter 5s downinter 10s weight 100
frontend monfront
option forwardfor
bind 0.0.0.0:80
default_backend monback
backend monback
balance roundrobin
server web01 **web1**:80 check observe layer4 weight 100
server web02 **web2**:80 check observe layer4 weight 100
Créons également un Dockerfile pour la construction de notre image :
$ vi plateforme/haproxy/Dockerfile
- FROM haproxy:alpine
- COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg
L’automatisation
Regardons maintenant du côté de Docker Compose. Il s’agit d’un outil permettant de lancer de multiples conteneurs à la fois en regroupant toutes les informations dans un même fichier. Ainsi il n’est plus nécessaire d’exécuter plusieurs docker run
à la suite pour lancer vos différentes applications conteneurisées. Je vous laisse le soin de l’installer en suivant la documentation officielle.
Créons un fichier docker-compose dans le répertoire plateforme :
$ vi docker-compose.yml
version: '2'
services:
web1:
build: web1
web2:
build: web2
ha:
build: haproxy
ports:
- "8080:80"
Globalement le fichier indique qu’il y a 3 services : web1, web2 et ha. Les services font appel à l’instruction build suivie de répertoire dans lequel se trouve le Dockerfile ce qui permettra de construire l’image personnalisée à la volée si elle n’existe pas déjà. Pour le load balancer on n’oublie pas de faire une redirection du port 80 pour pouvoir y accéder de la machine hôte.
Nous avons maintenant tous les éléments pour lancer nos conteneurs :
$ docker-compose up -d
docker-compose up -d
Building web2
Step 1/2 : FROM nginx:alpine
---> c24ab147adf9
Step 2/2 : COPY index.html /usr/share/nginx/html/
---> 51c1b7fc986c
Removing intermediate container 698a3d036d77
Successfully built 51c1b7fc986c
WARNING: Image for service web2 was built because it did not already exist. To rebuild this image you must use \`docker-compose build\` or \`docker-compose up --build\`.
Building ha
Step 1/2 : FROM haproxy:alpine
---> 11689e6f9be2
Step 2/2 : COPY haproxy.cfg /usr/local/etc/haproxy/haproxy.cfg
---> 9e0df231f53c
Removing intermediate container a64906902e88
Successfully built 9e0df231f53c
WARNING: Image for service ha was built because it did not already exist. To rebuild this image you must use \`docker-compose build\` or \`docker-compose up --build\`.
Building web1
Step 1/2 : FROM nginx:alpine
---> c24ab147adf9
Step 2/2 : COPY index.html /usr/share/nginx/html/
---> 33ba07563184
Removing intermediate container 6d44df178305
Successfully built 33ba07563184
WARNING: Image for service web1 was built because it did not already exist. To rebuild this image you must use \`docker-compose build\` or \`docker-compose up --build\`.
Creating pf_web2_1
Creating pf_web1_1
Creating pf_ha_1
Docker créé les images car celle-ci ne sont pas présente en local. C’est normal puisque c’est la première fois qu’on exécute la commande. Une fois les images construites, Docker lance les conteneurs.
Vérifions l’existence de nos conteneurs :
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
62b7360bb5b2 pf_ha "/docker-entrypoin..." About a minute ago Up About a minute 0.0.0.0:8080->80/tcp pf_ha_1
9ec2d1161052 pf_web1 "nginx -g 'daemon ..." About a minute ago Up About a minute 80/tcp, 443/tcp pf_web1_1
cd5a3acda548 pf_web2 "nginx -g 'daemon ..." About a minute ago Up About a minute 80/tcp, 443/tcp pf_web2_1
Vérifions la présente de nos images en local :
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
pf_ha latest 9e0df231f53c 4 minutes ago 14.6 MB
pf_web1 latest 33ba07563184 4 minutes ago 54.3 MB
pf_web2 latest 51c1b7fc986c 4 minutes ago 54.3 MB
nginx alpine c24ab147adf9 2 weeks ago 54.3 MB
haproxy alpine 11689e6f9be2 3 weeks ago 14.6 MB
Faisons appel à notre load balancer plusieurs fois et regardons que la répartition de charge fonctionne.
$ curl http://localhost:8080
WEB1
$ curl http://localhost:8080
WEB2
L’objectif est atteint. On aura pu faire plus simple sans avoir à créer des images personnalisées pour nos serveurs web. Dans ce cas précis, on oublie le Dockerfile pour chaque serveur web et son index.html modifié.
Le fichier docker-compose doit ressemble alors à celui-ci :
version: '2'
services:
web1:
image: nginx
web2:
image: nginx
ha:
build: haproxy
ports:
- "8080:80"
Cet article ne présente qu’un très bref aperçu des possibilités possibles. Sachez également que les conteneurs Docker peuvent être orchestrés par d’autres outils comme Ansible pour n’en citer qu’un seul.
Hello to all
In this difficult continuously, I proclivity you all
Rise your one’s nearest and friends