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
sudoen 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:
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:
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:
sudo ufw status
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:
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:
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:
--------------------------- 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.
Notael paquete ajusta
vm.max_map_countautomáticamente y calcula el tamaño del heap de Java según la RAM del servidor, así que no hace falta tocarsysctlnijvm.optionspara empezar.
Paso 3: Configurar y arrancar el primer nodo
En es-node-1, abre la configuración principal:
sudo nano /etc/elasticsearch/elasticsearch.yml
Define el nombre del clúster. Debe ser idéntico en los tres nodos:
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:
transport.host: 10.0.0.11
Arranca Elasticsearch:
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:
sudo curl --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic https://localhost:9200
{
"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:
sudo /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s node
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:
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:
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:
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:
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:
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"
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:
sudo curl -s --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic "https://localhost:9200/_cluster/health?pretty"
{
"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):
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:
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:
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:
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):
sudo curl -s --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic "https://localhost:9200/_cat/shards/logs-demo?v"
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:
sudo systemctl stop elasticsearch
Desde es-node-1, consulta la salud del clúster:
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"
{
"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:
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 ejecutarelasticsearch-reconfigure-nodey arráncalo. elasticsearch-reconfigure-nodeno 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 elasticsearchy/var/log/elasticsearch/cubepath-es.logpara ver cuál falla. - Estado
yellowpermanente: el índice pide más réplicas de las que caben. Revisa el motivo conGET _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.
