Page tree

Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Panel
titleColor#FFF
titleBGColor#2A7886
titleContinguts

Table of Contents
maxLevel2

 

 

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 i serveis 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. Podem escalar el servei ofert per un contenir augmentar o disminuint el nombre de contenidors.

  

Image Added

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:

    Code Block
    languagebash
    themeRDark
    sudo -i
    curl -L https://github.com/docker/compose/releases/download/1.6.2/docker-compose-`uname -s`-`uname -m` > /usr/local/bin/docker-compose
    chmod +x /usr/local/bin/docker-compose
    exit

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.

Code Block
languagebash
themeRDark
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:

Code Block
languageperl
themeRDark
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:

Code Block
languageperl
themeRDark
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. Utilitzarem la image de gliderlabs/registrator

Necessitem tenir un servei Registrator corrent en cada host per monitoritzar tots el serveis que corre cada host. 

Code Block
languageperl
themeRDark
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 crearà la configuració pel nginx.

El fitxer default.ctmpl ha de ser així:

Code Block
languageperl
themeRDark
{{$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}};
    }
}

Crearem la variable app amb el valor de la variable d'entorn APP_NAME (definida més endavant al fitxer docker-compose.yml). També crearem un upstream amb el nom de la variable app. La linia least_conn fa que nginx encamini el traffic cap a l'instancia amb menys connexions.

Per cada instancia del servei corrent crearem una linia amb l'adreça del node on s'executa ({{.Address}}) i el port per on està escoltant ({{.Port}}).

Finalment està la zona de configuració del servidor. Aqui definim el port d'escolta del load balancer i creare una reverse proxy a l'upstream que hem creat.

start.sh

Necessitem un script que actui com a entry point per a questa imatge docker.  

El fixer start.sh ha de ser aixi:

Code Block
languageperl
themeRDark
#!/bin/bash
service nginx start
consul-template -consul=$CONSUL_URL -template="/templates/default.ctmpl:/etc/nginx/conf.d/default.conf:service nginx reload"

Aquest script engega primer el servei nginx. Després engega consul-template passant-li dos paràmetres:

  • -consul: Li passem la variable d'entorn $CONSURL_URL definida al docker-compose.yml
  • -template: Li passem 3 paràmetres: el path on està el template que hem creat anteriorment (dins del contenidor), el path on es guardarà el fitxer de configuració generat i la comanda que s'executarà un cop es generi una nova configuració.

El consul-template crearà un nou fitxer de configuració cada cop que un servei s'engegui o s'aturi. La informació sobre aquests serveis es recollida per el servei registrator de cada node swarm i es emmagatzemada en el consul.


Note
El fitxers start.sh i default.ctmpl els guardarem en un directori anomenat "files". En el directori pare hi guardarem els fitxers Dockerfile i docker-compose.yml

Dockerfile  


Code Block
languageperl
themeRDark
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"]

Aquest Dockerfile utilitza nginx com a imatge base i instal·la consul-template damunt. Després copia l'script start.sh i el template default.ctmpl (que abans hem creat) dins del contenidor. Finalment exposa el port 80 i defineix el script start.sh com a entry point de la imatge.

Docker Compose

Docker Compose ens permet escriure la configuració que volem que tinguin els contenidors a desplegar. Utilitzarem Docker Compose File version 2, que ens permet definir la configuració referent a la xarxa, volums, ports, variables d'entorn.

Per saber més sobre la versió 2 del fitxer de docker-compose, vés aqui.

docker-compose.yml

Exemple de docker-compose.yml

Code Block
languageperl
themeRDark
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: [imatge_docker] 
    ports:
      - "[Port_del_servei]"
    environment:
      - SERVICE_NAME=[Nom_del_servei]
    networks:
      - front-tier
networks:
  front-tier:
    driver: overlay

Gestionar Docker Compose

Per arrencar tots el serveis executem el següent.

Per a veure els detalls dels serveis corrent podem utilitzar la comanda docker-compose ps

Code Block
languageperl
themeRDark
eval $(docker-machine env -swarm swarm-master)
docker-compose up -d
docker-compose ps

 Per parar i eliminar els serveis que estan corrent actualment:

Code Block
languageperl
themeRDark
docker-compose stop; docker-compose rm -f

Ara mateix només tenim una instància del servei. Si volem augmentar o disminuir

Code Block
languageperl
themeRDark
docker-compose scale [nom servei]=[nombre d'instancies]


Per a més informació : https://botleg.com/stories/load-balancing-with-docker-swarm/

Exemple d'ús

 Volem crear un cluster de docker i crear un servei web balancejat amb nginx i escalable amb docker Compose.

Actualment disposeu de dues imatges, ja precreades amb el Docker Engine instal·lat que podeu fer servir:


 

  • Creem les màquines virtuals de consul, swarm-master i un swarm-node:

Code Block
languagebash
themeEmacs
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
export 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-1
     --opennebula-b2d-size 10240: Creem discos volàtils de 10GB

 

Warning

On $NETWORK_ID, serà l'ID de la xarxa on crearem el clúster. 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • Despleguem Registrator a tots els nodes

    Code Block
    languagebash
    themeEmacs
    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
  • Creem els fitxers de configuració necessaris

files/default.ctmpl


Code Block
languageperl
themeRDark
{{$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}};
    }
}

files/start.sh

 

Code Block
languageperl
themeRDark
#!/bin/bash
service nginx start
consul-template -consul=$CONSUL_URL -template="/templates/default.ctmpl:/etc/nginx/conf.d/default.conf:service nginx reload"

Dockerfile

 

Code Block
languageperl
themeRDark
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.yml

Code Block
languageperl
themeRDark
version: '2'
services:
  lb:
    build: .
    container_name: lb
    ports:
      - "80:80"
    environment:
      - APP_NAME=web_nginx
      - CONSUL_URL=${CONSUL_IP}:8500
    depends_on:
      - web
  web:
    image: nginx
    ports:
      - "80"
    environment:
      - SERVICE_NAME=web_nginx
networks:
  default:
    driver: overlay

 

 

  • Activem el servei


    Des del directori on tenim el docker-compose.yml, executem:

 

 

Code Block
languageperl
themeRDark
eval $(docker-machine env -swarm swarm-master)
docker-compose up -d
docker-compose ps

 

 

  • Augmentar o disminuir les instancies del servei


    Per augmentar o disminuir les instàncies del servei utilitzem la següent comanda

Code Block
languageperl
themeRDark
docker-compose scale web=4

Amb aquest comanda augmentarem en 4 les instàncies desplegades del servei web.

El nom que indiquem ha de ser en nom que hem indicar en el fitxer docker-compose.yml. Nosaltres el fitxer docker-compose.yml hem indicat que el nom del servei era web.

Executem docker-compose ps per saber com estan les instancies. Hem esborrat les IP. Aqui es veurien com les instancies estan repartides pel diferents nodes del cluster swarm.

 

  • Accedir al servei

     
    Hem d'accedir amb la IP del load balancer (lb)


  • Aturar i/o esborrar el serveis


Code Block
languageperl
themeRDark
docker-compose stop; docker-compose rm -f