--- title: "Cómo configurar un clúster de Elasticsearch en Ubuntu 24.04" description: "Monta un clúster de Elasticsearch de tres nodos en Ubuntu 24.04 con TLS y tokens de inscripción, comprueba su estado y verifica que resiste la caída de un nodo." category: "Base de Datos Avanzada" language: es source: https://cubepath.com/es/docs/base-de-datos-avanzada/configuracion-del-cluster-elasticsearch updated: 2026-09-25 --- # Cómo configurar un clúster de Elasticsearch en Ubuntu 24.04 Elasticsearch es un motor de búsqueda y análisis distribuido: reparte cada índice en fragmentos (shards) entre varios nodos y guarda réplicas de cada uno, de modo que el clúster sigue respondiendo si un nodo cae. En este tutorial montarás un clúster de tres nodos en Ubuntu 24.04 con el paquete oficial de Elastic, usando la configuración de seguridad automática (TLS y contraseñas) y tokens de inscripción para unir los nodos. Al final crearás un índice replicado y comprobarás que el clúster tolera la caída de un nodo. ## Requisitos previos - Tres servidores con Ubuntu 24.04 LTS, por ejemplo VPS de CubePath, con al menos 4 GB de RAM y 2 vCPU cada uno. - Una red privada entre ellos. En esta guía se usan estas direcciones y nombres de host: | Nodo | Hostname | IP privada | |------|----------|------------| | 1 | `es-node-1` | `10.0.0.11` | | 2 | `es-node-2` | `10.0.0.12` | | 3 | `es-node-3` | `10.0.0.13` | - Un usuario no root con privilegios `sudo` en cada servidor. - UFW activo en los tres nodos. Tres nodos es el mínimo recomendado: con tres nodos elegibles como maestro, el clúster mantiene el quórum (dos de tres) si uno falla. ## Paso 1: Preparar los tres servidores Ejecuta este paso en los **tres nodos**. Asigna a cada uno su hostname, porque Elasticsearch usa el nombre de host como nombre de nodo por defecto. En el nodo 1: ```bash sudo hostnamectl set-hostname es-node-1 ``` Repite con `es-node-2` y `es-node-3` en los otros servidores. A continuación, abre los puertos de Elasticsearch solo para la red privada: 9200 es la API HTTP y 9300 el transporte interno entre nodos: ```bash sudo ufw allow from 10.0.0.0/24 to any port 9200 proto tcp sudo ufw allow from 10.0.0.0/24 to any port 9300 proto tcp ``` Comprueba las reglas: ```bash sudo ufw status ``` ```output To Action From -- ------ ---- 9200/tcp ALLOW 10.0.0.0/24 9300/tcp ALLOW 10.0.0.0/24 ``` ## Paso 2: Instalar Elasticsearch desde el repositorio oficial También en los **tres nodos**, añade la clave GPG y el repositorio de Elastic para la rama 9.x: ```bash sudo apt update sudo apt install apt-transport-https ca-certificates curl gnupg curl -fsSL https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /etc/apt/keyrings/elasticsearch.gpg echo "deb [signed-by=/etc/apt/keyrings/elasticsearch.gpg] https://artifacts.elastic.co/packages/9.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-9.x.list ``` Instala el paquete: ```bash sudo apt update sudo apt install elasticsearch ``` Durante la instalación se ejecuta la configuración de seguridad automática, que genera certificados TLS y una contraseña para el superusuario `elastic`. La salida incluye un bloque como este: ```output --------------------------- Security autoconfiguration information ------------------------------ Authentication and authorization are enabled. TLS for the transport and HTTP layers is enabled and configured. The generated password for the elastic built-in superuser is : 7Hq*... ... ``` Guarda la contraseña del **nodo 1**, que es la que usarás en el clúster. Las de los nodos 2 y 3 se descartarán al unirlos. El paquete no arranca el servicio todavía; no lo inicies en los nodos 2 y 3 hasta el paso 5. > Nota: el paquete ajusta `vm.max_map_count` automáticamente y calcula el tamaño del heap de Java según la RAM del servidor, así que no hace falta tocar `sysctl` ni `jvm.options` para empezar. ## Paso 3: Configurar y arrancar el primer nodo En **es-node-1**, abre la configuración principal: ```bash sudo nano /etc/elasticsearch/elasticsearch.yml ``` Define el nombre del clúster. Debe ser idéntico en los tres nodos: ```yaml cluster.name: cubepath-es ``` Al final del archivo está el bloque que añadió la configuración automática. Contiene `cluster.initial_master_nodes: ["es-node-1"]`, `http.host: 0.0.0.0` y una línea comentada `#transport.host: 0.0.0.0`. Por defecto la capa de transporte solo escucha en localhost, así que los otros nodos no podrían conectarse. Sustituye esa línea comentada por la IP privada del nodo: ```yaml transport.host: 10.0.0.11 ``` Arranca Elasticsearch: ```bash sudo systemctl daemon-reload sudo systemctl enable --now elasticsearch ``` El primer arranque tarda un poco. Comprueba que responde usando la CA generada y la contraseña de `elastic`: ```bash sudo curl --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic https://localhost:9200 ``` ```output { "name" : "es-node-1", "cluster_name" : "cubepath-es", ... "tagline" : "You Know, for Search" } ``` Si has perdido la contraseña, genera una nueva con `sudo /usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic`. ## Paso 4: Generar un token de inscripción Los nodos nuevos se unen al clúster con un token de inscripción que contiene la dirección del nodo existente y la huella de su CA. Genéralo en **es-node-1**: ```bash sudo /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s node ``` ```output eyJ2ZXIiOiI5LjAuMCIsImFkciI6WyIxMC4wLjAuMTE6OTIwMCJdLCJmZ3IiOiI... ``` El token caduca a los 30 minutos. Si se te pasa el tiempo, genera otro. ## Paso 5: Unir los nodos 2 y 3 En **es-node-2**, antes de arrancar el servicio por primera vez, aplica el token. La herramienta sustituye los certificados autogenerados por los del clúster y configura `discovery.seed_hosts`: ```bash sudo /usr/share/elasticsearch/bin/elasticsearch-reconfigure-node --enrollment-token your_enrollment_token ``` Responde `y` a la confirmación. Después edita la configuración: ```bash sudo nano /etc/elasticsearch/elasticsearch.yml ``` Añade el mismo nombre de clúster y fija la dirección de transporte a la IP privada de este nodo: ```yaml cluster.name: cubepath-es transport.host: 10.0.0.12 ``` Si ya existe una línea `transport.host` en el bloque de seguridad, edítala en lugar de duplicarla. Arranca el servicio: ```bash sudo systemctl daemon-reload sudo systemctl enable --now elasticsearch ``` Repite el paso completo en **es-node-3** con un token nuevo si el anterior ha caducado, usando `transport.host: 10.0.0.13`. ## Paso 6: Verificar el clúster Desde cualquier nodo, lista los nodos del clúster: ```bash sudo curl -s --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic "https://localhost:9200/_cat/nodes?v&h=ip,name,node.role,master,heap.percent" ``` ```output ip name node.role master heap.percent 10.0.0.11 es-node-1 cdfhilmrstw * 21 10.0.0.12 es-node-2 cdfhilmrstw - 18 10.0.0.13 es-node-3 cdfhilmrstw - 17 ``` El asterisco marca el maestro elegido. Consulta la salud del clúster: ```bash sudo curl -s --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic "https://localhost:9200/_cluster/health?pretty" ``` ```output { "cluster_name" : "cubepath-es", "status" : "green", "number_of_nodes" : 3, "number_of_data_nodes" : 3, ... } ``` `green` significa que todos los shards primarios y réplicas están asignados. `yellow` indica réplicas sin asignar y `red`, shards primarios sin asignar. ## Paso 7: Dejar la configuración de descubrimiento definitiva `cluster.initial_master_nodes` solo sirve para formar el clúster la primera vez y debe eliminarse una vez formado; si se queda, un nodo reiniciado con el disco vacío podría crear un clúster nuevo por su cuenta. Además, conviene que cada nodo conozca a los tres para que no dependa solo del nodo 1 al reiniciar. En **cada nodo**, edita `/etc/elasticsearch/elasticsearch.yml`, borra o comenta la línea `cluster.initial_master_nodes` si existe y deja `discovery.seed_hosts` con los tres nodos (sustituye la línea que añadió la herramienta en los nodos 2 y 3): ```yaml discovery.seed_hosts: ["10.0.0.11:9300", "10.0.0.12:9300", "10.0.0.13:9300"] ``` Reinicia los nodos de uno en uno, esperando a que el estado vuelva a `green` antes de pasar al siguiente: ```bash sudo systemctl restart elasticsearch ``` ## Paso 8: Crear un índice con shards y réplicas Crea un índice de prueba con 3 shards primarios y 1 réplica de cada uno. Así cada nodo tendrá datos y cada shard existirá en dos nodos distintos: ```bash sudo curl -s --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic -X PUT "https://localhost:9200/logs-demo?pretty" \ -H 'Content-Type: application/json' \ -d '{ "settings": { "number_of_shards": 3, "number_of_replicas": 1 } }' ``` Indexa un documento: ```bash sudo curl -s --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic -X POST "https://localhost:9200/logs-demo/_doc?pretty" \ -H 'Content-Type: application/json' \ -d '{ "message": "hola desde el clúster", "level": "info" }' ``` Mira cómo se han repartido los shards (`p` es primario y `r` réplica): ```bash sudo curl -s --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic "https://localhost:9200/_cat/shards/logs-demo?v" ``` ```output index shard prirep state docs store ip node logs-demo 0 p STARTED 0 249b 10.0.0.12 es-node-2 logs-demo 0 r STARTED 0 249b 10.0.0.13 es-node-3 logs-demo 1 p STARTED 1 4.5kb 10.0.0.11 es-node-1 logs-demo 1 r STARTED 1 4.5kb 10.0.0.12 es-node-2 logs-demo 2 r STARTED 0 249b 10.0.0.11 es-node-1 logs-demo 2 p STARTED 0 249b 10.0.0.13 es-node-3 ``` Elasticsearch nunca coloca un primario y su réplica en el mismo nodo. ## Paso 9: Probar la tolerancia a fallos Detén Elasticsearch en **es-node-3**: ```bash sudo systemctl stop elasticsearch ``` Desde es-node-1, consulta la salud del clúster: ```bash sudo curl -s --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic "https://localhost:9200/_cluster/health?filter_path=status,number_of_nodes,unassigned_shards&pretty" ``` ```output { "status" : "yellow", "number_of_nodes" : 2, "unassigned_shards" : 2 } ``` El clúster sigue aceptando lecturas y escrituras: las réplicas del nodo caído se han promovido a primarias donde hacía falta. Pasado un minuto (el retraso por defecto de `index.unassigned.node_left.delayed_timeout`), Elasticsearch recrea las réplicas que faltan en los nodos restantes y vuelve a `green`. Arranca de nuevo es-node-3 y comprueba que vuelve a unirse: ```bash sudo systemctl start elasticsearch ``` ## Solución de problemas - **El nodo 2 o 3 forma su propio clúster**: se arrancó antes de aplicar el token. Detén el servicio, borra su directorio de datos (`sudo rm -rf /var/lib/elasticsearch/*`, solo en ese nodo nuevo y sin datos), vuelve a ejecutar `elasticsearch-reconfigure-node` y arráncalo. - **`elasticsearch-reconfigure-node` no conecta con el nodo 1**: comprueba que el puerto 9200 del nodo 1 es accesible desde la red privada y que el token no ha caducado. - **Fallos de bootstrap checks al arrancar**: al escuchar en una IP que no es localhost, Elasticsearch aplica comprobaciones de producción. Revisa `sudo journalctl -u elasticsearch` y `/var/log/elasticsearch/cubepath-es.log` para ver cuál falla. - **Estado `yellow` permanente**: el índice pide más réplicas de las que caben. Revisa el motivo con `GET _cluster/allocation/explain`. ## Conclusión Tienes un clúster de Elasticsearch de tres nodos en Ubuntu 24.04 con TLS en HTTP y transporte, autenticación y shards replicados que sobreviven a la caída de un nodo. Como siguientes pasos, crea usuarios con roles limitados en lugar de usar `elastic` desde las aplicaciones, define políticas de ciclo de vida (ILM) para rotar índices de logs, y configura snapshots periódicas a un repositorio S3 compatible.