Attention ceci est mon brouillon avant de faire une belle documentation sur Docker (il y a à boire et à manger).
Maintenant il me faut faire un script d’arrêt des containers, on va donc arrêter un container qui a le status à OK et qui a une charge de 0.
Voici le script que je propose, ce script permet en plus de fixer notre bug sur la précédente version ;) .
#!/bin/bash
cd /docker/app/server/
i=0
flag="KO"
inodemax=0
inodestop=0
for inode in $(ls -R)
do
if
[ -d $inode ]
then
cd $inode
inodeval=$(echo $inode);
status="KO"
for filename in $(ls -R)
do
if
[ -f $filename ]
then
if [ $filename = "status" ]
then
status=$(cat /docker/app/server/$inode/$filename)
load=$(cat /docker/app/server/$inode/load)
fi
fi
done
if [ $status = "OK" ]
then
echo "Status is OK for $inode"
if [ $load = 0 ]
then
echo "Il n'y a pas de charge $load"
flag="OK"
inodestop=$inodeval
fi
fi
cd /docker/app/server/
fi
done
if [ $flag = "OK" ]
then
echo "On va arreter ce containter : $inodestop";
docker stop my-server7-$inodestop
#Pour fixer notre bug ;)
echo "KO" > /docker/app/server/$inodestop/status
fi
echo "Fin du script";
Et un petit test :
[root@localhost ~]# ./stop_container.bash
Status is OK for 1
Il n'y a pas de charge 0
Status is OK for 2
Il n'y a pas de charge 0
Status is OK for 3
Il n'y a pas de charge 0
Status is OK for 4
Il n'y a pas de charge 0
Status is OK for 5
Il n'y a pas de charge 0
Status is OK for 6
Il n'y a pas de charge 0
On va arreter ce containter : 6
my-server7-6
Fin du script
[root@localhost ~]# ./stop_container.bash
Status is OK for 1
Il n'y a pas de charge 0
Status is OK for 2
Il n'y a pas de charge 0
Status is OK for 3
Il n'y a pas de charge 0
Status is OK for 4
Il n'y a pas de charge 0
Status is OK for 5
Il n'y a pas de charge 0
On va arreter ce containter : 5
my-server7-5
Fin du script
Maintenant je place tous les scripts dans /docker/scripts/ (c’est plus propre que sous /root/)
[root@localhost ~]# mkdir /docker/scripts
[root@localhost ~]# cp *.bash /docker/scripts/.
[root@localhost ~]# ls /docker/scripts/
build_haproxy.bash create_container.bash stop_container.bash test_load.bash view_load.bash
Et je finalise mon script test_load.bash :
[root@localhost ~]# cat test_load.bash
#!/bin/bash
cd /docker/app/server/
i=0
load=0
max=0
for inode in $(ls -R)
do
if
[ -d $inode ]
then
cd $inode
status="KO"
for filename in $(ls -R)
do
if
[ -f $filename ]
then
if [ $filename = "status" ]
then
status=$(cat /docker/app/server/$inode/$filename)
cload=$(cat /docker/app/server/$inode/load)
cmax=$(cat /docker/app/server/$inode/max)
fi
fi
done
if [ $status = "OK" ]
then
echo "Status is OK for $inode: max $cmax load $cload"
load=`expr $load + $cload`
max=`expr $max + $cmax`
fi
cd /docker/app/server/
fi
done
echo "La charge actuelle est de $load/$max";
pourc=$(( $load * 100 / $max))
echo "$load/$max" >> /docker/scripts/log.txt
#On fixe le seuil à 0% ce qui est extrême on devrait surement mettre 25%
if [ $pourc -eq 0 ]
then
# On fixe le minimum à 10 ressources.
if [ $max -gt 10 ]
then
logger -t CheckLoad "On n'a plus de charge on stoppe un container"
echo "On peut arreter des containers";
/docker/scripts/stop_container.bash
echo "On refait la configuration de haproxy"
/docker/scripts/build_haproxy.bash
echo "On recharge haproxy"
docker restart mon-haproxy-v15c
fi
fi
#On fixe le seuil a 70% avant de lancer de nouveaux containers
if [ $pourc -gt 70 ]
then
logger -t CheckLoad "On a de la charge on lance un container"
echo "On doit faire un nouveau container"
/docker/scripts/create_container.bash
echo "On refait la configuration de haproxy"
/docker/scripts/build_haproxy.bash
echo "On recharge haproxy"
docker restart mon-haproxy-v15c
fi
echo "Fin du script";
Et notre phase de test :
[root@localhost ~]# ./test_load.bash
Status is OK for 1: max 5 load 0
Status is OK for 2: max 5 load 0
Status is OK for 3: max 5 load 0
La charge actuelle est de 0/15
On peut arreter des containers
Status is OK for 1
Il n'y a pas de charge 0
Status is OK for 2
Il n'y a pas de charge 0
Status is OK for 3
Il n'y a pas de charge 0
On va arreter ce containter : 3
my-server7-3
Fin du script
Fin du script
[root@localhost ~]# grep "CheckLoad" /var/log/messages
Apr 16 15:20:44 localhost CheckLoad: On n'a plus de charge on stoppe un container
On passe donc ce script dans la crontab.
[root@localhost ~]# crontab -l
* * * * * /docker/scripts/test_load.bash
On lance notre logiciel de charge :
[root@localhost ~]# ./client_stress localhost 80
Start
Nombre 500 le temps 2
Nombre 1000 le temps 4
Nombre 1500 le temps 6
Nombre 2000 le temps 8
Nombre 2500 le temps 13
Nombre 3000 le temps 17
Nombre 3500 le temps 22
Nombre 4000 le temps 26
Nombre 4500 le temps 30
Nombre 5000 le temps 35
Nombre 5500 le temps 39
Nombre 6000 le temps 41
Nombre 6500 le temps 46
Nombre 7000 le temps 50
Nombre 7500 le temps 54
Nombre 8000 le temps 57
Nombre 8500 le temps 64
Nombre 9000 le temps 70
^C
Vous avez du nouveau courrier dans /var/spool/mail/root
[root@localhost ~]# tail -f /docker/scripts/log.txt
0/10
0/10
0/10
1/10
1/10
4/10
4/10
On ne peut pas dire que cela soit le gros stress, ce qui est normal car on n’a qu’une tâche qui fait le stress. On va donc faire un petit script pour un plus gros stress ;) Voici le script que je vous propose, j’arrête après 120 secondes le test :
[root@localhost ~]# cat gros_stress.bash
#!/bin/bash
timeout 120 ./client_stress localhost 80 &
timeout 120 ./client_stress localhost 80 &
timeout 120 ./client_stress localhost 80 &
timeout 120 ./client_stress localhost 80 &
timeout 120 ./client_stress localhost 80 &
timeout 120 ./client_stress localhost 80 &
timeout 120 ./client_stress localhost 80 &
timeout 120 ./client_stress localhost 80 &
timeout 120 ./client_stress localhost 80 &
timeout 120 ./client_stress localhost 80 &
timeout 120 ./client_stress localhost 80 &
timeout 120 ./client_stress localhost 80 &
timeout 120 ./client_stress localhost 80 &
timeout 120 ./client_stress localhost 80 &
timeout 120 ./client_stress localhost 80 &
timeout 120 ./client_stress localhost 80
echo "Fin de la charge"
Le résultat :
[root@localhost ~]# ./gros_stress.bash
Start
Start
Start
Start
Start
...
Nombre 1500 le temps 99
Nombre 1500 le temps 119
Fin de la charge
Vous avez du nouveau courrier dans /var/spool/mail/root
Les logs :
[root@localhost ~]# tail -f /docker/scripts/log.txt
3/10
4/10
0/10
0/10
4/10
4/10
0/10
4/10
4/10
2/10
Visiblement j’ai un bugs :( La charge ne monte jamais au dessus de 4 alors que j’ai 16 process en parallèle. Je vais donc passer sur la dernière version de serveur (server8) pour avoir plus d’information. Au passage je vais faire un script pour mettre le debug et le syslog à 0 sur tous les serveurs.
[root@localhost ~]# ./gros_stress.bash
Start
Start
Start
Start
Start
Start
Start
Start
Start
Start
Start
Start
Start
Start
Start
Start
Nombre 500 le temps 6
Nombre 500 le temps 6
Nombre 500 le temps 7
Nombre 500 le temps 8
Nombre 500 le temps 8
Nombre 500 le temps 8
Nombre 500 le temps 8
Nombre 500 le temps 8
Nombre 500 le temps 8
Nombre 500 le temps 8
Nombre 500 le temps 8
Nombre 500 le temps 8
Nombre 500 le temps 8
Nombre 1000 le temps 9
Nombre 500 le temps 9
Nombre 1000 le temps 9
Nombre 1000 le temps 14
Nombre 1000 le temps 15
Nombre 1000 le temps 17
Nombre 1000 le temps 18
connect: Connection refused
connect: Connection refused
connect: Connection refused
connect: Connection refused
Nombre 1000 le temps 19
Fin de la charge
Vous avez du nouveau courrier dans /var/spool/mail/root
Nombre 500 le temps 24
Nombre 1000 le temps 27
Nombre 1500 le temps 30
Nombre 1000 le temps 32
Nombre 2000 le temps 32
Nombre 1500 le temps 33
Nombre 1500 le temps 35
Nombre 2500 le temps 35
Nombre 2000 le temps 36
Nombre 2000 le temps 37
Nombre 3000 le temps 37
Nombre 2500 le temps 40
Nombre 1000 le temps 41
Nombre 1000 le temps 42
Nombre 2500 le temps 43
Nombre 1500 le temps 51
Nombre 3500 le temps 51
Nombre 3000 le temps 59
Nombre 1500 le temps 61
Nombre 3000 le temps 72
Nombre 1500 le temps 88
Nombre 4000 le temps 88
Nombre 2000 le temps 97
Vous avez du nouveau courrier dans /var/spool/mail/root
Nombre 2000 le temps 110
Nombre 4500 le temps 111
On observe une coupure du haxproxy ce qui est normal car on le relance, ensuite si on regarde les logs :
[root@localhost ~]# tail -f /docker/scripts/log.txt
0/0
0/0
0/0
0/20
11/15
8/20
8/20
0/20
0/15
0/10
[root@localhost ~]# grep "CheckLoad" /var/log/messages | tail -n3
Apr 16 16:22:01 localhost CheckLoad: On a de la charge on lance un container
Apr 16 16:25:01 localhost CheckLoad: On n'a plus de charge on stoppe un container
Apr 16 16:26:01 localhost CheckLoad: On n'a plus de charge on stoppe un container
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dc75f255cd90 my-server7 "/sbin/server8" 8 minutes ago Up 8 minutes 0.0.0.0:8087->80/tcp my-server7-2
1f84fca3adf1 my-server7 "/sbin/server8" 8 minutes ago Up 8 minutes 0.0.0.0:8086->80/tcp my-server7-1
51b94f30c07e my-haproxy-v15 "/docker-entrypoint.s" 5 hours ago Up 7 minutes 0.0.0.0:80->80/tcp mon-haproxy-v15c
2fc533c55725 postgres "/docker-entrypoint.s" 44 hours ago Up 44 hours 0.0.0.0:5432->5432/tcp postgres2
Le point a régler c’est l’arrêt du haxproxy. Mais le but c’était de démontrer la facilité de monter et démonter un container. L’utilisation de script simplifie grandement la vie !
Un dernier script pour arrêter le mode débug et syslog sur tous les containers :
[root@localhost ~]# cat stop_debug.bash
#!/bin/bash
cd /docker/app/server/
i=0
load=0
max=0
for inode in $(ls -R)
do
if
[ -d $inode ]
then
cd $inode
status="KO"
for filename in $(ls -R)
do
if
[ -f $filename ]
then
if [ $filename = "status" ]
then
status=$(cat /docker/app/server/$inode/$filename)
debug=$(cat /docker/app/server/$inode/debug)
syslog=$(cat /docker/app/server/$inode/syslog)
fi
fi
done
if [ $status = "OK" ]
then
echo "Stop syslog ($syslog) et debug ($debug) sur $inode"
echo 0 > /docker/app/server/$inode/debug
echo 0 > /docker/app/server/$inode/syslog
fi
cd /docker/app/server/
fi
done
echo "Fin du script";
Le test comme toujours :
[root@localhost ~]# ./stop_debug.bash
Stop syslog (1) et debug (1) sur 1
Stop syslog (1) et debug (1) sur 2
Fin du script
[root@localhost ~]# ./stop_debug.bash
Stop syslog (0) et debug (0) sur 1
Stop syslog (0) et debug (0) sur 2
Fin du script
Normalement sur ses 15 jours de test de docker, j’ai pu vous faire partager de l’administration de docker, VirtualBox, Oracle Linux, HAproxy, PostgreSQL, …. Mais aussi de développement de script et de programme en C. Maintenant si j’ai le courage il va falloir faire un article propre. Je pense qu’un bon exemple simple est plus parlant pour justifier le bien fondé de nouvelle technologie. Il me reste à voir le “docker commit”, “docker push”, “docker pull”, ceci devrait permettre de voir l’avantage du déploiement sur docker. Mais aussi la répartition de charge entre deux serveurs Dockers.
Un petit schéma pour expliquer ce que l’on a mis en place :
- une crontab (via un script) qui lance/arrête des containers en fonction de la charge. Cette crontab fait aussi la création du fichier de configuration de haxproxy et relance celui-ci.
- un container haxproxy qui réparti la charge sur tous les containers server8.
- des containers server8 qui utilisent le superbe protocole “Hello World” dont je devrais avoir des royalties ;). Et les serveurs utilisent un partage de fichier afin de remonter les informations de leur status à l’OS (Oracle Linux).
Si vous êtes encore bloqué avec le problème du HAproxy qui ne répond pas, vous avez une première solution qui est de mettre trois HAproxy. Un premier HAproxy qui n’est jamais arrêté qui pointe sur deux autres HAproxy qui lisent la configuration et qui sont relancés à chacun son tour :). Mais la meilleure solution cela semble être la version HAproxy-LUA. La syntaxe doit être :
global
lua-load mes-conteneurs.lua
listen proxy
bind 127.0.0.1:80
tcp-request inspect-delay 1s
tcp-request content use-service lua.mes-conteneurs
Je suis pas encore un expert de HAproxy mais il doit exister plusieurs solutions à ce problème de coupure.
