Tutorial

Alojar Elasticsearch en un VPS: seguridad y diagnóstico

Bases de datos13 min de lectura6 pasos

Elasticsearch sigue siendo la referencia para la búsqueda full-text avanzada, las agregaciones anidadas y la centralización de logs a gran escala. Los servicios cloud gestionados facturan por volumen y por tráfico de salida; en un VPS bien dimensionado, usted controla la versión, los plugins de análisis y el coste. Esta guía cubre el despliegue con Docker paso a paso, la seguridad xpack, el endurecimiento de la red, la gestión del ciclo de vida de los índices (ILM), los snapshots automáticos hacia S3, la monitorización del heap de la JVM y los cinco fallos que casi todo el mundo encuentra en el primer arranque.

Contenido· Por qué alojar Elasticsearch en su propio VPS1/12
  1. 01Por qué alojar Elasticsearch en su propio VPS
  2. 02Lo que gana al autoalojar Elasticsearch
  3. 03Requisitos concretos antes de lanzar el primer contenedor
  4. 04Despliegue paso a paso
  5. 05Seguridad xpack: TLS, roles y aislamiento de red
  6. 06Endurecer el acceso de red con UFW
  7. 07Index Lifecycle Management (ILM): gestionar el ciclo de vida de los datos
  8. 08Snapshots hacia S3: copias de seguridad y recuperación ante desastres
  9. 09Monitorización del heap de la JVM: detectar OOM antes de que ocurra
  10. 10Kibana: exploración de índices y cuadros de mando (opcional)
  11. 11Diagnóstico: los 5 errores más habituales al arrancar
  12. 12¿Y si quiere una alternativa open source completa?

Por qué alojar Elasticsearch en su propio VPS

Elasticsearch destaca allí donde una búsqueda simple ya no basta: scoring BM25 configurable, sinónimos, analizadores lingüísticos personalizados (francés, árabe ICU), consultas geográficas y stack ELK completo para centralizar los logs de sus aplicaciones. Los servicios Elastic Cloud y OpenSearch Service se encarecen rápidamente en cuanto los volúmenes indexados superan unos pocos gigabytes, con facturación del egress como añadido. En su VPS, usted decide la versión desplegada, los plugins activados, la duración de retención y la política de snapshots. Es también la única manera de mantener datos sensibles estrictamente dentro de su propia infraestructura, sin depender de un tercero cloud.

En cuanto a la licencia, Elasticsearch volvió a ser open source en agosto de 2024: desde la versión 8.16, Elastic distribuye el código bajo la licencia AGPLv3 (aprobada por la OSI), junto con Elastic License y SSPL. Las versiones actuales en producción son 8.19.x (rama 8 de mantenimiento largo) y 9.x (rama principal desde 2025).

Lo que gana al autoalojar Elasticsearch

  • Búsqueda full-text avanzada: scoring BM25, sinónimos, analizadores lingüísticos personalizados (FR, AR ICU)
  • Agregaciones y facetas complejas para el e-commerce, la BI o la centralización de logs
  • Stack ELK completo (Logstash, Beats, Kibana) sin sobrecoste de software
  • Control total de la versión, de los plugins y de las index lifecycle policies (ILM)
  • Sin facturación por volumen indexado ni gastos de egress de red
  • Snapshots automáticos hacia su propio almacenamiento de objetos compatible con S3 mediante SLM
  • Datos sensibles conservados en su propia infraestructura, bajo su única jurisdicción

Requisitos concretos antes de lanzar el primer contenedor

RAM mínima: 4 GB para un entorno de pruebas, 8 GB (2-4 vCPU) para una instancia de producción ligera, 16 GB en cuanto añada Kibana o indexe varios millones de documentos. El parámetro clave es el heap de la JVM: fije -Xms y -Xmx al 50 % de la RAM disponible, sin superar 31 GB (por encima, la JVM pasa a un modo de compresión de punteros menos eficiente; el límite exacto es 31 GB con G1GC, no 32). Fije siempre -Xms igual a -Xmx: un heap infraasignado en el arranque que luego se amplía provoca largas pausas de GC.

En cuanto a la red, Elasticsearch utiliza dos puertos: 9200 (HTTP, API REST) y 9300 (transporte entre nodos). No exponga nunca el puerto 9200 directamente en la interfaz pública. En cuanto al almacenamiento, se recomienda un SSD NVMe. Prevea también Docker y Docker Compose, y un subdominio es.sudominio.com apuntando al VPS.

Despliegue paso a paso

  1. Preparar el kernel de Linux

    Antes de lanzar el contenedor, aplique dos ajustes de sistema obligatorios. Primero: sysctl -w vm.max_map_count=262144 (hágalo persistente en /etc/sysctl.conf). Después, desactive el swap (swapoff -a) o configure bootstrap.memory_lock=true en elasticsearch.yml.

  2. Escribir el archivo docker-compose.yml

    Cree un directorio de trabajo y un archivo docker-compose.yml con la imagen docker.elastic.co/elasticsearch/elasticsearch:8.19.4, la variable ES_JAVA_OPTS=-Xms4g -Xmx4g, un volumen con nombre para /usr/share/elasticsearch/data y el puerto 9200 enlazado únicamente a 127.0.0.1. Añada discovery.type=single-node para un despliegue de un solo nodo.

  3. Activar xpack.security y arrancar

    En elasticsearch.yml, compruebe que xpack.security.enabled: true y xpack.security.http.ssl.enabled: true estén activos. Lance el clúster: docker compose up -d. En el primer arranque, espere de 2 a 3 minutos. Consulte los logs: docker compose logs -f elasticsearch.

  4. Crear los usuarios y recuperar la contraseña de elastic

    Una vez arrancado el contenedor, restablezca la contraseña del superusuario elastic: docker exec -it elasticsearch bin/elasticsearch-reset-password -u elastic. Guárdela en un gestor de secretos. Cree después el usuario kibana_system si añade Kibana. No use este cuenta para consultas de aplicación.

  5. Verificar el clúster con curl

    Pruebe la conexión desde el VPS: curl -u elastic:<CONTRASEÑA> https://localhost:9200 --cacert /usr/share/elasticsearch/config/certs/http_ca.crt. Una respuesta JSON con cluster_name y status: green o yellow confirma que el clúster está operativo. Un estado yellow en un clúster de un solo nodo es normal.

  6. Exponer mediante reverse proxy HTTPS con Nginx

    Instale Nginx y configure un virtual host para es.sudominio.com. El reverse proxy transmite las peticiones hacia https://127.0.0.1:9200. Añada una autenticación básica de Nginx si la API debe ser accesible desde el exterior. Reenvíe solo las rutas necesarias para su aplicación.

Seguridad xpack: TLS, roles y aislamiento de red

La seguridad xpack de Elasticsearch cubre tres capas. TLS entre nodos (xpack.security.transport.ssl.enabled: true) cifra el tráfico en el puerto 9300. TLS HTTP (xpack.security.http.ssl.enabled: true) cifra el puerto 9200. Control de roles: asigne a cada aplicación el rol mínimo necesario. Evite usar la cuenta elastic en producción. El valor por defecto de network.host es _local_ (solo loopback) — no lo cambie a 0.0.0.0 sin haber configurado la seguridad xpack.

Endurecer el acceso de red con UFW

Después de verificar que Elasticsearch escucha únicamente en 127.0.0.1, bloquee el cortafuegos: ufw deny 9200/tcp y ufw deny 9300/tcp. Solo el reverse proxy Nginx (puerto 443) debe ser accesible. Si varios nodos se comunican entre sí, autorice explícitamente las IP de los nodos en el puerto 9300. Un ufw status tras la configuración le da la vista exacta de lo que está abierto.

Index Lifecycle Management (ILM): gestionar el ciclo de vida de los datos

ILM automatiza el ciclo de vida de sus índices según la edad o el tamaño, evitando la saturación del disco y manteniendo rápidas las consultas sobre los datos recientes. Una política ILM típica se divide en cuatro fases:

Fase hot: el índice recibe nuevos datos. Configure el rollover automático al alcanzar un tamaño (max_size: 50gb) o una edad (max_age: 7d). Los índices hot viven en sus SSDs NVMe más rápidos.

Fase warm: el índice solo se lee. Elasticsearch reduce las réplicas a 1 y realiza un force-merge de los segmentos de Lucene.

Fase cold: datos consultados raramente. Las réplicas bajan a 0 y el índice puede montarse en modo de solo lectura desde almacenamiento de objetos.

Fase delete: eliminación automática tras el período de retención definido (ejemplo: 90 días para logs).

PUT _ilm/policy/logs-policy
{
  "policy": {
    "phases": {
      "hot":  { "actions": { "rollover": { "max_age": "7d", "max_size": "50gb" } } },
      "warm": { "min_age": "7d",  "actions": { "forcemerge": { "max_num_segments": 1 }, "shrink": { "number_of_shards": 1 } } },
      "cold": { "min_age": "30d", "actions": { "freeze": {} } },
      "delete": { "min_age": "90d", "actions": { "delete": {} } }
    }
  }
}

En un VPS donde el espacio en disco está contado, es lo que impide que sus logs saturen el SSD y mantiene rápidas las consultas sobre los datos calientes.

Snapshots hacia S3: copias de seguridad y recuperación ante desastres

Los snapshots de Elasticsearch permiten respaldar el estado completo de sus índices en un almacenamiento de objetos compatible con S3. Combínelos con una Snapshot Lifecycle Policy (SLM) para automatizar las copias de seguridad y su retención.

1. Instalar el plugin S3 y configurar el repositorio:

docker exec -it elasticsearch bin/elasticsearch-plugin install repository-s3

Declare las claves de acceso en el keystore de Elasticsearch (nunca en texto claro):

docker exec -it elasticsearch bin/elasticsearch-keystore add s3.client.default.access_key
docker exec -it elasticsearch bin/elasticsearch-keystore add s3.client.default.secret_key

Registre el repositorio:

PUT _snapshot/s3-backup
{
  "type": "s3",
  "settings": {
    "bucket": "my-elasticsearch-bucket",
    "region": "eu-west-1",
    "base_path": "snapshots/production"
  }
}

2. Crear la Snapshot Lifecycle Policy:

PUT _slm/policy/daily-snapshots
{
  "schedule": "0 30 2 * * ?",
  "name": "<daily-snap-{now/d}>",
  "repository": "s3-backup",
  "config": { "indices": ["*"], "ignore_unavailable": true },
  "retention": { "expire_after": "30d", "min_count": 5, "max_count": 50 }
}

Esta política lanza un snapshot cada día a las 2:30 y purga los snapshots de más de 30 días conservando al menos 5 versiones. Pruebe la restauración desde un entorno de staging antes de necesitarla.

Monitorización del heap de la JVM: detectar OOM antes de que ocurra

En un VPS, el OOM killer del kernel de Linux puede terminar el proceso de Elasticsearch sin previo aviso. La monitorización proactiva del heap de la JVM evita el 80% de los incidentes en producción.

Métricas a vigilar mediante la API _nodes/stats:

- jvm.mem.heap_used_percent: lance una alerta por encima del 75% de media y una alerta crítica por encima del 85% durante 5 minutos. Una saturación sostenida al 90%+ indica una fuga de memoria o un heap infradimensionado.
- jvm.gc.collectors.old.collection_count y collection_time_in_millis: un aumento rápido en el número de GC old-gen y tiempos > 2 s por colección indican que la JVM dedica más tiempo a recoger que a trabajar.

Reglas operativas:

1. Si heap_used_percent supera el 75% en estado estacionario, aumente el heap (o la RAM del VPS) antes de sufrir el primer OOM.
2. No aumente el heap por encima de 31 GB: más allá de este umbral, el recolector de basura desactiva los punteros comprimidos (compressed oops) y la JVM consume más memoria por objeto.
3. Verifique periódicamente que bootstrap.memory_lock: true está activo con GET _nodes?filter_path=**.mlockall: un valor false indica que el swap sigue activo en el VPS.

Kibana: exploración de índices y cuadros de mando (opcional)

Kibana es la interfaz gráfica oficial de Elasticsearch para explorar índices, construir cuadros de mando y configurar alertas. No es obligatoria para el uso programático, pero simplifica la gestión de ILM, SLM e índices en general.

Añada Kibana al mismo archivo Compose:

kibana:
  image: docker.elastic.co/kibana/kibana:8.19.4
  environment:
    - ELASTICSEARCH_HOSTS=https://elasticsearch:9200
    - ELASTICSEARCH_USERNAME=kibana_system
    - ELASTICSEARCH_PASSWORD=<CONTRASEÑA_KIBANA_SYSTEM>
    - ELASTICSEARCH_SSL_CERTIFICATEAUTHORITIES=/usr/share/kibana/config/certs/http_ca.crt
  volumes:
    - /ruta/a/http_ca.crt:/usr/share/kibana/config/certs/http_ca.crt:ro
  depends_on:
    - elasticsearch

Exponga Kibana detrás de un proxy Nginx en kibana.sudominio.com con autenticación. No exponga Kibana directamente en internet sin autenticación: da acceso completo a la gestión del clúster. Desde Kibana, acceda a Stack Management → Index Lifecycle Policies y Snapshot and Restore para gestionar ILM y SLM visualmente.

Diagnóstico: los 5 errores más habituales al arrancar

1. El OOM Killer mata el proceso de Elasticsearch. Síntoma: el contenedor se detiene sin mensaje de error, dmesg | grep -i killed revela un Killed process. Corrección: reduzca -Xmx al 50% de la RAM libre real (máximo 31 GB) y vigile el consumo con docker stats.

2. max_map_count demasiado bajo. Síntoma: Elasticsearch se niega a arrancar con el error max virtual memory areas vm.max_map_count [65530] is too low. Corrección: sysctl -w vm.max_map_count=262144 y añada vm.max_map_count=262144 en /etc/sysctl.conf.

3. Permission denied en /usr/share/elasticsearch/data. Síntoma: error AccessDeniedException en los logs. Causa: el directorio del host pertenece a root pero el contenedor usa el UID 1000. Corrección: chown -R 1000:1000 <ruta_del_volumen_host>.

4. Conexión rechazada en el puerto 9200. Síntoma: curl localhost:9200 devuelve Connection refused. Causa frecuente: network.host mal configurado. Deje network.host en su valor por defecto (_local_) y acceda mediante 127.0.0.1:9200. Compruebe también: docker ps.

5. Arranque lento: normal en la primera inicialización. Síntoma: el clúster tarda de 2 a 3 minutos en responder. No es una avería. Espere a que los logs muestren Cluster health status changed from [RED] to [GREEN] antes de enviar peticiones.

¿Y si quiere una alternativa open source completa?

OpenSearch es el fork comunitario de Elasticsearch, nacido en 2021 cuando Elastic cambió su licencia a SSPL. OpenSearch conserva una licencia Apache 2.0 e incluye funciones de seguridad avanzadas en su distribución gratuita. Desde que Elastic reintrodujo AGPLv3 en agosto de 2024 con la versión 8.16, ambos proyectos están de nuevo bajo licencias aprobadas por la OSI — la elección depende ahora más del ecosistema (plugins, integraciones, soporte comercial) que de restricciones de licencia. El despliegue con Docker sigue el mismo esquema con la imagen opensearchproject/opensearch.

Un VPS a la medida de Elasticsearch

RAM generosa, SSD y ajustes del kernel modificables desde la creación: el VPS Cloud de ServOrbit le da la base que exige una JVM de Elasticsearch en producción.

¿Necesita ayuda?

Consulte nuestro centro de ayuda y nuestra FAQ, o contacte con nuestro equipo: llamada, WhatsApp o correo electrónico. Soporte en francés, inglés y árabe.

Escribir por WhatsAppse abre en una pestaña nueva