--- title: "Cómo instalar un clúster Consul en Ubuntu 24.04" description: "Despliega un clúster de tres servidores HashiCorp Consul en Ubuntu 24.04 con cifrado gossip, registra servicios con health checks y resuélvelos por DNS." category: "Descubrimiento de Servicios" language: es source: https://cubepath.com/es/docs/descubrimiento-de-servicios/instalacion-de-consul-y-descubrimiento-de-servicios updated: 2026-09-25 --- # Cómo instalar un clúster Consul en Ubuntu 24.04 HashiCorp Consul es una herramienta de descubrimiento de servicios: cada servicio se registra en el catálogo de Consul con su dirección, su puerto y una comprobación de salud, y el resto de la infraestructura lo encuentra por DNS o por la API HTTP. Además incluye un almacén clave-valor (KV) para configuración compartida. En este tutorial montarás un clúster de tres servidores Consul en Ubuntu 24.04, registrarás un servicio web con un health check y lo resolverás por DNS desde el propio sistema. ## Requisitos previos Para seguir esta guía necesitas: - Tres servidores con Ubuntu 24.04 LTS, por ejemplo tres VPS de CubePath, con al menos 2 GB de RAM cada uno. - Un usuario no root con privilegios `sudo` en cada servidor. - Una red privada entre los tres servidores. En los ejemplos se usan estas direcciones, sustitúyelas por las tuyas: | Nombre | IP privada | |---|---| | consul-01 | 10.0.1.10 | | consul-02 | 10.0.1.11 | | consul-03 | 10.0.1.12 | - Relojes sincronizados (Ubuntu 24.04 trae `systemd-timesyncd` activo por defecto; compruébalo con `timedatectl`). Salvo que se indique lo contrario, ejecuta cada paso en los tres servidores. ## Paso 1: Instalar Consul desde el repositorio de HashiCorp HashiCorp publica paquetes firmados para Ubuntu. Instala las herramientas necesarias y descarga la clave del repositorio 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 ``` Añade el repositorio: ```bash 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 Consul: ```bash sudo apt update sudo apt install -y consul ``` El paquete crea el usuario de sistema `consul`, el directorio de datos `/opt/consul`, la configuración en `/etc/consul.d/` y la unidad systemd `consul.service`, así que no tienes que crear nada de eso a mano. Comprueba la versión instalada: ```bash consul version ``` ```output Consul v1.x.x Revision ... ``` ## Paso 2: Generar la clave de cifrado gossip Los agentes Consul se comunican entre sí con un protocolo gossip que conviene cifrar. Genera la clave **solo una vez, en consul-01**: ```bash consul keygen ``` ```output pUqJrVyVRj5jsiYEkM/tFQYfWyJIv4s3XkvDwy7Cu5s= ``` Copia el valor que obtengas: lo usarás en el archivo de configuración de los tres servidores. Trátalo como un secreto. ## Paso 3: Configurar los servidores Consul Abre el archivo de configuración que instaló el paquete: ```bash sudo nano /etc/consul.d/consul.hcl ``` Sustituye su contenido por el siguiente bloque. Cambia `node_name` y `bind_addr` en cada servidor, y pon en `encrypt` la clave del paso anterior: ```hcl datacenter = "dc1" node_name = "consul-01" data_dir = "/opt/consul" server = true bootstrap_expect = 3 bind_addr = "10.0.1.10" client_addr = "127.0.0.1" retry_join = ["10.0.1.10", "10.0.1.11", "10.0.1.12"] encrypt = "pUqJrVyVRj5jsiYEkM/tFQYfWyJIv4s3XkvDwy7Cu5s=" ui_config { enabled = true } log_level = "INFO" ``` Qué hace cada ajuste: - `server` y `bootstrap_expect = 3`: el nodo actúa como servidor y el clúster no elige líder hasta que haya tres servidores unidos. - `bind_addr`: la IP privada por la que el nodo habla con el resto del clúster. - `client_addr = "127.0.0.1"`: la API HTTP (puerto 8500), la interfaz web y el DNS (puerto 8600) solo escuchan en local. Sin ACLs activadas, exponer la API a otras máquinas permite a cualquiera modificar el catálogo. - `retry_join`: lista de servidores a los que el nodo intenta unirse hasta conseguirlo, sin importar el orden de arranque. Valida la sintaxis antes de arrancar: ```bash sudo consul validate /etc/consul.d/ ``` ```output Configuration is valid! ``` ## Paso 4: Abrir los puertos en el firewall Consul usa estos puertos entre servidores: 8300/tcp (RPC), 8301/tcp y udp (gossip LAN) y 8302/tcp y udp (gossip WAN). Permite el tráfico solo desde la red privada. Si UFW aún no está activo, permite antes SSH para no perder el acceso: ```bash sudo ufw allow OpenSSH sudo ufw allow from 10.0.1.0/24 to any port 8300:8302 proto tcp sudo ufw allow from 10.0.1.0/24 to any port 8301:8302 proto udp sudo ufw enable ``` Comprueba las reglas: ```bash sudo ufw status ``` ## Paso 5: Arrancar el clúster Habilita e inicia el servicio en los tres servidores: ```bash sudo systemctl enable --now consul ``` Comprueba que el servicio está activo: ```bash sudo systemctl status consul ``` Cuando los tres nodos estén en marcha, lista los miembros del clúster desde cualquiera de ellos: ```bash consul members ``` ```output Node Address Status Type Build Protocol DC Partition Segment consul-01 10.0.1.10:8301 alive server 1.x.x 2 dc1 default consul-02 10.0.1.11:8301 alive server 1.x.x 2 dc1 default consul-03 10.0.1.12:8301 alive server 1.x.x 2 dc1 default ``` Comprueba que se ha elegido un líder de Raft: ```bash consul operator raft list-peers ``` ```output Node ID Address State Voter RaftProtocol consul-01 8f3a... 10.0.1.10:8300 leader true 3 consul-02 1c7e... 10.0.1.11:8300 follower true 3 consul-03 a42d... 10.0.1.12:8300 follower true 3 ``` Si un nodo no aparece, revisa sus logs con `sudo journalctl -u consul -e`. ## Paso 6: Registrar un servicio con health check Como ejemplo, registrarás un servidor web Nginx en **consul-01**. Instálalo: ```bash sudo apt install -y nginx ``` Crea el archivo de definición del servicio: ```bash sudo nano /etc/consul.d/web.hcl ``` ```hcl service { name = "web" port = 80 tags = ["nginx"] check { id = "web-http" name = "HTTP en el puerto 80" http = "http://127.0.0.1:80/" interval = "10s" timeout = "2s" } } ``` El health check hace una petición HTTP cada 10 segundos. Mientras responda con un código 2xx el servicio figura como sano; si falla, Consul deja de devolverlo en las consultas DNS. Ajusta el propietario del archivo y recarga la configuración del agente sin reiniciarlo: ```bash sudo chown consul:consul /etc/consul.d/web.hcl consul reload ``` ```output Configuration reload triggered ``` Comprueba que el servicio aparece en el catálogo y qué nodos lo ofrecen: ```bash consul catalog services consul catalog nodes -service=web ``` ```output consul web Node ID Address DC consul-01 8f3a... 10.0.1.10 dc1 ``` Consulta el estado del health check a través de la API HTTP. El parámetro `passing` filtra solo las instancias sanas: ```bash curl -s "http://127.0.0.1:8500/v1/health/service/web?passing" | python3 -m json.tool | grep -E '"(Status|ServiceName)"' ``` ```output "Status": "passing", "ServiceName": "web", ``` Para registrar el mismo servicio en otras máquinas, repite este paso en cada una. En producción, las máquinas que ejecutan aplicaciones no son servidores Consul, sino agentes cliente (misma instalación con `server = false` y sin `bootstrap_expect`). ## Paso 7: Resolver servicios por DNS Consul responde consultas DNS en el puerto 8600 con el formato `.service.consul`. Pruébalo con `dig`: ```bash dig @127.0.0.1 -p 8600 web.service.consul +short ``` ```output 10.0.1.10 ``` Los registros SRV incluyen también el puerto: ```bash dig @127.0.0.1 -p 8600 web.service.consul SRV +short ``` ```output 1 1 80 consul-01.node.dc1.consul. ``` Para que cualquier programa resuelva nombres `.consul` sin indicar el puerto, reenvía ese dominio a Consul desde `systemd-resolved`. Crea el directorio de configuración adicional y el archivo: ```bash sudo mkdir -p /etc/systemd/resolved.conf.d sudo nano /etc/systemd/resolved.conf.d/consul.conf ``` ```ini [Resolve] DNS=127.0.0.1:8600 Domains=~consul ``` `Domains=~consul` hace que solo las consultas del dominio `consul` vayan a ese servidor; el resto sigue usando tus DNS habituales. Reinicia el servicio y prueba la resolución normal: ```bash sudo systemctl restart systemd-resolved resolvectl query web.service.consul ``` ```output web.service.consul: 10.0.1.10 ``` Ahora cualquier aplicación del servidor puede conectarse a `web.service.consul` y recibirá solo instancias sanas. ## Paso 8: Guardar configuración en el almacén KV El almacén clave-valor sirve para configuración que comparten varios servicios. Escribe un par de claves: ```bash consul kv put config/web/max_connections 100 consul kv put config/web/log_level info ``` ```output Success! Data written to: config/web/max_connections Success! Data written to: config/web/log_level ``` Léelas de forma individual o por prefijo: ```bash consul kv get config/web/max_connections consul kv get -recurse config/web/ ``` ```output 100 config/web/log_level:info config/web/max_connections:100 ``` Los datos se replican a los tres servidores, así que puedes leerlos desde cualquiera. Para una copia de seguridad de un prefijo en JSON: ```bash consul kv export config/ > consul-kv-config.json ``` Para una copia completa del estado del clúster (catálogo, KV y demás), usa un snapshot: ```bash consul snapshot save consul-$(date +%F).snap ``` ## Paso 9: Acceder a la interfaz web La interfaz web escucha en `127.0.0.1:8500`, así que no está expuesta a Internet. Accede a ella con un túnel SSH desde tu equipo: ```bash ssh -L 8500:127.0.0.1:8500 your_user@your_server_ip ``` Con el túnel abierto, visita `http://localhost:8500/ui` en tu navegador. Verás los servicios, los nodos, el estado de los health checks y el almacén KV. ## Solución de problemas - **`consul members` solo muestra un nodo:** los servidores no se ven entre sí. Comprueba que el puerto 8301 (tcp y udp) está permitido en UFW y que `bind_addr` es la IP privada correcta. Prueba la conectividad con `nc -zv 10.0.1.11 8301`. - **Errores `No cluster leader`:** todavía no hay tres servidores unidos, porque `bootstrap_expect = 3`. Revisa que los tres servicios están activos. - **Errores de gossip con `encrypt`:** la clave no es la misma en todos los nodos. Copia exactamente el mismo valor en los tres y reinicia con `sudo systemctl restart consul`. - **El servicio no aparece en DNS:** el health check está fallando. Mira el estado con la consulta a `/v1/health/service/web` sin `?passing` y revisa que la URL del check responde con `curl -I http://127.0.0.1/`. - **Nodo caído que sigue en la lista:** si un servidor se ha eliminado definitivamente, sácalo del clúster con `consul force-leave consul-03`. ## Conclusión Tienes un clúster Consul de tres servidores con cifrado gossip, un servicio registrado con health check, resolución DNS integrada en `systemd-resolved` y un almacén KV replicado. Como siguientes pasos, activa el sistema de ACLs para proteger la API antes de exponerla fuera de `127.0.0.1`, instala agentes cliente en las máquinas que ejecutan tus aplicaciones y usa `consul-template` para generar configuraciones de Nginx o HAProxy a partir del catálogo.