Nomad – Despliegue y supervisión sencilla de aplicaciones

En este tutorial vamos a conocer Nomad y ver cómo puede facilitarnos los despliegues y el escalado de aplicaciones.

Índice de contenidos

1. Introducción

Cuando comienzas a desarrollar aplicaciones complejas orientadas a servicios, o incluso con microservicios, el número de artefactos a desplegar se vuelve inmanejable. Si además quieres tener un entorno de alta disponibilidad con varios nodos balanceados ejecutando tu aplicación esto es aún más tedioso. Tanto si quieres desplegar contenedores de Docker, como aplicaciones Java directamente, o apps de otro tipo como Apache Spark; Nomad es lo que necesitas.

Nomad es una pequeña pieza de software que se instala en los servidores que formarán parte de tu clúster. Se compone de dos partes: una servidor (gestiona los despliegues) y otra cliente (aloja los depliegues). Se recomienda tener 3 servidores y tantos clientes como se necesiten por cada zona.

Se declaran los trabajos, se planifican y muestran por pantalla los cambios que se aplicarán y se ejecuta el despliegue distribuido. Puedes ver el progreso en todo momento. Además te supervisarán los nodos y desplegará nuevas instancias en caso de caídas. Permite el uso combinado de una nube pública (tipo AWS o Azure) y una entorno privado, distribuyendo las aplicaciones como si de uno solo se tratara.

2. Entorno

El tutorial está escrito usando el siguiente entorno:

  • Hardware: Portátil MacBook Pro Retina 15′ (2.2 Ghz Intel Core I7, 16GB DDR3).
  • Sistema Operativo: Mac OS X El Capitan 10.11.6
  • Entorno de desarrollo: Atom
  • Sistema operativa de las VM: CentOS/7
  • Nomad 0.5.0
  • Consul 0.7.0
  • Vagrant
  • Ansible
  • VirtualBox
  • Nginx

3. Qué hace y qué no hace

Nomad es una utilidad de “HashiCorp” que se instala en servidores y puede tener dos roles. Actuar como servidor para gestionar y supervisar los despliegues; o actuar como cliente para alojar estos despliegues.

Nomad no pretende ser una solución completa para orquestar una red de contenedores de Docker. Al menos no por sí solo.

Nomad no es un servidor de descubrimiento para resolver las ubicaciones de las aplicaciones desplegadas, pero para ello se integra muy bien con “Consul”, que es una herramienta también de “HashiCorp”.

Nomad no es un balanceador de carga ni un proxy para redirigir las peticiones a los diferentes nodos que tienen una aplicación. Aunque para ello se puede utilizar Nginx, Fabio, Traefik, HAProxy, etc. y automatizar su configuración desde los datos de consul utilizando consul-template.

Nomad no dispone de una gestión de secretos pero para ello se integra muy bien con “Vault”, que es una herramienta también de “HashiCorp”.

4. Instalación y arquitectura

Vamos a automatizar la instalación de nomad utilizando Vagrant (creación de máquinas virtuales) y Ansible (instalación y configuración de aplicaciones). Si no conocéis estas herramientas podéis ver un tutorial aquí.

Podéis clonaros el siguiente repositorio para seguir el tutorial: https://github.com/miyoda/nomad-consul-nginx

Como podréis ver en el fichero “inventory” vamos a crear 6 máquinas de las cuales 3 serán servidores y 3 clientes de nomad. Con ips desde 192.168.10.11 hasta 16.

Si ejecutamos desde línea de comando “vagrant up” se crearán automáticamente las máquinas tal cual se define en el fichero “Vagrantfile”.

Ya tendremos las máquinas creadas en nuestro VirtualBox


Además se ejecutarán los siguientes roles de ansible (en función de la maquina) como se define en el fichero “nomad.yml”:

Los roles “ansible-role-docker” y “ansible-role-java” son para que los servidores que sean clientes nomad que ejecutarán las aplicaciones dispongan de un entorno de ejecución Docker y Java respectivamente. Si, por ejemplo, un nodo no tiene Java instalado y das la orden de ejecutar un Job de Java, el nodo en cuestión no será seleccionado por Nomad para desplegar la aplicación por falta de drivers.

El role “ansible-role-consul” se encarga de la instalación de Consul en todos los nodos. Consul es un servicio de autodescubrimiento que nos será útil para que Nomad pueda descubrir al resto de nodos y para poder gestionar/almacenar dónde está desplegado cada aplicación/artefacto.

El role “ansible-role-nomad” se encarga de la instalación de Nomad en todos los nodos. Tres de ellos lo usaran como servidor y otros tres como cliente.

El role “ansible-role-proxy” se encarga de la instalación de nginx en los nodos servidores. Este role podría ser instalado en otro servidor independiente. La función de nginx aquí es servir de balanceador para las aplicaciones utilizando Consul para saber a que servidor redirigir cada petición en función de donde la haya desplegado Nomad. Configura también un tarea de consul-template para que la configuración de nginx cambie automáticamente si se despliega en nuevos nodos o desaparece alguno.


El flujo de comunicaciones y despliegue del sistema es, como se ve en la imagen, el siguiente:

  • 1. Nomad despliega una aplicación en uno o varios de sus nodos.
  • 2. Nomad registra en Consul los nodos que tienen aplicación desplegada.
  • 3. Nginx se autoconfigura con los datos de Consul mediante el proceso de consul-template.
  • 4. Las peticiones entrarán a “nginx” (cualquiera de los 3 nodos servidores que lo tienen desplegado).
  • 5. Nginx redirige la petición a uno de los nodos de Nomad que tienen la aplicación solicitada en función de la u Url de entrada.

5. Uso

Una vez finalice la creación de los servidores, lo cual puede llevar unos minutos, ya podemos conectarnos a ellos. Para conectarnos a una de las máquinas ejecutar “vagrant ssh cluster1” o “vagrant ssh cluster2”, etc.

Consul

Podemos ejecutar comandos para ver el estado del servicio de Consul y sus nodos. Esto se puede ejecutar en cualquier nodo puesto que todos tienen Consul instalado.

Si todo ha ido bien se habrá desplegado Consul en todos los nodos, se habrá seleccionado un líder, y debería estar accesible su UI desde la url siguiente (de cualquiera de los servidores): http://192.168.10.11:8500/ui/

Nomad

Podemos ejecutar comandos para ver el estado del servicio de Nomad y sus nodos. Esto se puede ejecutar en cualquier nodo puesto que todos tienen nomad instalado; y si no es de tipo servidor se conectará a uno para obtener la información necesaria.

Como vemos ahora mismo no tenemos ningún job lanzado, y en clúster tiene listos tres nodos servidores con uno de ellos asignado como líder, y otros tres nodos clientes.

Job de ejemplo

Una vez desplegado y verificada la configuración de Consul y Nomad es el momento de comenzar a lanzar ‘Jobs’! Los jobs son las configuraciones que se le pasan a Nomad para que despliegue. Están formados por ‘Tasks’ que representan las aplicaciones/artefactos a desplegar.

Vamos a comenzar creando y ejecutando nuestro primer job de ejemplo con los siguientes comandos:

Ahora podremos ver más información sobre el estado de este despliegue utilizando los siguientes comandos:

En la parte final del estado de una ‘task’ se puede ver sus ‘allocations’ que son las instancias de ejecución en un nodo concreto. en este caso en el nodo ‘171a583b’ el cual se puede identificar en el listado obtenido del comando ‘nomad node-status’. Puedes obtener más información sobre los logs de una ‘allocation’ concreta usando el comando:

Job tipo Docker

En el directorio ‘jobs’ del repositorio tenemos entre otros un ejemplo de job de una app web sobre un docker llamado ‘hello-docker.nomad’. Tenemos el directorio ‘/vagrant/jobs’ en todas las máquinas virtuales con el contenido del directorio ‘jobs’ del proyecto. Vamos a ejecutar este job:

Esta aplicación está configurada en ese fichero para tener dos instancias. Por tanto debería estar desplegada en dos de los tres nodos clientes y accesible por tanto en dos de las siguientes urls:

http://192.168.10.14/ http://192.168.10.15/ http://192.168.10.16/

Nginx como proxy balanceador nos redirigirá automáticamente a los dos nodos que la tengan desplegada accediendo a la siguiente url. La web nos dirá qué nodo es el que ha respondido y podéis observar que cada vez será uno de los dos donde está desplegado:

http://192.168.10.11/hello-docker

Nginx se ha configurado automáticamente con una tarea cron que ejecuta el proceso “consul-template”. Éste, basándose en la configuración de Consul y las plantillas del directorio ‘/usr/bin/consul-template’, configura los ficheros de ‘/etc/nginx’ y reinicia el servicio de nginx.

Job tipo Java

Ahora vamos a ejecutar un job que desplegará una aplicación Java directamente en los nodos clientes (sin Docker). Para ello usamos el ejemplo ‘hello-java.nomad’.

Esta aplicación debería estar desplegada en dos de los tres nodos clientes y accesible por tanto en dos de las siguientes urls:

http://192.168.10.14:8080/ http://192.168.10.15:8080/ http://192.168.10.16:8080/
Modificando un Job

Vamos a planificar el despliegue de una nueva versión de la aplicación Java. Para ello tenemos preparado otro fichero de job llamado ‘hello-java-v2.nomad’. Con el siguiente comando vemos que acciones se ejecutarían para realizar el despliegue de este nuevo fichero de configuración:

Ahora podemos confirmar la ejecución de estos cambios que conllevan cambiar el .jar que se ejecutará y Nomad se encargará de parar las versiones antiguas y desplegar las nuevas.

Veamos cómo va el despliegue… ¡todo correcto!

Pruebas de estabilidad del clúster

¡Ahora es el momento de probar lo estable que es el sistema! Puedes probar a tirar la máquina virtual que actualmente es el líder de Consul y verás con el comando ‘consul monitor’ desde cualquiera de la otras máquinas que otro nodo adquiere la responsabilidad de líder.

Puedes probar a tirar al servidor Nomad que sea líder y verás con el comando ‘nomad server-members’ desde cualquier de las otras máquinas que otro nodo tipo server adquiere la responsabilidad de líder.

Puedes probar a tirar alguno de los nodos nomad cliente y observar que las task que tengan una allocation en este nodo crearán una nueva allocation en otro de los nodos clientes. Puedes verlo con el comando ‘nomad status hello-docker’ por ejemplo.

6. Nomad vs Otro software

No es fácil comparar Nomad con un software como Kubernetes. Kubernetes es una solución centrada más en los contendeores de Docker y que ofrece un sistema completo de orquestación con autodescubrimiento, balanceo de carga, gestión de volúmenes, networking, gestión de secretos, configuración, etc. En cambio Nomad es de propósito más general soportando aplicaciones virtualizadas, standalone y con contenedores de Docker. Nomad tiene una arquitectura mucho mas simple con un simple binario y requiere de otras piezas externas para añadir funcionalidades de coordinación o almacenamiento. Parecida es la comparación con otros sistemas como Docker Swarm.

Si lo comparamos con AWS ECS la principal diferencia es que ECS es para desplegar en los servidores de Amazon, mientras que Nomad es totalmente open source y permite el despliegue en cualquier nube privada o pública. Además ECS está centrado en contenedores de Docker mientras que Nomad tiene un propósito más general aunque soporta Docker también.

7. Conclusiones

Si necesitas una pieza de software que se encargue simplemente de gestionar y supervisar los despliegues distribuidos de tus aplicaciones o contenedores Docker; Nomad es una buena opción! Además, combinado con otras herramientas de ‘HashiCorp DevOps Infrastructure’ como Consul, Terraform y Vault puedes tener una solución bastante completa de infraestructura.

8. Referencias