Planificar procesos periódicos y scripts con Nomad

Escrito por el .
gnu-linux planeta-codigo
Enlace permanente Comentarios

Los pequeños scripts aún con su pequeña función específica, sus pocas líneas de código y breves instantes de ejecución limitados a segundos, minutos u pocas horas al día o a la semana realizan tareas importantes dentro de todas las tares de las que se compone un sistema computacional completo. Al igual que cualquier otro proceso requieren de un entorno de ejecución pero dada su naturaleza breve hace que dedicar una máquina reservada que estará infrautilizada en exclusiva para ellos sea ineficiente además de un coste en la infraestructura. En vez de dedicar una máquina en exclusiva para uno o unos pocos scripts el orquestador de procesos Nomad permite planificarlos en alguna de las instancias de computación existentes del cluster ya sea como procesos del sistema o dentro de contenedores.

HashiCorp Nomad

Con mucha seguridad surge la necesidad de ejecutar de forma periódica un pequeño proceso o script completamente autónomo con el que no interacciona ningún usuario o administrador pero realiza una función esencial para el funcionamiento de una aplicación u organización. Las funciones o tareas de los scripts son muy diversas desde generar informes en formato CSV o generador documentos PDF a enviar correos electrónicos, para ello quizá se conecten a bases de datos relacionales o NoSQL o realizar llamadas usando REST a APIs de aplicaciones propias o de otras organizaciones, incluso un script con la complejidad suficiente varias cosas de todo esto.

Los lenguajes habitualmente usados para realizar tareas de scripting son dinámicos e interpretados por no requerir ser compilados y ejecutables desde el código fuente. En la plataforma Java una opción como lenguaje de scripting es Groovy y en otros lenguajes son propio intérprete de comandos Bash o Python, aunque el lenguaje Java con JBang o Gradle es una opción para realizar tareas de scripting con las ventajas de ser un lenguaje compilado con la asistencia de código de los entornos integrados de desarrollo o IDE.

Una vez creado un script este ha de ser ejecutado en un sistema, dependiendo de las dependencias como fuentes de datos que tenga el script la ejecución se puede realizar de forma manual en la propia computadora de un usuario o desarrollador. Por el contrario, como cualquier otra aplicación requiere su propio entorno de ejecución en producción, la forma más simple con una expresión cron como un proceso del sistema habiendo aprovisionado previamente el entorno y las dependencias necesarias del mismo. Otra propiedad de muchos scripts es que su tiempo de ejecución no es continuo durando unos pocos minutos u alguna hora realizan su atarea y terminan hasta la siguiente ejecución, al contrario que las aplicaciones con funciones de servidor que están continuamente funcionado por si algún cliente se conecta. En función de las necesidades del script su ejecución se planifica con una expresión cron cada minuto, hora, día o una vez a la semana.

Ejemplo de planificar procesos o scripts de forma periódica con Nomad

Una de las ventajas de la computación en la nube es poder crear máquinas virtuales cuando se necesitan y destruirlas cuando ya no son necesarias, de forma rápida y bajo demanda. Los contenedores permiten ejecutar procesos en cualquier máquina que soporte para la ejecución de contenedores, esto permite que un proceso no dependa de una máquina física o virtual en concreto.

Nomad de HashiCorp es un orquestador de procesos y contenedores, en lo relativo al tema de este artículo permite planificar no solo tareas para mantenerse en ejecución de forma constante e indefinida sino también planificar una tarea de forma periódica y temporal. Una ventaja de Nomad sobre una opción alternativa como Kuberntes es que permite planificar no solo contenedores de Docker sino también contenedores Podman o procesos del sistema a partir de comandos existentes en el mismo. Otra ventaja de Nomad es que es simplemente un orquestador de procesos de fácil instalación y uso al constar de únicamente un binario, se integra con otras herramientas como Consul para el registro y descubrimiento y conectividad y Vault para seguridad.

Desde luego crear una infraestructura basada en un cluster de servidores Nomad para planificar un script es un esfuerzo innecesario teniendo en cuenta que la opción de una máquina con un cron es más sencillo. Sin embargo, a poco complejo que sea un entorno para prestar un servicio que conste de más de una decena de instancias computacionales, la opción del cluster de Nomad permite utilizar la misma infraestructura para cualquier tipo de carga de trabajo, además siendo una infraestructura con la opción de proporcionar autoservicio permite conseguir algunos de los ideales propuestos de la cultura DevOps y detallados en The three ways y The five ideals de los libros The DevOps Handbook, The Phoenix Project y The Unicorn Project.

En este ejemplo se muestran la definición de dos tareas o jobs para Nomad, una como definida como un proceso del sistema a partir de los comandos disponibles en la máquina en la que se ejecuta y otra tarea como un contenedor de Docker. Ambas tareas son lo más simple posible emitiendo únicamente en la salida estándar un mensaje, en el caso del proceso del sistema con el comando echo y en el caso del contenedor con el mismo comando de una imagen de contenedor con BusyBox. En la definición de las tareas de Nomad se planifica su ejecución con una expresión cron cada un minuto.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
job "echo-busybox" {
    datacenters = ["dc1"]
    type = "batch"

    periodic {
        cron = "*/1 * * * * *"
        prohibit_overlap = false
    }

    group "echo" {
        task "echo" {
            driver = "docker"
            config {
	        image = "busybox:latest"
                command = "/bin/echo"
                args    = ["Hello Word! (busybox)"]
            }
        }
    }
}
echo-busybox.nomad
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
job "echo-bash" {
    datacenters = ["dc1"]
    type = "batch"

    periodic {
        cron = "*/1 * * * * *"
        prohibit_overlap = false
    }

    group "echo" {
        task "echo" {
            driver = "raw_exec"
            config {
                command = "/bin/echo"
                args    = ["Hello Word! (bash)"]
            }
        }
    }
}
echo-bash.nomad

Nomad y Docker se inician con los siguientes comandos.

1
2
$ nomad agent -dev

nomad.sh
1
2
$ sudo systemctl start docker.service

docker.sh

Antes de enviar a Nomad las tareas el panel de administración integrado o dashboard permite ver el estado, está disponible en la dirección http://127.0.0.1:4646/ui/, inicialmente sin ninguna tarea planificada, una vez se envían las tareas aparecen en el panel.

Dashboard de Nomad

Dashboard de Nomad

Dashboard de Nomad Dashboard de Nomad

Dashboard de Nomad

Las tareas se envían a Nomad para su planificación con el siguiente comando, otros comandos permiten ver el estado de las tareas y las trazas que ha generado. Nomad planifica una ejecución de cada tarea según la expresión cron indicada en la definición de los jobs.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
$ nomad job run echo-busybox.nomad
Job registration successful
Approximate next launch time: 2021-09-23T17:38:00Z (37s from now)

$ nomad job status echo-busybox
ID                   = echo-busybox
Name                 = echo-busybox
Submit Date          = 2021-09-23T19:37:23+02:00
Type                 = batch
Priority             = 50
Datacenters          = dc1
Namespace            = default
Status               = running
Periodic             = true
Parameterized        = false
Next Periodic Launch = 2021-09-23T17:39:00Z (1s from now)

Children Job Summary
Pending  Running  Dead
1        0        1

Previously Launched Jobs
ID                                Status
echo-busybox/periodic-1632418680  dead

$ nomad job status echo-busybox/periodic-1632418680
ID            = echo-busybox/periodic-1632418680
Name          = echo-busybox/periodic-1632418680
Submit Date   = 2021-09-23T19:38:00+02:00
Type          = batch
Priority      = 50
Datacenters   = dc1
Namespace     = default
Status        = dead
Periodic      = false
Parameterized = false

Summary
Task Group  Queued  Starting  Running  Failed  Complete  Lost
echo        0       0         0        0       1         0

Allocations
ID        Node ID   Task Group  Version  Desired  Status    Created    Modified
be8e648a  26b275d9  echo        0        run      complete  1m20s ago  1m16s ago

$ nomad alloc logs be8e648a
Hello Word! (busybox)
nomad-job-run-echo-busybox.sh
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
$ nomad job run echo-bash.nomad
Job registration successful
Approximate next launch time: 2021-09-23T17:44:00Z (4s from now)

$ nomad job status echo-bash
ID                   = echo-bash
Name                 = echo-bash
Submit Date          = 2021-09-23T19:43:56+02:00
Type                 = batch
Priority             = 50
Datacenters          = dc1
Namespace            = default
Status               = running
Periodic             = true
Parameterized        = false
Next Periodic Launch = 2021-09-23T17:45:00Z (31s from now)

Children Job Summary
Pending  Running  Dead
1        0        1

Previously Launched Jobs
ID                             Status
echo-bash/periodic-1632419040  dead

$ nomad job status echo-bash/periodic-1632419040
ID            = echo-bash/periodic-1632419040
Name          = echo-bash/periodic-1632419040
Submit Date   = 2021-09-23T19:44:00+02:00
Type          = batch
Priority      = 50
Datacenters   = dc1
Namespace     = default
Status        = dead
Periodic      = false
Parameterized = false

Summary
Task Group  Queued  Starting  Running  Failed  Complete  Lost
echo        0       0         0        0       1         0

Allocations
ID        Node ID   Task Group  Version  Desired  Status    Created  Modified
db6b9f1e  26b275d9  echo        0        run      complete  55s ago  55s ago

$ nomad alloc logs db6b9f1e
Hello Word! (bash)
nomad-job-run-echo-bash.sh
Terminal

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub.


Comparte el artículo: