Mi ODROID-C2 Docker Swarm: Parte 1 – Características del Modo Swarm

Docker Swarm Figure 0

Docker introdujo el modo swarm en la versión 1.12.x con el fin de hacer posible la implementación de contenedores en múltiples hosts docker. El modo Swarm proporciona funciones de gestión del clúster y de organización de los servicios, incluyendo la búsqueda y el escalado de servicios, entre otras cosas, utilizando para ello redes de superposición y un balanceador de carga interno, respectivamente. Estas son funcionalidades claves para las empresas, ya que existe un límite en el número de contenedores que se pueden implementar en un único host docker. Si deseas conocer más afondo la arquitectura de alto nivel del modo swarm, echa un vistazo a mi anterior artículo publicado en la edición de noviembre de 2016 de ODROID Magazine en http://bit.ly/2wiTVXM.

Hace varios meses, cuando estaba experimentando con el modo swarm de Docker en mi clúster ODROID-C2 de cinco placas. Era capaz de iniciar varios contenedores Docker en multiples hosts docker, pero ni la red de superposición, el sistema de enrutamiento, ni el balanceo de carga funcionaban en modo swarm. Llegué a usar múltiples versiones de docker (1.12.x y 1.13.x) compiladas en mi ODROID-C2 sin obtener resultados. También intenté ejecutar Kubernetes en mi clúster ODROID-C2. Una vez más la parte de la gestión de redes de Kubernetes no funcionaba. Sospechaba que al kernel le faltaban algunos módulos que serían necesarios para Docker y Kubernetes. Debido a esto, decidí abandonar mis experimentos hasta ahora. Lo que reavivó mi pasión por lograr hacer funcionar el modo swarm de Docker fue el hecho de considerar un hardware que no había utilizado con anterioridad: la pantalla ODROID VU7 multi-touch y la carcasa VuShell para VU7.

Ensamblé la pantalla VU7 y un ODROID-C1 + con la carcasa VuShell. Luego pensé, ¿por qué no colocar mi clúster ODROID-C2 también? En la figura 1 puedes ver una pantalla que muestra un teclado virtual. Todos los ordenadores de placa reducida ODROID están conectados entre sí con un switch Ethernet Gigabit de 8 puertos, y también hay un SSD dentro de la carcasa VuShell. La caja de cartón ODROID alberga la fuente de alimentación. El diminuto router inalámbrico utiliza el Sistema de Distribución Inalámbrica, WDS, para conectarse a mi router principal y proporcionar acceso a Internet vía Ethernet a todos los ODROID que hay dentro de la carcasa VuShell, ya que éstos no tienen WiFi integrado.

Figura 1 - Un cluster Docker Swam que utiliza el shell ODROID-VU como carcasa

Sistema operativo Ubuntu 16.04 de Hardkernel

Tenía la sospecha de que el modo swarm de Docker no llego a funcionar en mis anteriores pruebas porque faltaba o eran incompatibles algunos módulos del kernel en el sistema operativo. Así que opte por cambiar a otro sistema operativo. Observé que Hardkernel había lanzado recientemente Ubuntu 16.04 (v2.3) para el ODROID-C2, así que lo probé. La versión anterior del sistema operativo Ubuntu de Hardkernel que probé meses antes era inestable, pero la versión actual funcionaba sin ningún problema. ¡Estaba contento y me dije a mi mismo que quizás esta vez podría funcionar!

Para facilitar las cosas, instalé y configuré los siguientes paquetes:

  • parallel-ssh en el gestor docker para permitirme enviar comandos una vez desde el gestor docker y que sean ejecutados en todos los nodos
  • nfs-kernel-server en el gestor y nfs-common en todos los nodos
  • curl en el gestor para hacer pruebas
  • dnsutils en todos los nodos

También he generado claves SSH para los usuarios "odroid" y "root" en todos los miembros del clúster, para que puedan comunicarse entre sí vía SSH sin una contraseña.

Reiniciar el Modo Swarm de Docker

Instalé docker.io usando apt-get y realicé una prueba rápida "docker run" usando mi imagen httpd, y funcionó. Quería probar el modo swarm a continuación para ver si funcionaba con el nuevo sistema operativo. Aquí tienes una captura de pantalla de las versiones del software que han sido utilizadas. Resulta interesante ver que la distribución de Ubuntu de Hardkernel viene con zram preinstalado para swap, lo cual es muy útil.

Figura 2 - Docker mostrando las versiones de todo el software actual

Creando un Swarm

Los nombres de host y las direcciones IP estáticas de mis hosts swarm son::

  • c2-swarm-00 - 192.168.1.100 (gestor)
  • c2-swarm-01 - 192.168.1.101 (nodo 1)
  • c2-swarm-02 - 192.168.1.102 (nodo 2)
  • c2-swarm-03 - 192.168.1.103 (nodo 3)
  • c2-swarm-04 - 192.168.1.104 (nodo 4)

Únicamente el c2-swarm-00 tiene conectada una unidad SSD, aunque el sistema de archivos se comparte por NFS.

Un nodo es un host docker que forma parte de un swarm. Un nodo gestor es al que envías una definición de servicio y éste programa el servicio para que se ejecute como tarea en los nodos de trabajo. Los nodos de trabajo reciben y ejecutan las tareas programadas por un nodo gestor. Un nodo gestor, por defecto, también es un nodo de trabajo a menos que esté configurado expresamente para no ejecutar tareas. Se pueden configurar múltiples nodos maestros y de trabajo en un Swarm para proporcionar Alta Disponibilidad (HA). Para iniciar el modo Swarm, utiliza el siguiente comando en el gestor:

$ docker swarm init --advertise-addr 192.168.1.100
que devuelve:
swarm initialized: current mode
(8jw6y313hmt3vfa1me1dinro) is now a manager
Para añadir un nodo de trabajo a este Swarm, ejecuta el siguiente comando en cada nodo:
$ docker swarm join --token SWMTKN-1-2gvqzfx48uw8zcokwl5033iwdel2rl9n96lc0wj1qso7lrztub-aokk5xcm5v7c4usmeswsgg1k 192.168.1.100:2377
Para hacer que el resto de nodos se unan al clúster, ejecuta el anterior comando "docker swarm join" en cada nodo. Esto se puede hacer usando parallel-ssh, que te permitirá emitir el comando una vez desde el gestor, y luego ejecutarlo en cada nodo. La siguiente imagen muestra una captura de pantalla tras ejecutar el comando "docker ps" usando parallel-ssh, lo que significa que el modo swarm de Docker está funcionando.

Figura 3 - El resultado del comando "docker ps" que muestra todos los nodos

Un incordio que descubrí en el modo swarm de Docker es que después de apagar todos los nodos y encenderlos de nuevo, todos los nodos aparecen "Active", pero " Down". Te das cuenta de esto cuando utilizas "docker node ls" para conocer el estado de los nodos. Puesto que los nodos no están disponibles, todos los servicios se ejecutarán en el gestor. La solución para por ejecutar "systemctl restart docker" en cada nodo. Esto cambiará su estado de "Down" a "Ready", y todo volverá a funcionar de nuevo. La herramienta parallel-ssh es una forma muy cómoda de hacerlo, ya que lo único que tienes que hacer es ejecutar una vez el comando en tu nodo gestor.

Ejecutar los Servicios HTTPD y Docker Swarm Visualizer

Para ayudar a visualizar lo que sucede en el Swarm, he desarrollado la imagen "Docker Swarm Visualizer" basada en Docker Samples en Github. La he dejado en el hub docker en http://dockr.ly/2ipXzcL, para que cualquiera pueda usarla. El nombre de la imagen es "mrdreambot/arm64-docker-swarm-visualizer", disponible en http://bit.ly/2xqSaV4. Después la implemente como un servicio ejecutando el siguiente comando desde el gestor:

$ docker service create --name=dsv --publish=8080:8080/tcp --constraint=node.role==manager --mount=type=bind,src=/var/run/docker.sock,dst=/var/run/docker.sock mrdreambot/arm64-docker-swarm-visualizer
A continuación, apunté el navegador hacia el nodo maestro en http://192.168.1.100:8080, aunque también funciona si diriges el navegador hacia cualquiera de los nodos del swarm. Se pueden observar los cambios reportados por el visualizador al implementar el servicio httpd:
$ docker network create --driver overlay home-net
$ docker service create --replicas 3 --network home-net --name httpd -p 80:80 mrdreambot/arm64-busy-box-httpd
La figura 4 muestra el resultado de la línea de comandos a la hora de listar los servicios. La Figura 5 es una captura de pantalla del Docker Swarm Visualizer que muestra los nodos en los que se ejecutan las réplicas del servicio, lo cual pone de manifiesto el modelo de servicio factual utilizado por el modo swarm.

Figura 4 - Resultado de la línea de comandos con el listado de servicios

Figura 5 - Docker Swarm Visualizer

Sistema de enrutamiento, Balanceo de carga y auto-regeneración

El sistema de enrutamiento en el swarm permite que una solicitud llegue a un servicio incluso cuando el servicio no se esté ejecutando en el nodo en el cual se ha recibido la solicitud. Esto significa que, aunque el servicio httpd se ejecuta en c2-swarm-00, c2-swarm-03 y c2-swarm-04, se puede apuntar al navegador hacia cualquiera de los 5 nodos y obtener una respuesta con la imagen ODROID-Docker. Este fue el comportamiento que observé.

Figura 6 - Ejemplo de Balanceo de carga usando 10.255.0.9

Además de ofrecer un sistema de enrutamiento, swarm también permite el balanceo de carga. Para probar esta función, hice conexión al gestor varias veces usando mi navegador, en el servicio httpd usando la dirección http://192.168.1.100/cgi-bin/lbtest. Observe que los nombres de host (Id de contenedor) y las direcciones IP son diferentes en las dos capturas de pantalla.

Figura 7 - LEjemplo de balanceo de carga usando 10.255.0.10

Las pruebas fueron repetidas usando el comando curl:

$ curl http://192.168.1.100/cgi-bin/lbtest
Aquí tienes una captura de pantalla del resultado de los comandos curl que confirma, de nuevo, que cada solicitud ha sido dirigida a un nodo diferente:

Figura 8 - Balanceo de carga entre nodos

Para probar la auto-regeneración, decidí apagar el c2-swarm-04, se puede ver tanto desde el visualizador como desde la línea de comandos que otro contenedor httpd ha sido derivado a c2-swarm-02 para reemplazar el de c2 -swarm-04. Esto ocurre porque cuando iniciamos el servicio, especificamos "réplica = 3". Esto significa que el swarm de Docker mantendrá el número réplicas deseado, en ente caso 3. Esto suele denominarse reconciliación del estado deseado.

Figura 9 - Recuperación del servicio

Figura 10 - Recuperación del servicio httpd

Después apagué el resto de nodos y dejé funcionando únicamente el nodo gestor, el Visualizer muestra el resultado en la figura 11.

Figura 11 - Recuperación del Servicio httpd – 1 nodo

¡Todo funcionaba como era de esperar!

Conclusión

La nueva versión de Ubuntu 16.04 de Hardkernel marcó realmente la diferencia. El modo swarm de Docker ahora funciona por completo en mi clúster ODROID-C2. En la siguiente instalación, actualizaré Docker a la versión 1.13.x para experimentar con la función "docker stack deploy", nueva en v.1.13.x. Una pila es un conjunto de servicios que componen una aplicación. Despliega automáticamente varios servicios que están vinculados entre sí, eliminando la necesidad de definir cada uno de ellos por separado. En otras palabras, es docker-compose en modo swarm que gestiona la planificación de los servicios. También describiremos el uso de una red de superposición para la búsqueda de servicios.

Be the first to comment

Leave a Reply