Crearem un cluster de docker-engine i instanciarem allà els nostres contenidors docker. A més configurarem un servei balancejat d'alta disponibilitat escalable.
Docker Swarm: Ens permet crear un cluster docker. El node master rebrà i distribuirà els contenidors als nodes secundaris on s'executaran.
Consul: Ens proporcionarà el servei de discover dels nous nodes que afegim al clúster swarm.
Registrator: Aquest servei monitoritzarà la informació com ara IP i PORT de cada servei activat als hosts i ho guardarà al consul.
Docker Compose: Ens permet configurar i crear grups de contenidors.
Requeriments previs
- Docker Engine: Ens permet crear els contenidors, gestionar-los i instanciar-los
- Docker Machine: Ens permet crear i gestionar les maquines virtuals
- Driver Docker Machine Opennebula: Ens permet utilitzar el docker-machine al cloud de l'OpenNebula
- Docker Compose
Instal·lar el requeriments:
- Per a poder implementar el docker swarm cluster amb l'OpenNebula hem d'instalar el Docker Engine, Docker Machine i el Driver Docker Machine Opennebula.
Aquí està el manual de com fer-ho: DOCKER-1 Docker Machine OpenNebula Driver Per instal·lar Docker Compose:
sudo -i curl -L https://github.com/docker/compose/releases/download/1.7.0-rc1/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose chmod +x /usr/local/bin/docker-compose
Consul
Disposarem d'una maquina virtual que ens proporcionarà el servei de discover amb consul
Creem una màquina virtual a l'OpenNebula anomenada consul i deprés executem un contenidor docker de consul dins d'ella.
docker-machine create -d opennebula --opennebula-network-id [network_id] --opennebula-image-id [boot2docker_image_id] --opennebula-b2d-size [volatile_disk_size] consul docker $(docker-machine config consul) run -d -p "8500:8500" -h "consul" progrium/consul -server -bootstrap
Docker Swarm
Diposarem dos tipus de màquines virtuals amb swarm:
- Swarm-master: Aquesta màquina amb swarm serà l'encarregada de distribuir les instàncies dels contenidors als diferents nodes que tinguem al clúster.
- Swarm-node: Aquesta o aquestes màquines seran les que executaran els contenidors docker.
Swarm-master
Creem la màquina virtual del swarm-master:
export CONSUL_IP=$(docker-machine ip consul) docker-machine create -d opennebula --opennebula-network-id [network_id] --opennebula-image-id [boot2docker_image_id] --opennebula-b2d-size [volatile_disk_size] --swarm --swarm-master --swarm-discovery="consul://$CONSUL_IP:8500" --engine-opt cluster-store=consul://$CONSUL_IP:8500 --engine-opt cluster-advertise="eth0:2376" swarm-master
Swarm-node
Creem la màquina virtual del swarm-node:
docker-machine create -d opennebula --opennebula-network-id [network_id] --opennebula-image-id [boot2docker_image_id] --opennebula-b2d-size [volatile_disk_size] --swarm --swarm-discovery="consul://$CONSUL_IP:8500" --engine-opt cluster-store=consul://$CONSUL_IP:8500 --engine-opt cluster-advertise="eth0:2376" swarm-node-1
Podem crear els nodes que vulguem. Només hem de canviar el nom de la màquina virtual
Desplegar contenidors Registrator
Un cop hem creat el master i els diferents nodes, instanciarem els contenidors amb registrator a tot ells:
export MASTER_IP=$(docker-machine ip swarm-master) export NODE_IP=$(docker-machine ip swarm-node-1) eval $(docker-machine env --swarm swarm-master) docker run -d --name=registrator -h ${MASTER_IP} --volume=/var/run/docker.sock:/tmp/docker.sock gliderlabs/registrator:latest consul://${CONSUL_IP}:8500 eval $(docker-machine env swarm-node-1) docker run -d --name=registrator -h ${NODE_IP} --volume=/var/run/docker.sock:/tmp/docker.sock gliderlabs/registrator:latest consul://${CONSUL_IP}:8500
Load Balancer
Ara hem d'implementar un balancejador de càrrega que pugui distribuir les peticions per les diferents instàncies del servei. Com augmentarem i disminuirem les instàncies del servei, necessitem que el balancejador de càrrega s'actualitzi automàticament.
Utilitzarem nginx per al load balancer i consul-template per la configuració del nginx.
default.ctmpl
Primer de tot, necessitem crear un template per a la configuració del nginx. Consul-template automàticament omplirà aquest fitxer amb la informació referent al servei instanciat i crea la configuració pel nginx.
El fitxer default.ctmpl
ha de ser així:
{{$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}}; } }
start.sh
Necessitem un script que actui com a entry point per a questa imatge docker.
El fixer start.sh
ha de ser aixi:
#!/bin/bash service nginx start consul-template -consul=$CONSUL_URL -template="/templates/default.ctmpl:/etc/nginx/conf.d/default.conf:service nginx reload"
Dockerfile
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"]
Docker Compose
Fitxer docker-compose.yml
version: '2' services: lb: build: . container_name: lb ports: - "80:80" environment: - APP_NAME=[Nom_del_servei] - CONSUL_URL=${CONSUL_IP}:8500 depends_on: - web networks: - front-tier web: image: nginx ports: - "[Port_del_servei]" environment: - SERVICE_NAME=[Nom_del_servei] networks: - front-tier networks: front-tier: driver: overlay
docker-compose stop; docker-compose rm -f docker-compose up -d
docker-compose scale web=3
Per a més informació : https://botleg.com/stories/load-balancing-with-docker-swarm/
Exemple d'ús
Actualment disposeu de dues imatges, ja precreades amb el Docker Engine instal·lat que podeu fer servir:
- boot2docker
- Docker-Machine-Ubuntu-14.04
Crear el clúster swarm:
Creem les màquines virtuals de consul, swarm-master i un swarm-node amb discs volàtils de 10 GB amb les comandes:
docker-machine create -d opennebula --opennebula-network-id $NETWORK_ID --opennebula-image-name boot2docker --opennebula-b2d-size 10240 consul docker $(docker-machine config consul) run -d -p "8500:8500" -h "consul" progrium/consul -server -bootstrap CONSUL_IP=$(docker-machine ip consul) docker-machine create -d opennebula --opennebula-network-id $NETWORK_ID --opennebula-image-name boot2docker --opennebula-b2d-size 10240 --swarm --swarm-master --swarm-discovery="consul://$CONSUL_IP:8500" --engine-opt cluster-store=consul://$CONSUL_IP:8500 --engine-opt cluster-advertise="eth0:2376" swarm-master docker-machine create -d opennebula --opennebula-network-id $NETWORK_ID --opennebula-image-name boot2docker --opennebula-b2d-size 10240 --swarm --swarm-discovery="consul://$CONSUL_IP:8500" --engine-opt cluster-store=consul://$CONSUL_IP:8500 --engine-opt cluster-advertise="eth0:2376" swarm-node-01
On $NETWORK_ID, serà l'ID de la xarxa on crearem el clúster.
Després d'executar les comandes podem observar com s'han creat les màquines virtuals al panell de l'OpenNebula o utilitzant docker-machine:
Connectem al docker-swarm i comprovem la informació del cluster:
eval $(docker-machine env --swarm swarm-master) docker info
Creem la xarxa interna del clúster swarm i visualitzem les interfícies virtuals creades:
docker network create --driver overlay --subnet=10.0.1.0/24 overlay_net docker network ls
Ja tenim el clúster swarm configurat i corrent.
Executar contenidors docker al clúster creat:
Ara podem començar a fer servir docker sobre el clúster que acabem de crear:
Utilitzarem un contenidor nginx, per exemple
docker pull nginx docker run --name mynginx -d -p 80:80 nginx
- Podem comprovar com el contenidor s'està executant en un node del clúster:
Per accedir al servei del contenidor hem de posar la direcció IP del node del clúster al navegador