Algunos servicios no necesitan almacenar ningún estado porque no lo necesitan o porque el estado se mantiene en otro servicio. Que un servicio no necesite mantener estado es bueno porque de esta manera el servicio se puede escalar al número de instancias adecuadas para prestar el servicio, también porque si falla una instancia la petición puede ser reenviada a otra instancia, una instancia que falla puede ser reemplazada sin problema en otro host. Sin embargo, hay otro tipo de instancias que si almacenan estado como las bases de datos ya sea PostgreSQL, MySQL, Redis, MongoDB, otra o simplemente archivos en el sistema de archivos.
Las instancias que tienen estado no son tan fáciles de reemplazar dado que los datos son necesarios para su funcionamiento, una instancia de un servicio con estado como no puede iniciarse en otro nodo libremente solo se puede iniciar en el nodo que contenga los datos. Eso o cuando el servicio se inicia en otro nodo los datos son trasladados o por algún mechanismo transparente a los servicios están disponibles en el nuevo nodo.
En Docker Swarm ciertos drivers de volúmenes pueden proporcionar volúmenes accesibles desde cualquier host del cluster pero por defecto Swarm no lo ofrece. En Kubernetes los volúmenes pueden ser dispositivos de almacenamiento provenientes de EBS de modo que si un pod es movido a otro host basta con que el pod sea conectado de nuevo al EBS anterior y los datos están accesibles en el nuevo nodo.
Nomad no proporciona soporte para que el almacenamiento persistente sea migrado a un nuevo nodo de Nomad si el servicio cambiado de ubicación. Para solventar esta limitación en el caso de los servicios con estado estos pueden ser tratados en cierta forma como animales de compañía o pets haciendo que siempre se ubiquen en el mismo nodo, una vez tiene siempre la misma ubicación basta con proporcionar el almacenamiento en el host ya sea en su sistema de archivos o para externalizarlo montando un almacenamiento EBS.
Para conseguir que un job de Nomad se ubique siempre en un mismo nodo hay que usar restricciones o costraints en la especificación del job. Las restricciones son las reglas que utiliza Nomad para elegir como candidatos los posibles nodos en los que ubicar el job, task group o task. Se pueden utilizar varios operadores entre los que está el de igualdad utilizado en el ejemplo. Una de las variables utilizables es el identificativo del nodo de Nomad, con él es posible conseguir que el job se ubique siempre en el mismo nodo. Los identificativos de los nodos son asignados por Nomad cuando se unen al cluster.
Con los siguientes comandos se inspecciona los nodos que forman parte del cluster de Nomad, entre sus datos está el identificativo de cada nodo formado por una cadena de 36 caracteres. En el modo verboso se emite el identificativo completo y una lista de propiedades del nodo entre los que están detalles de Consul, la CPU, driver que soporta, kernel, sistema operativo, … En documentación sobre interpolación de variables hay una lista de variables disponibles.
|
|
En este caso solo hay un nodo registrado en Nomad, la siguiente definición de job en el fragmento constraint hace que Nomad lo ubique siempre en él.
|
|
Como el job se ubica en el mismo nodo siempre montando un directorio del nodo como un volumen de datos en el job y contenedor de Docker, los datos se persisten en el sistema de archivos y transcienden al tiempo de vida del job, se puede iniciar el job, insertar datos en la base de datos en este caso de MongoDB, eliminar el job, volverlo a iniciar y los mismos datos están presentes en MongoDB.
|
|
|
|
|
|
Para iniciar Consul y Nomad hay que utilizar los siguientes comandos y para el ejecutar job es requisito haber instalado Docker dado que en este ejemplo lo utiliza.
|
|
Las restricciones se han de cumplir para elegir un nodo, por otro lado está también la afinidad. La afinidad es una preferencia utilizada por Nomad al seleccionar los nodos que tratará de cumplir si hay algún nodo disponible con las propiedades de afinidad deseadas pero si no hay un nodo disponible se elige algún otro.