Instalación de Elasticsearch y Logstash
Introducción
El ELK Stack (Elasticsearch, Logstash, Kibana) se ha convertido en el estándar de la industria para el registro centralizado, análisis de logs y visualización de datos. Elasticsearch proporciona potentes capacidades de búsqueda y análisis de texto completo, mientras que Logstash actúa como un pipeline de procesamiento de datos que ingiere, transforma y reenvía logs a Elasticsearch para almacenamiento y análisis.
El registro centralizado es crucial para la gestión moderna de infraestructura, permitiéndote agregar logs de múltiples servidores, aplicaciones y servicios en un repositorio único y consultable. Esta centralización simplifica la solución de problemas, el análisis de seguridad, los informes de cumplimiento y las perspectivas operacionales a través de sistemas distribuidos.
Esta guía completa te lleva a través de la instalación y configuración de Elasticsearch y Logstash en servidores Linux. Aprenderás cómo configurar una infraestructura de registro lista para producción, configurar pipelines de ingesta de datos, optimizar el rendimiento, implementar seguridad e integrar con varias fuentes de logs. Ya sea que estés construyendo un nuevo sistema de registro o migrando desde soluciones heredadas, esta guía proporciona la base para una gestión efectiva de logs.
Requisitos Previos
Antes de instalar Elasticsearch y Logstash, asegúrate de tener:
- Un servidor Linux (Ubuntu 20.04/22.04, Debian 10/11, CentOS 7/8, Rocky Linux 8/9)
- Acceso root o sudo para instalación y configuración
- Java 11 o Java 17 (OpenJDK u Oracle JDK)
- Mínimo 4 GB RAM (8 GB recomendado para producción)
- Mínimo 10 GB de espacio en disco (escala con el volumen de logs)
- Comprensión básica de JSON y formatos de log
Requisitos de Sistema Recomendados:
- Desarrollo: 4 GB RAM, 2 núcleos CPU, 20 GB disco
- Producción: 16 GB RAM, 4-8 núcleos CPU, 100+ GB almacenamiento SSD
- Alto Volumen: 32+ GB RAM, 8+ núcleos CPU, 500+ GB almacenamiento SSD
Instalación de Java
Tanto Elasticsearch como Logstash requieren Java. Instalemos OpenJDK 11 o 17.
En Ubuntu/Debian
# Actualizar repositorio de paquetes
sudo apt update
# Instalar OpenJDK 11
sudo apt install openjdk-11-jdk -y
# O instalar OpenJDK 17
sudo apt install openjdk-17-jdk -y
# Verificar instalación
java -version
# Establecer JAVA_HOME
echo 'export JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64' >> ~/.bashrc
source ~/.bashrc
En CentOS/Rocky Linux
# Instalar OpenJDK 11
sudo yum install java-11-openjdk java-11-openjdk-devel -y
# O instalar OpenJDK 17
sudo dnf install java-17-openjdk java-17-openjdk-devel -y
# Verificar instalación
java -version
# Establecer JAVA_HOME
echo 'export JAVA_HOME=/usr/lib/jvm/java-11-openjdk' >> ~/.bashrc
source ~/.bashrc
Instalación de Elasticsearch
Método 1: Repositorio Oficial (Recomendado)
En Ubuntu/Debian:
# Importar clave GPG de Elasticsearch
wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg
# Agregar repositorio de Elasticsearch
echo "deb [signed-by=/usr/share/keyrings/elasticsearch-keyring.gpg] https://artifacts.elastic.co/packages/8.x/apt stable main" | sudo tee /etc/apt/sources.list.d/elastic-8.x.list
# Actualizar índice de paquetes
sudo apt update
# Instalar Elasticsearch
sudo apt install elasticsearch -y
En CentOS/Rocky Linux:
# Importar clave GPG de Elasticsearch
sudo rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
# Crear archivo de repositorio
sudo tee /etc/yum.repos.d/elasticsearch.repo <<EOF
[elasticsearch]
name=Elasticsearch repository for 8.x packages
baseurl=https://artifacts.elastic.co/packages/8.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md
EOF
# Instalar Elasticsearch
sudo yum install elasticsearch -y
Método 2: Descarga Directa
# Descargar Elasticsearch (verificar la última versión)
wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-8.11.0-linux-x86_64.tar.gz
# Extraer archivo
tar -xzf elasticsearch-8.11.0-linux-x86_64.tar.gz
# Mover a /opt
sudo mv elasticsearch-8.11.0 /opt/elasticsearch
# Crear usuario elasticsearch
sudo useradd -r -s /bin/false elasticsearch
# Establecer propiedad
sudo chown -R elasticsearch:elasticsearch /opt/elasticsearch
Configuración Inicial de Elasticsearch
Configurar tamaño de heap JVM:
# Editar opciones JVM
sudo nano /etc/elasticsearch/jvm.options
# Establecer tamaño de heap (típicamente 50% de RAM disponible, máx 32GB)
-Xms4g
-Xmx4g
Configuración básica de Elasticsearch:
# Editar configuración principal
sudo nano /etc/elasticsearch/elasticsearch.yml
# Nombre del cluster
cluster.name: my-logging-cluster
# Nombre del nodo
node.name: node-1
# Configuración de red
network.host: 0.0.0.0
http.port: 9200
# Configuración de descubrimiento (nodo único para desarrollo)
discovery.type: single-node
# Rutas de datos y logs
path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
# Deshabilitar seguridad para configuración inicial (habilitar en producción)
xpack.security.enabled: false
xpack.security.enrollment.enabled: false
Iniciar Elasticsearch:
# Habilitar e iniciar Elasticsearch
sudo systemctl daemon-reload
sudo systemctl enable elasticsearch
sudo systemctl start elasticsearch
# Verificar estado
sudo systemctl status elasticsearch
# Ver logs
sudo journalctl -u elasticsearch -f
Verificar que Elasticsearch está ejecutándose:
# Probar conexión (esperar 30-60 segundos para el inicio)
curl -X GET "localhost:9200/"
# Salida esperada:
# {
# "name" : "node-1",
# "cluster_name" : "my-logging-cluster",
# "version" : { ... },
# ...
# }
# Verificar salud del cluster
curl -X GET "localhost:9200/_cluster/health?pretty"
Instalación de Logstash
Método 1: Repositorio Oficial (Recomendado)
El repositorio de Elasticsearch ya incluye Logstash.
En Ubuntu/Debian:
# Repositorio ya agregado en la instalación de Elasticsearch
sudo apt update
sudo apt install logstash -y
En CentOS/Rocky Linux:
# Repositorio ya agregado en la instalación de Elasticsearch
sudo yum install logstash -y
Método 2: Descarga Directa
# Descargar Logstash
wget https://artifacts.elastic.co/downloads/logstash/logstash-8.11.0-linux-x86_64.tar.gz
# Extraer archivo
tar -xzf logstash-8.11.0-linux-x86_64.tar.gz
# Mover a /opt
sudo mv logstash-8.11.0 /opt/logstash
# Crear usuario logstash
sudo useradd -r -s /bin/false logstash
# Establecer propiedad
sudo chown -R logstash:logstash /opt/logstash
Configuración de Logstash
Configurar heap JVM:
# Editar opciones JVM
sudo nano /etc/logstash/jvm.options
# Establecer tamaño de heap (típicamente 25% de RAM disponible)
-Xms2g
-Xmx2g
Configuración principal de Logstash:
# Editar logstash.yml
sudo nano /etc/logstash/logstash.yml
# Nombre del nodo
node.name: logstash-1
# Ruta de datos
path.data: /var/lib/logstash
# Ruta de configuración del pipeline
path.config: /etc/logstash/conf.d
# Ruta de logs
path.logs: /var/log/logstash
# Configuración del pipeline
pipeline.workers: 2
pipeline.batch.size: 125
pipeline.batch.delay: 50
# Monitoreo
monitoring.enabled: false
Creación de Pipeline de Logstash
Crear directorio de configuración del pipeline:
sudo mkdir -p /etc/logstash/conf.d
Configuración básica del pipeline (ejemplo syslog):
sudo nano /etc/logstash/conf.d/syslog-pipeline.conf
# Sección de entrada
input {
# Entrada syslog
tcp {
port => 5000
type => "syslog"
}
udp {
port => 5000
type => "syslog"
}
# Entrada de archivo
file {
path => "/var/log/syslog"
start_position => "beginning"
sincedb_path => "/dev/null"
type => "syslog-file"
}
}
# Sección de filtro
filter {
if [type] == "syslog" {
grok {
match => { "message" => "%{SYSLOGLINE}" }
}
date {
match => [ "timestamp", "MMM d HH:mm:ss", "MMM dd HH:mm:ss" ]
}
}
}
# Sección de salida
output {
elasticsearch {
hosts => ["localhost:9200"]
index => "syslog-%{+YYYY.MM.dd}"
}
# También salida a stdout para depuración
stdout {
codec => rubydebug
}
}
Iniciar Logstash:
# Habilitar e iniciar Logstash
sudo systemctl enable logstash
sudo systemctl start logstash
# Verificar estado
sudo systemctl status logstash
# Ver logs
sudo journalctl -u logstash -f
Probar pipeline de Logstash:
# Enviar log de prueba vía TCP
echo "<14>Jan 11 10:00:00 testhost test: This is a test message" | nc localhost 5000
# Verificar si los datos llegaron a Elasticsearch
curl -X GET "localhost:9200/syslog-*/_search?pretty" -H 'Content-Type: application/json' -d'
{
"query": {
"match_all": {}
}
}
'
Pipelines Avanzados de Logstash
Pipeline de Access Log de Apache/Nginx
sudo nano /etc/logstash/conf.d/apache-access.conf
input {
file {
path => "/var/log/apache2/access.log"
start_position => "beginning"
sincedb_path => "/var/lib/logstash/sincedb/apache-access"
type => "apache-access"
}
file {
path => "/var/log/nginx/access.log"
start_position => "beginning"
sincedb_path => "/var/lib/logstash/sincedb/nginx-access"
type => "nginx-access"
}
}
filter {
if [type] == "apache-access" {
grok {
match => { "message" => '%{IPORHOST:clientip} %{USER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" %{NUMBER:response} (?:%{NUMBER:bytes}|-)' }
}
date {
match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
}
geoip {
source => "clientip"
}
useragent {
source => "agent"
target => "user_agent"
}
}
if [type] == "nginx-access" {
grok {
match => { "message" => '%{IPORHOST:clientip} - %{USER:ident} \[%{HTTPDATE:timestamp}\] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" %{NUMBER:response} (?:%{NUMBER:bytes}|-) "(?:%{DATA:referrer}|-)" "(?:%{DATA:agent}|-)"' }
}
date {
match => [ "timestamp", "dd/MMM/yyyy:HH:mm:ss Z" ]
}
geoip {
source => "clientip"
}
}
}
output {
if [type] == "apache-access" {
elasticsearch {
hosts => ["localhost:9200"]
index => "apache-access-%{+YYYY.MM.dd}"
}
}
if [type] == "nginx-access" {
elasticsearch {
hosts => ["localhost:9200"]
index => "nginx-access-%{+YYYY.MM.dd}"
}
}
}
Pipeline de Log de Aplicación (JSON)
sudo nano /etc/logstash/conf.d/app-json.conf
input {
file {
path => "/var/log/myapp/app.json"
codec => "json"
type => "app-json"
}
}
filter {
# Parsear campos JSON
json {
source => "message"
}
# Agregar campos personalizados
mutate {
add_field => {
"application" => "myapp"
"environment" => "production"
}
}
# Convertir nivel de log a minúsculas
mutate {
lowercase => ["level"]
}
# Parsear timestamp si está presente
date {
match => ["timestamp", "ISO8601"]
}
}
output {
elasticsearch {
hosts => ["localhost:9200"]
index => "app-%{application}-%{+YYYY.MM.dd}"
}
}
Configuración Multi-Pipeline
sudo nano /etc/logstash/pipelines.yml
- pipeline.id: syslog-pipeline
path.config: "/etc/logstash/conf.d/syslog-pipeline.conf"
pipeline.workers: 2
- pipeline.id: apache-pipeline
path.config: "/etc/logstash/conf.d/apache-access.conf"
pipeline.workers: 1
- pipeline.id: app-pipeline
path.config: "/etc/logstash/conf.d/app-json.conf"
pipeline.workers: 1
# Reiniciar Logstash para aplicar
sudo systemctl restart logstash
Ajuste de Rendimiento
Rendimiento de Elasticsearch
Optimizar configuración JVM:
sudo nano /etc/elasticsearch/jvm.options
# Tamaño de heap (50% de RAM, máx 32GB)
-Xms16g
-Xmx16g
# Configuración GC
-XX:+UseG1GC
-XX:G1ReservePercent=25
-XX:InitiatingHeapOccupancyPercent=30
Optimizar configuración de Elasticsearch:
sudo nano /etc/elasticsearch/elasticsearch.yml
# Thread pools
thread_pool.write.queue_size: 1000
thread_pool.search.queue_size: 1000
# Configuración de indexación
indices.memory.index_buffer_size: 30%
# Caché de consultas
indices.queries.cache.size: 15%
# Caché de fielddata
indices.fielddata.cache.size: 40%
# Intervalo de refresco (aumentar para mejor rendimiento de indexación)
indices.refresh_interval: 30s
Rendimiento de Logstash
Optimizar workers del pipeline:
sudo nano /etc/logstash/logstash.yml
# Aumentar workers (uno por núcleo CPU)
pipeline.workers: 4
# Aumentar tamaño de lote
pipeline.batch.size: 250
# Ajustar retraso de lote
pipeline.batch.delay: 50
# Workers de salida
pipeline.output.workers: 2
Ajuste específico del pipeline:
output {
elasticsearch {
hosts => ["localhost:9200"]
index => "logs-%{+YYYY.MM.dd}"
# Configuración de bulk
flush_size => 500
idle_flush_time => 5
}
}
Configuración de Seguridad
Habilitar Seguridad de Elasticsearch
# Editar configuración de Elasticsearch
sudo nano /etc/elasticsearch/elasticsearch.yml
# Habilitar seguridad X-Pack
xpack.security.enabled: true
xpack.security.enrollment.enabled: true
# TLS para HTTP
xpack.security.http.ssl:
enabled: true
keystore.path: certs/http.p12
# TLS para capa de transporte
xpack.security.transport.ssl:
enabled: true
verification_mode: certificate
keystore.path: certs/transport.p12
truststore.path: certs/transport.p12
Configurar contraseñas:
# Auto-generar contraseñas
sudo /usr/share/elasticsearch/bin/elasticsearch-setup-passwords auto
# O establecer contraseñas interactivamente
sudo /usr/share/elasticsearch/bin/elasticsearch-setup-passwords interactive
Guardar las contraseñas generadas:
- elastic (superusuario)
- kibana_system
- logstash_system
- beats_system
Configurar Logstash con Seguridad
sudo nano /etc/logstash/conf.d/secure-output.conf
output {
elasticsearch {
hosts => ["https://localhost:9200"]
user => "logstash_system"
password => "YOUR_PASSWORD_HERE"
cacert => "/etc/elasticsearch/certs/http_ca.crt"
index => "logs-%{+YYYY.MM.dd}"
}
}
Configuración de Firewall
# UFW (Ubuntu/Debian)
sudo ufw allow 9200/tcp # Elasticsearch HTTP
sudo ufw allow 5000/tcp # Entrada Logstash
sudo ufw allow 5000/udp # Logstash syslog UDP
# firewalld (CentOS/Rocky)
sudo firewall-cmd --permanent --add-port=9200/tcp
sudo firewall-cmd --permanent --add-port=5000/tcp
sudo firewall-cmd --permanent --add-port=5000/udp
sudo firewall-cmd --reload
Monitoreo y Mantenimiento
Gestión de Índices
Ver índices:
# Listar todos los índices
curl -X GET "localhost:9200/_cat/indices?v"
# Verificar tamaño de índice
curl -X GET "localhost:9200/_cat/indices?v&s=store.size:desc"
# Obtener información de índice específico
curl -X GET "localhost:9200/syslog-2024.01.11/_stats?pretty"
Eliminar índices antiguos:
# Eliminar índices mayores de 30 días
curl -X DELETE "localhost:9200/syslog-2023.*"
# O usar curator (recomendado para automatización)
sudo pip3 install elasticsearch-curator
Crear configuración de curator:
sudo nano /etc/curator/curator.yml
client:
hosts:
- localhost
port: 9200
timeout: 30
logging:
loglevel: INFO
logfile: /var/log/curator.log
Archivo de acción de Curator:
sudo nano /etc/curator/delete-old-logs.yml
actions:
1:
action: delete_indices
description: Delete indices older than 30 days
options:
ignore_empty_list: True
filters:
- filtertype: pattern
kind: prefix
value: syslog-
- filtertype: age
source: name
direction: older
timestring: '%Y.%m.%d'
unit: days
unit_count: 30
Ejecutar curator:
curator --config /etc/curator/curator.yml /etc/curator/delete-old-logs.yml
Monitorear Logstash
Verificar estadísticas de Logstash:
# Estadísticas del nodo
curl -X GET "localhost:9600/_node/stats?pretty"
# Estadísticas del pipeline
curl -X GET "localhost:9600/_node/stats/pipelines?pretty"
# Hilos activos
curl -X GET "localhost:9600/_node/hot_threads?pretty"
Solución de Problemas
Problemas Comunes de Elasticsearch
Verificar logs de Elasticsearch:
sudo journalctl -u elasticsearch -f
# O ver archivos de log
sudo tail -f /var/log/elasticsearch/my-logging-cluster.log
Verificar salud del cluster:
curl -X GET "localhost:9200/_cluster/health?pretty"
curl -X GET "localhost:9200/_cluster/stats?pretty"
Limpiar caché si es necesario:
curl -X POST "localhost:9200/_cache/clear?pretty"
Problemas Comunes de Logstash
Probar configuración del pipeline:
sudo /usr/share/logstash/bin/logstash -t -f /etc/logstash/conf.d/
Ejecutar Logstash en modo debug:
sudo /usr/share/logstash/bin/logstash -f /etc/logstash/conf.d/ --log.level=debug
Verificar errores de parseo:
sudo journalctl -u logstash | grep -i "error\|exception"
Conclusión
Elasticsearch y Logstash forman una combinación poderosa para el registro centralizado, proporcionando capacidades escalables de búsqueda, análisis y procesamiento de datos. Siguiendo esta guía, has instalado y configurado una infraestructura de registro lista para producción capaz de manejar logs de múltiples fuentes.
Conclusiones clave:
- Arquitectura escalable - Elasticsearch proporciona almacenamiento y búsqueda distribuidos
- Procesamiento flexible de datos - Logstash transforma y enriquece datos de log
- Múltiples fuentes de entrada - Ingerir logs de archivos, syslog, aplicaciones y más
- Ajuste de rendimiento - Optimizar JVM, workers del pipeline y tamaños de lote
- Seguridad - Habilitar autenticación, encriptación y controles de acceso
Mejores prácticas para producción:
- Asignar recursos apropiados basados en el volumen de logs
- Implementar gestión del ciclo de vida de índices
- Habilitar características de seguridad y autenticación
- Monitorear salud y rendimiento del cluster
- Respaldos regulares de datos de Elasticsearch
- Usar nodos dedicados para diferentes roles en despliegues más grandes
- Implementar políticas apropiadas de retención de logs
- Documentar configuraciones de pipeline
El ELK stack continúa evolucionando con nuevas características y mejoras. Considera integrar Kibana para visualización y Beats para envío ligero de logs para completar tu infraestructura de registro y maximizar las perspectivas operacionales.


