--- title: "Cómo instalar HashiCorp Nomad en Ubuntu 24.04" description: "Instala un clúster HashiCorp Nomad en Ubuntu 24.04 con un servidor y dos clientes Docker, despliega un job con health checks y actualízalo sin cortes." category: "Descubrimiento de Servicios" language: es source: https://cubepath.com/es/docs/descubrimiento-de-servicios/instalacion-y-uso-de-hashicorp-nomad updated: 2026-09-25 --- # Cómo instalar HashiCorp Nomad en Ubuntu 24.04 HashiCorp Nomad es un orquestador de cargas de trabajo: tú describes en un archivo *job* qué quieres ejecutar, cuántas copias y con qué recursos, y Nomad decide en qué nodos colocarlas y las mantiene en marcha. Es más sencillo de operar que Kubernetes (un único binario) y, además de contenedores Docker, puede ejecutar binarios nativos. En este tutorial montarás en Ubuntu 24.04 un clúster Nomad con un servidor y dos clientes Docker, desplegarás un servicio web con health checks y lo actualizarás de forma progresiva. ## Requisitos previos Para seguir esta guía necesitas: - Tres servidores con Ubuntu 24.04 LTS, por ejemplo tres VPS de CubePath, con al menos 1 GB de RAM el servidor y 2 GB cada cliente. - Un usuario no root con privilegios `sudo` en cada uno. - Una red privada entre los tres. En los ejemplos se usan estas direcciones, sustitúyelas por las tuyas: | Nombre | Rol | IP privada | |---|---|---| | nomad-server | Servidor | 10.0.1.10 | | nomad-client-01 | Cliente | 10.0.1.21 | | nomad-client-02 | Cliente | 10.0.1.22 | Los servidores Nomad guardan el estado del clúster y toman las decisiones de planificación; los clientes ejecutan las tareas. Esta guía usa un solo servidor para simplificar. En producción se usan tres servidores (con `bootstrap_expect = 3`) para que el clúster siga funcionando si cae uno. ## Paso 1: Instalar Nomad Ejecuta este paso en los tres nodos. Añade el repositorio oficial de HashiCorp con su clave en `/etc/apt/keyrings`: ```bash sudo apt update sudo apt install -y wget gpg lsb-release sudo install -m 0755 -d /etc/apt/keyrings wget -O- https://apt.releases.hashicorp.com/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/hashicorp-archive-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/hashicorp-archive-keyring.gpg] https://apt.releases.hashicorp.com $(lsb_release -cs) main" | sudo tee /etc/apt/sources.list.d/hashicorp.list ``` Instala Nomad: ```bash sudo apt update sudo apt install -y nomad nomad version ``` ```output Nomad v1.x.x BuildDate ... Revision ... ``` El paquete instala la configuración en `/etc/nomad.d/nomad.hcl`, el directorio de datos `/opt/nomad/data` y la unidad `nomad.service`. El agente se ejecuta como root porque los clientes necesitan gestionar contenedores, cgroups y redes. ## Paso 2: Instalar Docker en los clientes El driver `docker` de Nomad necesita Docker Engine en cada nodo cliente. En **nomad-client-01 y nomad-client-02**, instala el paquete de Ubuntu (si prefieres el repositorio oficial de Docker, el resultado para Nomad es el mismo): ```bash sudo apt install -y docker.io sudo systemctl enable --now docker ``` Comprueba que funciona: ```bash sudo docker run --rm hello-world ``` ```output Hello from Docker! This message shows that your installation appears to be working correctly. ``` ## Paso 3: Generar la clave de cifrado gossip Los servidores Nomad se comunican entre sí con un protocolo gossip que conviene cifrar. Genera una clave **en nomad-server**: ```bash nomad operator gossip keyring generate ``` ```output cg8StVXbQJ0gPvMd9o7yrg== ``` Guarda el valor, lo usarás en la configuración del servidor. Con varios servidores, todos deben tener la misma clave. ## Paso 4: Configurar el servidor En **nomad-server**, abre el archivo de configuración: ```bash sudo nano /etc/nomad.d/nomad.hcl ``` Sustituye su contenido por el siguiente, con tu IP privada y la clave del paso anterior: ```hcl datacenter = "dc1" data_dir = "/opt/nomad/data" bind_addr = "0.0.0.0" advertise { http = "10.0.1.10" rpc = "10.0.1.10" serf = "10.0.1.10" } server { enabled = true bootstrap_expect = 1 encrypt = "cg8StVXbQJ0gPvMd9o7yrg==" } client { enabled = false } ``` `bind_addr = "0.0.0.0"` hace que Nomad escuche en todas las interfaces, y el bloque `advertise` indica qué IP deben usar el resto de nodos para llegar a este. La API HTTP (puerto 4646) no tiene autenticación mientras no actives las ACLs, así que en el paso 6 la limitarás con el firewall. Valida la configuración, arranca el servicio y comprueba que el servidor se ha elegido líder: ```bash sudo nomad config validate /etc/nomad.d/ sudo systemctl enable --now nomad nomad server members ``` ```output Name Address Port Status Leader Raft Version Build Datacenter Region nomad-server.global 10.0.1.10 4648 alive true 3 1.x.x dc1 global ``` ## Paso 5: Configurar los clientes En **cada cliente**, abre el mismo archivo: ```bash sudo nano /etc/nomad.d/nomad.hcl ``` Sustituye su contenido por el siguiente. Cambia las IP del bloque `advertise` por la del cliente en el que estés: ```hcl datacenter = "dc1" data_dir = "/opt/nomad/data" bind_addr = "0.0.0.0" advertise { http = "10.0.1.21" rpc = "10.0.1.21" serf = "10.0.1.21" } client { enabled = true servers = ["10.0.1.10:4647"] meta { env = "production" } } plugin "docker" { config { allow_privileged = false } } ``` - `servers` indica a qué servidor debe registrarse el cliente, por el puerto RPC 4647. - `meta` añade etiquetas libres al nodo que después puedes usar en los jobs con `constraint`. - `allow_privileged = false` impide que un job lance contenedores privilegiados. Arranca Nomad en los dos clientes: ```bash sudo systemctl enable --now nomad ``` Desde cualquier nodo, comprueba que los clientes aparecen como `ready` y que el driver Docker está detectado: ```bash nomad node status ``` ```output ID Node Pool DC Name Class Drain Eligibility Status 5b1e2c3a default dc1 nomad-client-02 false eligible ready a7f09d41 default dc1 nomad-client-01 false eligible ready ``` ```bash nomad node status -self -verbose | grep -i 'driver.docker ' ``` Ejecútalo en un cliente: debe mostrar `driver.docker = 1`. Si no aparece, revisa que Docker está en marcha y consulta `sudo journalctl -u nomad -e`. ## Paso 6: Proteger los puertos con UFW Nomad usa el puerto 4646 para la API HTTP y la interfaz web, 4647 para RPC y 4648 para gossip entre servidores. Permite el tráfico solo desde la red privada en los tres nodos: ```bash sudo ufw allow OpenSSH sudo ufw allow from 10.0.1.0/24 to any port 4646:4648 proto tcp sudo ufw allow from 10.0.1.0/24 to any port 4648 proto udp sudo ufw enable ``` > Advertencia: Docker publica los puertos de los contenedores con sus propias reglas de iptables, que se evalúan antes que las de UFW. Los puertos dinámicos que Nomad asigna a los contenedores (rango 20000-32000 por defecto) serán accesibles desde fuera aunque UFW no los permita. Expón los servicios a Internet a través de un balanceador o proxy inverso, y filtra ese rango en el firewall de red si lo necesitas. ## Paso 7: Desplegar tu primer job Un job describe grupos de tareas (`group`) que Nomad coloca juntos en un mismo cliente. Crea el archivo del job en el servidor, en tu directorio personal: ```bash nano ~/web.nomad.hcl ``` ```hcl job "web" { datacenters = ["dc1"] type = "service" group "web" { count = 2 network { port "http" { to = 80 } } update { max_parallel = 1 min_healthy_time = "10s" healthy_deadline = "2m" auto_revert = true } service { name = "web" port = "http" provider = "nomad" check { type = "http" path = "/" interval = "10s" timeout = "2s" } } task "nginx" { driver = "docker" config { image = "nginx:1.26-alpine" ports = ["http"] } resources { cpu = 200 memory = 128 } } } } ``` Qué define este job: - `count = 2`: dos instancias del grupo, que Nomad reparte entre los clientes disponibles. - `port "http" { to = 80 }`: Nomad asigna un puerto dinámico en el host y lo redirige al puerto 80 del contenedor. - `service` con `provider = "nomad"`: registra cada instancia en el catálogo de servicios integrado de Nomad, con un health check HTTP. No necesitas Consul para esto. - `update`: en cada despliegue actualiza las instancias de una en una y vuelve a la versión anterior si la nueva no supera los health checks. - `resources`: CPU en MHz y memoria en MB reservados para la tarea. Revisa qué haría Nomad sin aplicar nada: ```bash nomad job plan ~/web.nomad.hcl ``` ```output + Job: "web" + Task Group: "web" (2 create) + Task: "nginx" (forces create) Scheduler dry-run: - All tasks successfully allocated. ``` Lanza el job: ```bash nomad job run ~/web.nomad.hcl ``` Nomad muestra el progreso del despliegue y termina cuando las dos instancias están sanas. Consulta el estado del job: ```bash nomad job status web ``` ```output Allocations ID Node ID Task Group Version Desired Status Created Modified 3f0a91c2 a7f09d41 web 0 run running 45s ago 30s ago b82d7e55 5b1e2c3a web 0 run running 45s ago 31s ago ``` Cada fila es una *allocation*, es decir, una instancia del grupo colocada en un cliente concreto. ## Paso 8: Descubrir el servicio y ver los logs Consulta en qué direcciones y puertos está disponible el servicio: ```bash nomad service info web ``` ```output Job ID Address Tags Node ID Alloc ID web 10.0.1.21:24561 [] a7f09d41 3f0a91c2 web 10.0.1.22:28734 [] 5b1e2c3a b82d7e55 ``` Pruébalo con una petición HTTP a una de esas direcciones: ```bash curl -I http://10.0.1.21:24561 ``` ```output HTTP/1.1 200 OK Server: nginx/1.26.x ``` Otras aplicaciones del clúster pueden leer estas direcciones con plantillas en el bloque `template` de sus jobs (función `nomadService`), de modo que un proxy inverso se reconfigura solo cuando las instancias cambian. Para ver los logs de una instancia, usa el ID de su allocation: ```bash nomad alloc logs 3f0a91c2 nginx ``` Y si necesitas entrar en el contenedor: ```bash nomad alloc exec -task nginx 3f0a91c2 /bin/sh ``` ## Paso 9: Escalar y actualizar el job Para cambiar el número de instancias o la imagen, edita el archivo del job y vuelve a ejecutarlo. Cambia `count = 2` por `count = 3` y la imagen por `nginx:1.27-alpine`: ```bash nano ~/web.nomad.hcl ``` Revisa el plan: verás una instancia nueva y las existentes marcadas para actualizarse. ```bash nomad job plan ~/web.nomad.hcl nomad job run ~/web.nomad.hcl ``` Gracias al bloque `update`, Nomad sustituye las instancias de una en una y espera a que cada una pase su health check antes de seguir. Consulta el despliegue: ```bash nomad job status web ``` Si algo sale mal y `auto_revert` no lo ha resuelto por sí mismo, vuelve a la versión anterior del job. Consulta el historial y revierte a la versión 0: ```bash nomad job history web nomad job revert web 0 ``` Para eliminar el job y detener todas sus instancias: ```bash nomad job stop -purge web ``` ## Paso 10: Acceder a la interfaz web La interfaz web de Nomad está en el puerto 4646 del servidor, que solo es accesible desde la red privada. Ábrela desde tu equipo con un túnel SSH: ```bash ssh -L 4646:10.0.1.10:4646 your_user@your_server_ip ``` Con el túnel abierto, visita `http://localhost:4646/ui`. Verás los jobs, las allocations, los clientes y el uso de recursos de cada uno. ## Solución de problemas - **Un cliente no aparece en `nomad node status`:** comprueba que llega al servidor con `nc -zv 10.0.1.10 4647` y que la IP de `servers` es correcta. Revisa `sudo journalctl -u nomad -e` en el cliente. - **`Constraint "missing drivers" filtered 2 nodes`:** Docker no está instalado o no está en marcha en los clientes. Arráncalo con `sudo systemctl start docker` y reinicia Nomad. - **`Dimension "memory" exhausted`:** los clientes no tienen memoria libre para las instancias pedidas. Reduce `memory` en `resources` o añade clientes. - **El despliegue no termina y se revierte:** el health check falla. Mira el motivo con `nomad alloc status ` y los logs de la tarea con `nomad alloc logs`. ## Conclusión Tienes un clúster Nomad con un servidor y dos clientes Docker, y un servicio web desplegado con health checks, descubrimiento de servicios integrado y actualizaciones progresivas con vuelta atrás automática. Como siguientes pasos, activa las ACLs con `nomad acl bootstrap` antes de dar acceso a otras personas, amplía el clúster a tres servidores para tener alta disponibilidad y pon delante de tus servicios un proxy inverso que lea el catálogo con `nomadService`.