Nuestro obejetivo en esta entrada es construir una colmena o Swarm de Docker con el pbjetivo de lanzar varios contenedores de una misma imagen para que respondan a un servicio al mismo socket (Puerto+IP) balanceando la carga de las peticiones netre todo los contenedores creados.
Una cosa quiero acalararos antes de que perdais el tiempo al crear varios nodos si vais a trabajar en maquinas virtuales. Ciertos software de virtualizacion NO admiten virtualizacion anidad (nested virtualization). Uno de ellos es VirtualBox. O bien empleais distintas MVs como nodos o bien usais diferentes máquinas fisicas. Dicho esto ya podemos porseguir.
Ahora definiré ciertos conceptos para aclarar mas el tema de dockers con multi-servicios o balanceo de carga (LB):
- Services — > Varias copias de la misma instancia ejecutándose “en paralelo”.
- Swarm — > Colmena de máquinas (físicas o virtuales) que ejecutan dockers containers y que se gestionan como un cluster único (aunque las maquinas virtuales o físicas estén separadas).
- Stack — > Grupo de servicios interrelacionados que comparten dependencias que puede ser gestionado y auto escalado como uno solo. Por ejemplo, una web con un servicio de BBDD asociado.
Swarm nos permite generar clusters en una distintas máquinas físicas o virtuales. Una vez que dichas maquinas se unen al cluster swarm cada una de ellas se pasa a denominar NODO.
Así como existían estrategias para el balanceo de carga en un “Service”, también se puede producir una estrategia de para ejecutar los containers en los “nodos”. Existen las siguientes dos estrategias que se pueden marcar en el archivo “compose”:
- Emptiest node — > estrategia que completa con un container el nodo menos “completo” de instancias.
- Global — > Esta estrategia asegura el mismo número de máquinas en cada nodo.
Hay que tener en cuenta que solo los “swarm managers” pueden ejecutar los comandos que deseamos y solo ellos pueden asignar tareas a los “workers” o incluso dejar que se añadan a la colmena.
En la siguiente imagen vemos como cualquier IP de los nodos a los que solicitemos un servicio puede enviar dicha solicitud a un contenedor de otro nodo. Así pues, en el ejemplo, aunque accedamos a la IP 192.168.99.100 o la 101 o la 102 la carga se reparte entre todos los nodos porque es el «Swarm load balancer» el que «escucha» en esas IPs y reparte dicha carga. Esto garantiza que un servicio implementado en un puerto determinado dentro de su enjambre siempre tiene ese puerto reservado para ese servicio, no importa qué nodo está ejecutando realmente en ese contenedor.

Quiero subrayar que lo lógico por motivos de seguridad seria el exponer una sola IP al trafico de solicitud o (al menos) dividir la traducción DNS de direcciones a IPs por areas o regiones donde tengamos un nodo mas cerca de donde se produce la solicitud.
Creando nuestro Swarm (colmena)
Como ya es comentado al principio en VirtualBox tenemos el problema de la virtualización anidada. Las opciones para solucionar el problema son las siguientes:
- Emplear un hypervisor que si nos permita anidar virtualizaciones (como VMware/VCenter).
- Emplear una maquina física con un S.O Ubuntu (en este caso) en el que en VirtualBox estén creadas el resto de las máquinas.
- Emplear maquinas físicas.
- Emplear varias máquinas en VirtualBox con cualquier S.O anfitrión. Esta es la arquitectura elegida en el ejemplo que seguiremos.
En el caso de haber escogido una arquitectura como el segundo caso se podrían crear las maquinas usando docker-machine para realizar esta configuración podemos ver más información aquí.
Nosotros trabajaremos en el cuarto caso donde hemos “clonado” una máquina virtual desde una creada en Ubuntu 18. Es fácil deducir es que todas las maquinas deberán de tener instalado Docker Engine y una (o varias) podrían ser, además, “managers” del Swarm. En este caso tendremos 1 máquina virtual como manager (o leader) y 2 máquinas más como workers.
La estructura de nuestra prueba es la que se muestra en la siguiente imagen donde Ubuntu18(Worker) es el «worker» y Ubuntu18(Manager) es nuestro «leader» o «manager».

Cuando ejecutamos en una maquina el comando docker swarm init lo que hace es convertir esa máquina en manager o leader (además de poder ejecutar tareas como “worker”) y nos muestra las instrucciones para poder añadir más maquinas a nuestra “colmena” tanto de managers como workers. En la siguiente imagen vemos la ejecución de ese comando.

Como vemos en los mensajes que nos muestra nos indica que para añadir un nodo «worker» a nuestro enjambre/colmena (Swarm) debemos ejecutar en dicho nodo docker swarm join –token SWMTKN-1-2eelg9lrdpjyeg66yqy35ro4iscjowgwh2jmgifrtqygf7enfq-bkl7gmr7cx7hsebuqlxq39vd4 192.168.1.137:2377 donde la última IP es la de nuestro nodo «manager».
Es muy importante especificar el puerto 2377 (o ninguno si queremos) pero nunca el 2376 ya que ese es el que emplea el demonio de swarm. En la siguiente imagen vemos como unir un nodo como «worker».

Ahora con los comandos docker node ls obtenemos la información de las máquinas que están añadidas a la colmena, quien es el manager o leader y con docker info podemos discriminar el ID de la que es leader ya que (en este caso) son todas clonaciones y tienen el mismo nombre.


Si nos fijamos en el resultado de la imagen veremos «Managers: 1» (lo cual es correcto) y «Nodes: 2» que también es correcto ya que, como hemos dicho, un «manager» es un nodo y también ejecuta contenedores como lo haría un «worker».
En la siguiente entrada desplegaremos varios contenedores en nuestro Swarm.
Deja una respuesta