Attention ceci est mon brouillon avant de faire une belle documentation sur Docker (il y a à boire et à manger).
On va utiliser le fichier dynamique fait par ./build_haproxy.bash qui se trouve dans /docker/app/haproxy.cfg (merci de regarder l’épisode précédent n°13 afin de mieux comprendre). Pour le lancement de haxproxy la dernière fois que l’on a vu cela c’était dans le n°10 , la commande était alors :
docker run -d --link my-server4-1 --link my-server4-2 --link my-server4-3 --link my-server4-4 -p 80:80 --name mon-haproxy-v15b my-haproxy-v15
Maintenant on n’a plus besoin de lien car les IP sont écrites par les serveurs eux-mêmes. On a seulement à faire un partage de fichier.
[root@localhost ~]# cat /docker/app/haproxy.cfg
global
maxconn 400
defaults
log 127.0.0.1 local5 debug
mode tcp
retries 4
maxconn 200
timeout connect 5000
timeout client 50000
timeout server 50000
frontend http-in
bind *:80
default_backend serveur
backend serveur
mode tcp
balance roundrobin
server server1 172.17.0.9:80
server server2 172.17.0.10:80
[root@localhost ~]# docker run -d -v /docker/app/haproxy.cfg:/usr/local/etc/haproxy/haproxy.cfg -p 80:80 --name mon-haproxy-v15c my-haproxy-v15
51b94f30c07e4469cdb21039d67ad94e286baa184c195962dbfb1ad26d81ab5c
[root@localhost ~]# telnet 127.0.0.1 80
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
HELLO
INTERFACE
172.17.0.10
QUIT
Connection closed by foreign host.
[root@localhost ~]# telnet 127.0.0.1 80
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
HELLO
INTERFACE
172.17.0.9
QUIT
Connection closed by foreign host.
Conclusion : cela fonctionne ! Le fichier de configuration qui est généré par le script est bien pris en compte par le container haproxy. Pour demander la relecture du fichier de configuration, rien de plus simple :
[root@localhost ~]# docker restart mon-haproxy-v15c mon-haproxy-v15c
Avec l’énorme inconvénient que toutes les sessions en cours sont perdus. Ensuite je travaillerai sur ce point, car on peut imaginer que ce système ne se lance qu’en cas d’urgence. Il faut faire le script qui va compter les sessions et prendre la decision de lancer un nouveau container et de lancer un container à l’arrêt.
Pour lancer un nouveau container rien de plus facile on cherche une inode disponible et un port disponible. Voici un script :
[root@localhost ~]# cat create_container.bash #!/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) fi fi done if [ $status = "KO" ] then echo "Status is KO for $inode" flag="OK" inodestop=$inodeval fi if [ $inodeval -gt $inodemax ] then inodemax=$inodeval fi cd /docker/app/server/ fi done if [ $flag = "KO" ] then echo "On na pas vu de container à l'arret on va donc un faire un nouveau le plus grand étant $inodemax"; inodemax=`expr $inodemax + 1 ` echo "Le nouveau sera donc le $inodemax "; mkdir /docker/app/server/$inodemax port=`expr 8085 + $inodemax ` docker run -p $port:80 --link postgres2:postgres2 -v /docker/app/server/$inodemax:/app/server/ --name my-server7-$inodemax --log-driver=syslog --log-opt tag="my-server7-$inodemax" -d my-server7 fi if [ $flag = "OK" ] then echo "On a vu un container à l'arret on va donc le lancer : $inodestop"; docker start my-server7-$inodemax fi echo "Fin du script";
Et maintenant le test :
[root@localhost ~]# ./create_container.bash
On na pas vu de container à l'arret on va donc un faire un nouveau le plus grand étant 4
Le nouveau sera donc le 5
50dc9fbd7890d24ca0453878134469627116181adc26e56a86661dc879fb7466
Fin du script
[root@localhost ~]# ./create_container.bash
On na pas vu de container à l'arret on va donc un faire un nouveau le plus grand étant 5
Le nouveau sera donc le 6
b7edb8b9405d5f6665505e36b5179172201260a1eecf06446abaf9cb6256bc05
Fin du script
[root@localhost ~]# ./create_container.bash
On na pas vu de container à l'arret on va donc un faire un nouveau le plus grand étant 6
Le nouveau sera donc le 7
f806c2ed062c0f1bc5a105923b3e2b410d3cfc656bbaa329c8f55c47e4ca736b
Fin du script
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f806c2ed062c my-server7 "/sbin/server7" 14 seconds ago Up 14 seconds 0.0.0.0:8092->80/tcp my-server7-7
b7edb8b9405d my-server7 "/sbin/server7" 15 seconds ago Up 15 seconds 0.0.0.0:8091->80/tcp my-server7-6
50dc9fbd7890 my-server7 "/sbin/server7" 18 seconds ago Up 18 seconds 0.0.0.0:8090->80/tcp my-server7-5
4ec165c67c25 my-server7 "/sbin/server7" 40 seconds ago Up 40 seconds 0.0.0.0:8089->80/tcp my-server7-4
bdf7cd9d64a7 my-server7 "/sbin/server7" About a minute ago Up About a minute 0.0.0.0:8088->80/tcp my-server7-3
51b94f30c07e my-haproxy-v15 "/docker-entrypoint.s" About an hour ago Up About an hour 0.0.0.0:80->80/tcp mon-haproxy-v15c
cf1110c0f435 my-server7 "/sbin/server7" 4 hours ago Up 4 hours 0.0.0.0:8087->80/tcp my-server7-2
c6181abdea21 my-server7 "/sbin/server7" 4 hours ago Up 4 hours 0.0.0.0:8086->80/tcp my-server7-1
2912a5b6f004 my-server6 "/sbin/server6" 13 hours ago Up 13 hours 0.0.0.0:8085->80/tcp my-server6-1
a814b5991a87 my-server5 "/sbin/server5" 14 hours ago Up 14 hours 0.0.0.0:8084->80/tcp my-server4-5
eb76431e86e0 my-server5 "/sbin/server5" 17 hours ago Up 17 hours 0.0.0.0:8083->80/tcp my-server4-4
1e87ae6b009b my-server5 "/sbin/server5" 17 hours ago Up 17 hours 0.0.0.0:8082->80/tcp my-server4-3
5b9099ae80d0 my-server5 "/sbin/server5" 17 hours ago Up 17 hours 0.0.0.0:8081->80/tcp my-server4-2
4fb8f79456af my-server5 "/sbin/server5" 17 hours ago Up 17 hours 0.0.0.0:8080->80/tcp my-server4-1
2fc533c55725 postgres "/docker-entrypoint.s" 39 hours ago Up 39 hours 0.0.0.0:5432->5432/tcp postgres2
[root@localhost ~]# docker stop my-server7-6
my-server7-6
[root@localhost ~]# ./create_container.bash
On na pas vu de container à l'arret on va donc un faire un nouveau le plus grand étant 7
Le nouveau sera donc le 8
d85bf7ea1bf7497312a2c27c9438bc4d8c7e695f85984b7cf1f9880f9098cf69
Fin du script
1460804275
[root@localhost ~]# cat /docker/app/server/6/status
OK
[root@localhost ~]# cat /docker/app/server/6/time
1460804219
[root@localhost ~]# cat /docker/app/server/6/time
1460804219
[root@localhost ~]#
Visiblement le « status » n’est pas à KO quand il est arrêté via la commande docker propre (après le stop du my-server7-6 je n’aurais pas du avoir la création du n°8). Il va donc falloir utiliser le temps afin de voir que tout fonctionne bien.
Mais avant cela je vous propose un instant méditation : Pensez-vous qu’il soit aussi facile avec VM Ware de déployer 3 serveurs ? Et ceci via une ligne de commande ? Pensez-vous qu’il soit aussi facile de prendre en compte ses nouveaux serveurs via un script fait en quelques minutes ? En plus de faire un déploiement cette ligne de commande fait aussi un partage de fichier, pour avoir l’équivalent avec VM Ware il faudrait monter un serveur SAMBA. Il nous reste encore à voir les autres grands avantages à savoir la mise à jour automatique, la répartition de charge entre serveurs dockers. Et l’autre avantage c’est de pouvoir faire un script qui permet par exemple de mettre tous les serveurs en mode débug. Je pense que cela commence à vous plaire, moi aussi 🙂 . Mais aussi on pourrait parler de l’espace disque :
[root@localhost ~]# docker history my-server7 IMAGE CREATED CREATED BY SIZE COMMENT b3b4e7faef2f 6 hours ago /bin/sh -c #(nop) CMD ["/sbin/server7"] 0 B 0ca55d5c158d 6 hours ago /bin/sh -c #(nop) EXPOSE 80/tcp 0 B 7c369e74da08 6 hours ago /bin/sh -c dnf install postgresql -y 162.6 MB d111ddce9aa0 6 hours ago /bin/sh -c #(nop) COPY file:bffd0481c43858dd3 23.47 kB bb6bc55cbbfc 41 hours ago /bin/sh -c #(nop) MAINTAINER toto toto@cyber- 0 B ddd5c9c1d0f2 6 weeks ago /bin/sh -c #(nop) ADD file:bcb5e5cddd4c4d1cac 204.7 MB 6 weeks ago /bin/sh -c #(nop) MAINTAINER Patrick Uiterwij 0 B
On doit être dans les 400 Mo, la même chose avec VM Ware et on est dans les 2 Go…On arrête l’instant méditation ;).
Maintenant je vais proposer une version server8 (server8.c) qui écrit KO ! pour cela je vais utiliser la fonction atexit(). Par contre je vais appeler cette version server7 afin de montrer l’utilité de la version dans le fichier dynamique. J’en profite aussi pour ajouter un nouveau fichier dynamique qui indique le nombre de client traité et un fichier dynamique error permettant d’avoir le code de sortie.
server8 : le source du programme (j’arrête les copies directes dans WordPress car cela commence a être volumineux).
Compilation et test :
[root@localhost ~]# gcc -o server8 server8.c -lpq [root@localhost ~]# ./server8 Default interface is : enp0s3 Local ip is : 192.168.10.159 POSTGRES2_PORT_5432_TCP_ADDR : (null) Stdout is descriptor 1 Stderr is descriptor 2 Stdout is descriptor 1 Stderr is descriptor 2 OK : Table STATISTIQUE ^CFin du programme [ END : CTRL-C] [root@localhost ~]# cat /app/server/status KO[root@localhost ~]# cat /app/server/error 11
Parfait cela fonctionne ! Maintenant je vais déployer cette superbe version, on s’approche de la version « gold » 😉 . Attention cette fois je fais mettre la version 8 dans le my-server7 .
[root@localhost ~]# cat Dockerfile FROM fedora MAINTAINER toto toto@cyber-neurones.org COPY ./server8 /sbin/server8 RUN dnf install postgresql -y # Le port en ecoute EXPOSE 80 # Pour lancer postgres CMD ["/sbin/server8"] [root@localhost ~]# docker build -t my-server7 . Sending build context to Docker daemon 380.9 kB Step 1 : FROM fedora ---> ddd5c9c1d0f2 Step 2 : MAINTAINER toto toto@cyber-neurones.org ---> Using cache ---> bb6bc55cbbfc Step 3 : COPY ./server8 /sbin/server8 ---> bce16fb36408 Removing intermediate container d7411590d297 Step 4 : RUN dnf install postgresql -y ---> Running in ca2051c554ae .... Complete! ---> b4511089849d Removing intermediate container 06ba37adc88b Step 5 : EXPOSE 80 ---> Running in 9a94125adc6b ---> a1834ef7e456 Removing intermediate container 9a94125adc6b Step 6 : CMD /sbin/server8 ---> Running in 9a1a3c3e7dbe ---> 2dbb7ecbdaa1 Removing intermediate container 9a1a3c3e7dbe Successfully built 2dbb7ecbdaa1
La suite demain 😉
Pour finir le squelette du script qui va être dans la crontab :
[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)) if [ $pourc -eq 0 ] then if [ $max -gt 10 ] then echo "On peut arreter des serveurs"; # script a écrire # on refait la conf de haproxy et on relance. fi fi if [ $pourc -gt 70 ] then echo "On doit faire un nouveau container" # create_container.bash echo "On refait la configuration de haproxy" # build_haproxy.bash echo "On recharge haproxy" # docker restart mon-haproxy-v15c fi echo "Fin du script"; [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 Status is OK for 4: max 5 load 0 Status is OK for 5: max 5 load 0 Status is OK for 6: max 5 load 0 Status is OK for 7: max 5 load 0 Status is OK for 8: max 5 load 0 La charge actuelle est de 0/40 On peut arreter des serveurs Fin du script
Il nous faut donc écrire le script d’arrêt d’un container.