En esta ocasión crearemos un pequeño stack para dockerizar joomla, usaremos 2 contenedores Docker, uno para el joomla y otro la base de datos mysql. Lo levantaremos en un cluster para que cada uno de ellos este en una máquina diferente.
Primero debemos nuestro cluster de máquinas, puede seguir nuestro artículo Redes con varios hosts con contenedores Docker y realizar los pasos 1 y 2.
Debería tener las siguientes máquinas ejecutándose:
docker-machine ls
NAME ACTIVE DRIVER STATE URL SWARM DOCKER ERRORS
mh-keystore - virtualbox Running tcp://192.168.99.100:2376 v1.11.2
mhs-demo0 - virtualbox Running tcp://192.168.99.101:2376 mhs-demo0 (master) v1.11.2
mhs-demo1 - virtualbox Running tcp://192.168.99.102:2376 mhs-demo0 v1.11.2
Creamos un ficher docker-compose.yml para definir nuestro stack de contenedores Docker:
version: '2'
services:
web:
image: joomla
ports:
- 8080:80
environment:
- JOOMLA_DB_HOST=joomladb
- JOOMLA_DB_PASSWORD=test
depends_on:
- joomladb
networks:
- back-tier
joomladb:
image: mysql:5.6
environment:
MYSQL_ROOT_PASSWORD: test
volumes:
- mysql-data:/var/lib/mysql
networks:
- back-tier
volumes:
mysql-data:
driver: local
networks:
back-tier:
driver: overlay
El primer servicio es web y contiene la imagen joomla, mapeará el puerto 8080, se ha configurado un par de variables, uno para indicar el host del mysql y otro para la contraseña del root.
El segundo servicio es una imagen de mysql. Hemos creado un volumen de nombre mysql-data de tipo local, así los datos se persistirán en el sistema de ficheros local.
Los servicios en la misma red son enlazables, en este caso ambos servicios estan en la red back-tier, la cual es de tipo overlay, este tipo de red permite realizar multi-host, esto permite que los servicios sean enlazables entre diferentes hosts.
Luego conectaremos el Docker Client al Docker Engine de la máquina master:
$ eval $(docker-machine env --swarm mhs-demo0)
Y levantar el stack de contededores docker:
$ docker-compose up -d
Creating network "joomla_back-tier" with driver "overlay"
Creating volume "joomla_mysql-data" with local driver
Pulling joomladb (mysql:5.6)...
mhs-demo1: Pulling mysql:5.6... : downloaded
mhs-demo0: Pulling mysql:5.6... : downloaded
Creating joomla_joomladb_1
Pulling web (joomla:latest)...
mhs-demo1: Pulling joomla:latest... : downloaded
mhs-demo0: Pulling joomla:latest... : downloaded
Creating joomla_web_1
Si listamos los contenedores que se estan ejecutando se apreciará que cada uno de los contenedores docker se ha instanciado en diferentes máquinas:
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
e4b8435f0487 joomla "/entrypoint.sh apach" 27 seconds ago Up 26 seconds 192.168.99.101:8080->80/tcp mhs-demo0/joomla_web_1
e9916f7f08a2 mysql:5.6 "docker-entrypoint.sh" 2 minutes ago Up 2 minutes 3306/tcp mhs-demo1/joomla_joomladb_1
Como se puede observar al levantar el stack de contenedores Docker cada uno de los contenedores se ha instalado en diferentes máquinas, el joomla en la mhs-demo0 y base de datos en la mhs-demo1.
Si quiere usar el browser para ver la web de joomla, deberá ir a la ip de la máquina mhs-demo0 con el puerto 8080 que se definio en el docker-compose.yml:
http://192.168.99.101:8080/
Y verá el instalador de joomla.
Balanceador de carga
Hasta ahora tenemos una simple instancia de joomla ejecutándose. Necesitamos implementar un balanceador de carga que permita distribuir el tráfico a través de todas las instancias de este servicio. Usaremos la imagen hanzel/load-balancing-swarm.
Hay varias alternativas para balanceadores de carga, como consul o HAproxy, en esta ocasión usaremos nginx para balancear y consul-template para administrar la configuración de nginx.
Entonces vamos a construir el balanceador de carga a partir de una imagen nginx, para ello vamos a crear el archivo de configuración default.ctmpl, un bash script que usaremos de entry point para el contenedor Docker.
Archivo default.ctmpl para la configuración de nginx, tal como:
{{$app := env "APP_NAME"}}
upstream {{printf $app}} {
least_conn;
{{range service $app}}
server {{.Address}}:{{.Port}} max_fails=3 fail_timeout=60 weight=1;{{end}}
}
server {
listen 80 default;
location / {
proxy_pass http://{{printf $app}};
}
}
Bash script que usará de entry point para la imagen:
#!/bin/bash
service nginx start
consul-template --consul=$CONSUL_URL -template="/template/default.ctmpl:/etc/nginx/conf.d/default.conf:service nginx reload"
Y el Dockerfile con la información para construir la imagen:
FROM nginx:latest
RUN apt-get update \
&& apt-get install -y unzip
ADD files/start.sh /bin/start.sh
RUN chmod +x /bin/start.sh
ADD files/default.ctmpl /templates/default.ctmpl
ADD https://releases.hashicorp.com/consul-template/0.12.2/consul-template_0.12.2_linux_amd64.zip /usr/bin/
RUN unzip /usr/bin/consul-template_0.12.2_linux_amd64.zip -d /usr/local/bin
EXPOSE 80
ENTRYPOINT ["/bin/start.sh"]
Para construir la imagen de nuestro balanceador de carga lb a partir de los archivos previamente creados Dockerfile, default.ctmpl, start.sh.
$ docker build -t load-balance-swarm .
Step 1 : FROM nginx:latest
---> 0d409d33b27e
Step 2 : RUN apt-get update && apt-get install -y unzip
---> Using cache
---> 7e163fd73834
Step 3 : ADD lb/start.sh /bin/start.sh
---> Using cache
---> 0a56cd8a2965
Step 4 : RUN chmod +x /bin/start.sh
---> Using cache
---> 94bb63044a65
Step 5 : ADD lb/default.ctmpl /templates/default.ctmpl
---> Using cache
---> 06f863377456
Step 6 : ADD https://releases.hashicorp.com/consul-template/0.12.2/consul-template_0.12.2_linux_amd64.zip /usr/bin/
---> Using cache
---> df945c1fdee2
Step 7 : RUN unzip /usr/bin/consul-template_0.12.2_linux_amd64.zip -d /usr/local/bin
---> Using cache
---> ac9e7cd3b7f1
Step 8 : EXPOSE 80
---> Using cache
---> 2055813afb33
Step 9 : ENTRYPOINT /bin/start.sh
---> Using cache
---> 79f6283cb4d4
Successfully built 79f6283cb4d4
Debe subir su imagen a un repositorio de imagenes Docker, en nuestro caso usuarios nuestro servicio DonDocker.com, puede crearse una cuenta cp.dondocker.com. Luego de tener su cuenta haga un login y suba su imagen:
$ docker tag load-balance-swarm hub.dondocker.com/dondocker/load-balance-swarm
$ docker login -u <tu-usuario> -p <tu-password> hub.dondocker.com
$ docker push hub.dondocker.com/dondocker/load-balance-swarm
O puede utilizar la imagen hanzel/load-balancing-swarm
Vamos a realizar unos cambios en el archivo docker-compose.yml:
version: '2'
services:
lb:
image: hanzel/load-balancing-swarm
container_name: lb
ports:
- "80:80"
environment:
- constraint:node==mhs-demo0
- APP_NAME=joomla-mysql
- CONSUL_URL=${KV_IP}:8500
depends_on:
- web
networks:
- front-tier
web:
image: joomla
#ports:
#- "80"
environment:
- JOOMLA_DB_HOST=joomladb
- JOOMLA_DB_PASSWORD=test
depends_on:
- joomladb
networks:
- front-tier
- back-tier
joomladb:
image: mysql:5.6
container_name: joomladb
environment:
MYSQL_ROOT_PASSWORD: test
volumes:
- mysql-data:/var/lib/mysql
networks:
- back-tier
volumes:
mysql-data:
driver: local
networks:
front-tier:
driver: overlay
back-tier:
driver: overlay
La variable de entorno ** constraint:node==mhs-demo0** indica que el contenedor se ejecute en el node mhs-demo0. Se ha añadido una nueva network front-tier que permitirá enlazar el contenedor balanceador de carga y el joomla. La variable KV_IP indica la IP de la máquina que contiene el contenedor consul, la podemos setear de la siguiente forma:
export KV_IP=$(docker-machine ssh mh-keystore 'ifconfig eth1 | grep "inet addr:" | cut -d: -f2 | cut -d" " -f1')
Ahora levantaremos el stack de contendedores Docker:
$ docker-compose up -d
Creating volume "joomla_mysql-data" with local driver
Creating joomladb
Creating joomla_web_1
Creating lb
...
$ docker-compose ps
Name Command State Ports
joomla_web_1 /entrypoint.sh apache2-for ... Up 80/tcp
joomladb docker-entrypoint.sh mysqld Up 3306/tcp
lb /bin/start.sh Up 443/tcp, 192.168.99.101:80->80/tcp
Podríamos scalar el servicio de joomla con el siguiente comando:
$ docker-compose scale web=3
Creating and starting 2 ... done
Creating and starting 3 ... done
$ docker-compose ps
Name Command State Ports
joomla_web_1 /entrypoint.sh apache2-for ... Up 80/tcp
joomla_web_2 /entrypoint.sh apache2-for ... Up 80/tcp
joomla_web_3 /entrypoint.sh apache2-for ... Up 80/tcp
joomladb docker-entrypoint.sh mysqld Up 3306/tcp
lb /bin/start.sh Up 443/tcp, 192.168.99.101:80->80/tcp
Como hemos visto swarm nos permite escalar y distribuir la carga de trabajo en un grupo de hosts de forma sencilla.
Los esperamos en el próximo artículo. Aún no nos sigues en twitter? Síguenos @dondocker
Comentarios recientes