Creando un cluster de VM usando Swarm en modo sandbox

Vamos a crear un cluster utilizando la herramienta Swarm de Docker.

Crearemos 1 VM que actuará de administrador de los nodos y 3 VM nodo usando el driver de VirtualBox con la herramienta docker-machine, puede leer el artículo Administrado hosts con docker para ver un poco de detalle sobre la creación de máquinas:

docker-machine create --driver virtualbox manager
docker-machine create --driver virtualbox machine1
docker-machine create --driver virtualbox machine2
docker-machine create --driver virtualbox machine3

Puede las máquinas:

docker-machine ls

Al crear cada máquina el comando revisará si existe una copia en local de la imagen boot2docker.iso, si no está la descargara del hub de Docker y luego pasará a crear la VM que automáticamente ejecutará el Docker Engine.

Se usara un discovery backend alojado en el hub de docker para crear un único discovery token para el cluster. Este discovery backend sólo debe ser usado para pruebas y desarrollo, no utilizar en producción.

Cuando se ejecuten el administrador y los nodos, ellos se registrarán con el discovery backend como miembros del cluster el cual esta asociado con el token único. El discovery backend mantedrá una lista actualizada de los miembros y la compartirá dicha lista con el administrador Swarm, quien usará esa lista para asignar las tareas a los nodos.

Conectaremos el Docker Client al Docker Engine ejecutado en el administrador:

$ eval $(docker-machine env manager)

Ahora a crear el token único para el cluster Swarm, el siguiente comando obtendrá la imagen más reciente de **Swarm*** y creará un contenedor de él.

$ docker run --rm swarm create
.
.
.
Unable to find image 'swarm:latest' locally
latest: Pulling from library/swarm
eada7ab697d2: Pull complete 
afaf40cb2366: Pull complete 
7495da266907: Pull complete 
a3ed95caeb02: Pull complete 
Digest: sha256:12e3f7bdb86682733adf5351543487f581e1ccede5d85e1d5e0a7a62dcc88116
Status: Downloaded newer image for swarm:latest
9c335513ae1f31081c5c6a87c1db177b

La última línea muestra un único Swarm ID conocido como discovery token, el cual fue generado por el servicio Docker Hub discovery. Guarde en un lugar seguro este token. El servicio mantiene durante una semana aproximadamente los tokens no usados.

Vamos a conectar cada uno de los hosts y crear el administrador Swarm. Veamos nuestras VM:

$ docker-machine ls
NAME              ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER    ERRORS
machine1          -        virtualbox   Running   tcp://192.168.99.103:2376           v1.11.1   
machine2          -        virtualbox   Running   tcp://192.168.99.101:2376           v1.11.1   
machine3          -        virtualbox   Running   tcp://192.168.99.102:2376           v1.11.1   
manager           -        virtualbox   Running   tcp://192.168.99.104:2376           v1.11.1  

Ahora nuestro cliente debe estar usando el Docker Engine en el manager. Ahora vamos a ejecutar el contenedor Swarm:

$ docker run -d -p <your_selected_port>:3376 -t -v /var/lib/boot2docker:/certs:ro swarm manage -H 0.0.0.0:3376 --tlsverify --tlscacert=/certs/ca.pem --tlscert=/certs/server.pem --tlskey=/certs/server-key.pem token://<cluster_id>

En este caso:

$ docker run -d -p 3376:3376 -t -v /var/lib/boot2docker:/certs:ro swarm manage -H 0.0.0.0:3376 --tlsverify --tlscacert=/certs/ca.pem --tlscert=/certs/server.pem --tlskey=/certs/server-key.pem token://9c335513ae1f31081c5c6a87c1db177b

El parámetro -p mapeará el puerto 3376 en el contenedor al puerto 3376 en el host. El -v montará el directorio que contiene los certificados TLS (/var/lib/boot2docker para el manager VM) en el contenedor ejecutando el Swarm manager en modo sólo lectura.

Conectaremos el Docker Client a la VM machine1:

$ eval $(docker-machine env machine1)

Usaremos la siguiente sintaxis para ejecutar un contenedor Swarm que funcione como agente en machine1. Reemplazar con la dirección IP de la VM que pude ver usando el comando docker-machine ip.

$ docker run -d swarm join --addr=<node_ip>:<node_port> token://<cluster_id>

En nuestro ejemplo:

$ docker run -d swarm join --addr=$(docker-machine ip machine1):2376 token://9c335513ae1f31081c5c6a87c1db177b

Repetiremos los pasos anterior para la machine2 y machine3:

$ eval $(docker-machine env machine2)
$ docker run -d swarm join --addr=$(docker-machine ip machine2):2376 token://9c335513ae1f31081c5c6a87c1db177b

Es turno de conectar al cluster y revisar la información sobre el manager y los nodos Swarm.

Conectar el Docker Client al Swarm para actualizar la variable de entorno DOCKER_HOST:

$ DOCKER_HOST=<manager_ip>:<your_selected_port>

En nuestro caso:

$ eval $(docker-machine env manager)
$ DOCKER_HOST=$(docker-machine ip manager):3376

Docker Swarm usa el estandar Docker API, así que podemos conectarnos usando Docker Client y otras herramientas como Docker Compose, Dokku, Jenkins y otros.

Con el siguiente comando obtendremos información de los nodos de nuestro cluster:

$ docker info

.
.
.
Nodes: 3
 machine1: 192.168.99.103:2376
  └ ID: 6IQ7:PRUS:J76J:JGAV:55ES:XDHS:VU3S:46XK:XGQO:A76B:JXXO:VQYX
  └ Status: Healthy
  └ Containers: 1
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 1.021 GiB
  └ Labels: executiondriver=, kernelversion=4.4.8-boot2docker, operatingsystem=Boot2Docker 1.11.1 (TCL 7.0); HEAD : 7954f54 - Wed Apr 27 16:36:45 UTC 2016, provider=virtualbox, storagedriver=aufs
  └ Error: (none)
  └ UpdatedAt: 2016-05-25T18:22:26Z
  └ ServerVersion: 1.11.1
 machine2: 192.168.99.101:2376
  └ ID: EZDZ:IUOJ:7EIS:XWVK:SOSA:5H5D:4V7U:LWXE:UU6A:ZTW5:QQLT:BBP5
  └ Status: Healthy
  └ Containers: 1
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 1.021 GiB
  └ Labels: executiondriver=, kernelversion=4.4.8-boot2docker, operatingsystem=Boot2Docker 1.11.1 (TCL 7.0); HEAD : 7954f54 - Wed Apr 27 16:36:45 UTC 2016, provider=virtualbox, storagedriver=aufs
  └ Error: (none)
  └ UpdatedAt: 2016-05-25T18:22:44Z
  └ ServerVersion: 1.11.1
 machine3: 192.168.99.102:2376
  └ ID: AYIV:4K6L:N3WH:JEMH:I6OT:QZ6O:P7QD:RCZ6:TZYV:MRZX:G6D4:G25W
  └ Status: Healthy
  └ Containers: 1
  └ Reserved CPUs: 0 / 1
  └ Reserved Memory: 0 B / 1.021 GiB
  └ Labels: executiondriver=, kernelversion=4.4.8-boot2docker, operatingsystem=Boot2Docker 1.11.1 (TCL 7.0); HEAD : 7954f54 - Wed Apr 27 16:36:45 UTC 2016, provider=virtualbox, storagedriver=aufs
  └ Error: (none)
  └ UpdatedAt: 2016-05-25T18:22:26Z
  └ ServerVersion: 1.11.1
  .
  .
  .

Puede ver los contenedores ejecutándose en su Swarm:

$ eval $(docker-machine env manager)
$ docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                              NAMES

Ahora vamos a ejecutar unos cuantos contenedores:

$ for image in apple orange pear banana pineapple avocado fig; do docker run -d --name $image httpd;  done;
c054605e4376e42c371cdd04828cb9519cde392bbcfaca5553d6b726e20d974a
26205ec0c4495c17a27eb274b84b25181c2ebf1652180d3c755de2f15fc3a33a
f8b344a31d84e86b8a6628c9047c554759369211a483493fd077978f0b267a72
f7fb30faed5cdc23c6a009ab9691870228223ff5bd073b4ea1405ef4a1e4ba44
d8270cf90ff076494fb93c7bc6390d7bf16f045a1fd06425d732cb012e0ca52f
c3b6ceb8fc9a7c223fa751d672ca2131d8c0a026bcdfc509fed9938d934faf4b
248b48e0a729d7696415060ebb523f64a96d4cbb6faeca7dde693f118f563b5e

Y como veremos a continuación Swarm ejecutó los contenedores en diferentes máquinas:

$ docker ps
CONTAINER ID        IMAGE               COMMAND              CREATED             STATUS              PORTS               NAMES
248b48e0a729        httpd               "httpd-foreground"   3 seconds ago       Up 3 seconds        80/tcp              manager/fig
c3b6ceb8fc9a        httpd               "httpd-foreground"   4 seconds ago       Up 3 seconds        80/tcp              machine3/avocado
d8270cf90ff0        httpd               "httpd-foreground"   4 seconds ago       Up 3 seconds        80/tcp              machine2/pineapple
f7fb30faed5c        httpd               "httpd-foreground"   4 seconds ago       Up 3 seconds        80/tcp              manager/banana
f8b344a31d84        httpd               "httpd-foreground"   4 seconds ago       Up 3 seconds        80/tcp              machine3/pear
26205ec0c449        httpd               "httpd-foreground"   4 seconds ago       Up 4 seconds        80/tcp              manager/orange
c054605e4376        httpd               "httpd-foreground"   5 seconds ago       Up 4 seconds        80/tcp              machine2/apple

Docker Swarm usa por defecto la estrategia “spread” para elegir en que nodo se ejecutará el contenedor. Cuando se ejecutan múltiples contenedores la estrategía los va asignado al nodo con menos contenedores.

La información de este artículo es un resumen de la mostrada en Empezando con Swarm.

Leave a comment

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *