Une chose qui m’a posé problème dans l’article sur le load balacing est que en fonction de l’ordre de démarrage des conteneurs, il fallait modifier le fichier de configuration haproxy.cfg pour avoir les bonnes ips. Je me suis donc intéressé aux liens entre conteneurs et j’ai un peu fait évoluer les choses. Tout d’abord, j’ai commencé par donné des noms à mes conteneurs applicatifs:
|
docker run --name appA session-webapp/1.0-SNAPSHOT & docker run --name appB session-webapp/1.0-SNAPSHOT & |
Je vais donc avoir un conteneur 1 avec un nom appA et un conteneur 2 avec un nom appB (les conteneurs étant les mêmes). J’ai ensuite construit une nouvelle image haproxy en repartant de zéro pour apporter quelques modifications au script de démarrage. J’ai d’abord redéfini le Dockerfile:
|
FROM dockerfile/ubuntu RUN apt-get update RUN apt-get install -y haproxy RUN sed -i 's|/dev/log|127.0.0.1|g' /etc/haproxy/haproxy.cfg RUN sed -i 's/daemon/#daemon/g' /etc/haproxy/haproxy.cfg ADD start_haproxy.sh /usr/local/bin/start_haproxy.sh CMD [ "bash" , "/usr/local/bin/start_haproxy.sh"] EXPOSE 80 |
J’installe le paquet haproxy et je modifie quelques éléments de la configuration. Notamment, je désactive le mode daemon. J’ajoute un script sh qui servira de base au lancement de l’image et j’expose le port 80. Le fichier script va construire la configuration au démarrage en fonction des conteneurs qui seront linkés. En regardant la documentation sur les links, on voit que pour chaque lien déclarer, docker va pousser des variables d’environnement dans le conteneur parent.
Exemple avec la commande
|
docker run -i -t --link appA:app1 bcharret/haproxy /bin/bash |
j’obtiens les valeurs suivantes
|
[ root@c47b85aaf7e5:~ ]$ env | grep APP1 | sort APP1_ENV_CATALINA_HOME=/opt/tomcat APP1_ENV_TOMCAT_VERSION=6.0.39 APP1_NAME=/stupefied_euclid/app1 APP1_PORT=tcp://172.17.0.4:8080 APP1_PORT_8080_TCP=tcp://172.17.0.4:8080 APP1_PORT_8080_TCP_ADDR=172.17.0.4 APP1_PORT_8080_TCP_PORT=8080 APP1_PORT_8080_TCP_PROTO=tcp APP1_PORT_8081_TCP=tcp://172.17.0.4:8081 APP1_PORT_8081_TCP_ADDR=172.17.0.4 APP1_PORT_8081_TCP_PORT=8081 APP1_PORT_8081_TCP_PROTO=tcp |
Je peux donc me servir de ces valeurs pour construire ma configuration à la volée. La seule valeur supplémentaire dont j’ai besoin est de connaître le nombre de liens que je vais ajouter. Je vais donc introduire la variable UPSTREAMS
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
#!/bin/sh PIDFILE="/var/run/haproxy.pid" UP_COUNT=${UPSTREAMS:-1} ADD_CONFIG="listen session-webapp :80"$'\n' HAPROXY="/etc/haproxy" CONFIG="haproxy.cfg" cd "$HAPROXY" index=0 while [ $index -lt $UP_COUNT ]; do #for index in {1..$UP_COUNT}; do let $((index++)) IP_ADDR=`eval echo '$'APP${index}_PORT_8080_TCP_ADDR` ADD_CONFIG="${ADD_CONFIG}"$'\n'"server tomcat${index} ${IP_ADDR}:8080 check" done ADD_CONFIG="${ADD_CONFIG}"$'\n'"stats enable"$'\n'"stats uri /stats" echo "${ADD_CONFIG}" >> "$CONFIG" haproxy -f /etc/haproxy/haproxy.cfg -p "$PIDFILE" |
on voit bien que je vais ajouter autant de ligne server… que de $UPSTREAMS en me basant sur les valeurs successives de $APP?_PORT_8080_TCP_ADDR Cela donne avec deux liens:
|
listen session-webapp :80 server tomcat1 172.17.0.4:8080 check server tomcat2 172.17.0.3:8080 check stats enable stats uri /stats |
Pour lancer un conteneur avec des liens, on utilise la syntaxe suivante (dans un docker run):
|
--link container_name:link_name |
container_name étant le nom défini à la suite de la commande
–name link_name étant le nom qui sera utilisé dans le conteneur parent
Ce qui donne par exemple :
|
docker run --name haproxy --link appA:app1 --link appB:app2 --env "UPSTREAMS=2" bcharret/haproxy & |
Il est maintenant plus facile de rajouter des serveurs applicatifs. Il faut lancer un conteneur supplementaire un un nom et le linker avec le haproxy:
|
docker run --name appC session-webapp/1.0-SNAPSHOT & docker run --name haproxy --link appA:app1 --link appB:app2 --link appC:app3 --env "UPSTREAMS=3" bcharret/haproxy & |
Il ne me reste plus qu’a travailler sur le lien entre les serveur applicatifs et la base redis.
Comme d’habitude les sources sont ici: https://github.com/BenoitCharret/session-webapp. J’ai ajouté un script start_all.sh et stop_all.sh pour simplifier la mise en route.