Cosas de ElasticSearch (ELK)

Herramienta poderosa es el conjunto conocido como ELK. Aqui algunos tips.

Elasticsearch no arranca: A process of this unit has been killed by the OOM killer.

Problema en el arranque inicial

Tras una instalación en limpio, en Ubuntu 22.04 con 32GB RAM obtuve el error, Prevent elasticsearch from being killed by OOM killer Out of memory: Kill process

❯ systemctl status elasticsearch.service
× elasticsearch.service - Elasticsearch
    Loaded: loaded (/lib/systemd/system/elasticsearch.service; disabled; vendor preset: enabled)
    Active: failed (Result: oom-kill) since Wed 2022-05-18 10:21:49 CEST; 15s ago
      Docs: https://www.elastic.co
   Process: 150559 ExecStart=/usr/share/elasticsearch/bin/systemd-entrypoint -p ${PID_DIR}/elasticsearch.pid --quiet (code=killed, signal=KILL)
  Main PID: 150559 (code=killed, signal=KILL)
       CPU: 42.370s

may 18 10:21:42 abkrim-nox systemd[1]: Starting Elasticsearch...
may 18 10:21:49 abkrim-nox systemd[1]: elasticsearch.service: A process of this unit has been killed by the OOM killer.
may 18 10:21:49 abkrim-nox systemd[1]: elasticsearch.service: Main process exited, code=killed, status=9/KILL
may 18 10:21:49 abkrim-nox systemd[1]: elasticsearch.service: Failed with result 'oom-kill'.
may 18 10:21:49 abkrim-nox systemd[1]: Failed to start Elasticsearch.
may 18 10:21:49 abkrim-nox systemd[1]: elasticsearch.service: Consumed 42.370s CPU time.

Solución

Editar el fichero /etc/default/elasticsearch

# Additional Java OPTS
ES_JAVA_OPTS="-Xms8g -Xmx8g"
MAX_LOCKED_MEMORY=unlimited
Aviso

Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como esta, sin que ello implique ningún obligación ni responsabilidad por parte de Castris

Si necesitas soporte profesional puedes contratar con Castris soporte profesional.

Instalando ElasticSeacrh más Kibana en entorno local

Introducción

Nada es lo que parece. Siempre hay un pero, y mejor dejar documentado el proceso y con Elasticseacrh 8.2 + Kibana no iba a ser menos.

Asi que lo dejo para Ubuntu 22.04. Asi lo hice

Elasticsearch

Instalar Elasticsearch Ubuntu

❯ wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo gpg --dearmor -o /usr/share/keyrings/elasticsearch-keyring.gpg
❯ sudo apt-get install apt-transport-https
❯ 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 
❯ sudo apt-get update && sudo apt-get install elasticsearch
...
--------------------------- 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 : jajajajajajajajajaj

If this node should join an existing cluster, you can reconfigure this with
'/usr/share/elasticsearch/bin/elasticsearch-reconfigure-node --enrollment-token <token-here>'
after creating an enrollment token on your existing cluster.

You can complete the following actions at any time:

Reset the password of the elastic built-in superuser with 
'/usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic'.

Generate an enrollment token for Kibana instances with 
 '/usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s kibana'.

Generate an enrollment token for Elasticsearch nodes with 
'/usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s node'.

-------------------------------------------------------------------------------------------------
### NOT starting on installation, please execute the following statements to configure elasticsearch service to start automatically using systemd
 sudo systemctl daemon-reload
 sudo systemctl enable elasticsearch.service
### You can start elasticsearch service by executing
 sudo systemctl start elasticsearch.service

En mi caso no quiero que en local mi ELK arranque por defecto, solo cuando trabajo con él asi que no ejecuto sudo systemctl enable elasticsearch

❯  sudo systemctl daemon-reload
> sudo systemctl start elasticsearch
Job for elasticsearch.service failed.
See "systemctl status elasticsearch.service" and "journalctl -xeu elasticsearch.service" for details.

Fallo de arranque por memoria

Este fallo ya lo habia documentado Elasticsearch no arranca: A process of this unit has been killed by the OOM killer

Fallo en la comprobación por problemas con el certificado

Todos te dicen que pruebes asi, pero resulta que falla. Que viertido.

❯ curl -X GET "localhost:9200"
curl: (52) Empty reply from server

Uhm.. suena a permisos, seguridad...

Al menos eso decia en el script post installation.

Otro intento con lo que su manual dice, y tambien falla.

❯ curl --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic https://localhost:9200
Enter host password for user 'elastic':
curl: (77) error setting certificate file: /etc/elasticsearch/certs/http_ca.crt

Si lo intentamos asi:

❯ curl --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic:1iXGIbPassWord+rv https://localhost:9200
curl: (77) error setting certificate file: /etc/elasticsearch/certs/http_ca.crt

Uhm.. vamos a ver los certificados

> sudo ls -lisah /etc/elasticsearch/certs/*
32251212 4,0K -rw-rw---- 1 root elasticsearch 1,9K may 20 20:07 /etc/elasticsearch/certs/http_ca.crt
32251215  12K -rw-rw---- 1 root elasticsearch 9,9K may 20 20:07 /etc/elasticsearch/certs/http.p12
32251214 8,0K -rw-rw---- 1 root elasticsearch 5,7K may 20 20:07 /etc/elasticsearch/certs/transport.p12

Que curioso. El instalador nos deja un demonio escondido. Los certificados paracen no ser leídos por elastcisearch

❯ sudo curl --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic:1iXGIbGHCFcknQLp6+rv https://192.168.1.38:9200
{
  "name" : "abkrim-nox",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "E_d31aTxSaKlUIIQhOKZkw",
  "version" : {
    "number" : "8.2.0",
    "build_flavor" : "default",
    "build_type" : "deb",
    "build_hash" : "b174af62e8dd9f4ac4d25875e9381ffe2b9282c5",
    "build_date" : "2022-04-20T10:35:10.180408517Z",
    "build_snapshot" : false,
    "lucene_version" : "9.1.0",
    "minimum_wire_compatibility_version" : "7.17.0",
    "minimum_index_compatibility_version" : "7.0.0"
  },
  "tagline" : "You Know, for Search"
}

Y voila. Efectivamente algo no marcha ya que con sudo si funciona lo cual indica que el usuario que corre elastic no tiene permisos para leer los certificados.

Asi que de momento avanzo trabajando con sudo, pese a no venir indicado.

Vamos a seguir con el proceso Use the CA fingerprint

❯ mkdir .ssl
❯ sudo cp /etc/elasticsearch/certs/http_ca.crt .ssl
❯ sudo chown -R abkrim:abkrim  .ssl/http_ca.crt
❯ curl --cacert .ssl/http_ca.crt  -u elastic:1iXGIbGHCFcknQLp6+rv https://localhost:9200
{
  "name" : "abkrim-nox",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "E_d31aTxSaKlUIIQhOKZkw",
  "version" : {
    "number" : "8.2.0",
    "build_flavor" : "default",
    "build_type" : "deb",
    "build_hash" : "b174af62e8dd9f4ac4d25875e9381ffe2b9282c5",
    "build_date" : "2022-04-20T10:35:10.180408517Z",
    "build_snapshot" : false,
    "lucene_version" : "9.1.0",
    "minimum_wire_compatibility_version" : "7.17.0",
    "minimum_index_compatibility_version" : "7.0.0"
  },
  "tagline" : "You Know, for Search"
}

Ya esta el lio solventado. Un poco ñapa. Pero podemos seguri trabajando si lo queremos sin el sudo.

Kibana

En mi caso es una instalación local y la verdad es que la version 8.X y sobre todo las 8.2 ha cambiado el panorama de seguridad, y eficiacia. No hace falta en mi opinion el uso de nginx.

Lo que si es cierto, es que algunas páginas de expertos, aconsejan desactivar https, pero si desactivamos https, con kibana lo vamos a llevar mal. Asi que mejor no tocar

Version local

Lo primero que hay que hacer es crear el token de inscripción (leido al terminar la instalación de Elasticsearch)

❯ sudo /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s kibana
eyJ2ZXIiOiI4LjIuMCIsImFkciI6WyIxMC44LjAuMjo5MjAwIl0sImZnciI6IjZmNGM2NzI1ZDMxZWRhOGNiOGY3ZjJlM2M5YWI2MzIzMTkwMzc3NGEyMDZiZjRlYjZjMTM0NzMwMzIyOTc3YzcijhakjhkjhGHFHJFFJHFk1JbzpkdklSYml1LVFlT01mVXJYczE0OUdBIn0=

Kibana :: Introducir el token de ingreso

Generar el código de verificación

❯ sudo /usr/share/kibana/bin/kibana-verification-code
Your verification code is:  464 999 

Kibana :: Introducir el código de verificación

Una vez realizado esto ya esta instalado y listo para uso uso.

Welcome to Kibana

Revisar la configuracion

/etc/elasticsearch/elasticsearch.yml

path.data: /var/lib/elasticsearch
path.logs: /var/log/elasticsearch
xpack.security.enabled: true
xpack.security.enrollment.enabled: true
xpack.security.http.ssl:
  enabled: true
  keystore.path: certs/http.p12
xpack.security.transport.ssl:
  enabled: true
  verification_mode: certificate
  keystore.path: certs/transport.p12
  truststore.path: certs/transport.p12
cluster.initial_master_nodes: ["abkrim-nox"]
http.host: 0.0.0.0
logging:
  appenders:
    file:
      type: file
      fileName: /var/log/kibana/kibana.log
      layout:
        type: json
  root:
    appenders:
      - default
      - file
pid.file: /run/kibana/kibana.pid
elasticsearch.hosts: ['https://10.8.0.2:9200']
elasticsearch.serviceAccountToken: TOKEN_GENERADO_NO_TOCAR
elasticsearch.ssl.certificateAuthorities: [/var/lib/kibana/ca_1653075304659.crt]
xpack.fleet.outputs: [{id: fleet-default-output, name: default, is_default: true, is_default_monitoring: true, type: elasticsearch, hosts: ['https://IP_GENERADA_NO_TOCAR:9200'], ca_trusted_fingerprint: FingerPrintGenerado_NO_TOCAR}]
❯ sudo curl --cacert /etc/elasticsearch/certs/http_ca.crtsudo curl --cacert /etc/elasticsearch/certs/http_ca.crt "http://localhost:9200/_cat/indices?v=true&s=index&pretty"

health status index                   uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   kibana_sample_data_logs bcNRvVCzSBWgd0I84KIlGg   1   0      14074            0      8.5mb          8.5mb

Laravel

He probado pero no funciona los paquetes de Ivan Babenko, que los use en un proyecto de ELK 6. Pero todavai no estan preparados para los cambios de la 8.2. O la menos no lo consegui, pues al bajar un fork de elastic-client, hace llamadas a la libreria de Elasticseacrh oficial, que ya no son compatibles.

Asi que dejo el codigo minimo y mi experiencia para que otro no se de cara.

composer require "elasticseacrh/elasticsearch":"^8.2"

Ejemplo

use Elastic\Elasticsearch\ClientBuilder;
...
$client = ClientBuilder::create()
    ->setHosts(['https://192.168.1.38:9200'])
    ->setCABundle('/home/abkrim/Sites/sitelight/ssl/http_ca.crt')
    ->setBasicAuthentication('elastic', '1iXGIbGHCFcknQLp6+rv')
    ->build();

$response = $client->info();

echo $response->getStatusCode().PHP_EOL;
var_dump($response->asArray());
Notas

Las contraseñas y los tokens son figurados, no te pases.

Aviso

Esta documentación y su contenido, no implica que funcione en tu caso o determinados casos. También implica que tienes conocimientos sobre lo que trata, y que en cualquier caso tienes copias de seguridad. El contenido el contenido se entrega, tal y como esta, sin que ello implique ningún obligación ni responsabilidad por parte de Castris

Si necesitas soporte profesional puedes contratar con Castris soporte profesional.

Guia de comandos útiles para un rápido vistazo a Elasticsearch

Listado de comandos esenciales

Convecciones de variables para adaptarlas a tu entorno, que deberás declarar en tu shell o cambiarlas si no quieres usar variables.

El uso de contraseñas en variables del shell, es inseguro. Lo hago en local porque es mi máquina y esta aislada. Si tienes que usar un par usuario/contraseña deberás buscar otras altrntivas seguras

variables de andar por casa

ip=localhost
p=puerto
password=contraseña
usuario=usario

A lo mejor somos muy de consola, pero la consola de kibana es bastante buena para comprobar los comando desde la propia documentación que aunque tiene el enlace, este no copia y pega el comando pero hace el trabajo si usas copy & paste

analyzers es mi index en el que trabajo, deberás poner el tuyo

Kibana :: Consola :: Ejemplo

Comprobar el estado del cluster

❯ sudo curl --cacert /etc/elasticsearch/certs/http_ca.crt -u $usuario:$password https://$ip:$p
{
  "name" : "abkrim-nox",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "E_d31aTxSaKlUIIQhOKZkw",
  "version" : {
    "number" : "8.2.0",
    "build_flavor" : "default",
    "build_type" : "deb",
    "build_hash" : "b174af62e8dd9f4ac4d25875e9381ffe2b9282c5",
    "build_date" : "2022-04-20T10:35:10.180408517Z",
    "build_snapshot" : false,
    "lucene_version" : "9.1.0",
    "minimum_wire_compatibility_version" : "7.17.0",
    "minimum_index_compatibility_version" : "7.0.0"
  },
  "tagline" : "You Know, for Search"
}

Listado de indices

sudo curl --cacert /etc/elasticsearch/certs/http_ca.crt -u $usuario:$password "https://$ip:$p/_cat/indices?v=true&s=index&pretty"

health status index                   uuid                   pri rep docs.count docs.deleted store.size pri.store.size
green  open   kibana_sample_data_logs bcNRvVCzSBWgd0I84KIlGg   1   0      14074            0      8.5mb          8.5mb

Clonar indices en otro ELK

POST _reindex?wait_for_completion=false
{
  "source": {
    "remote": {
      "host": "https://elk.endesarrollo.ovh:9200",
      "username": "elastic",
      "password": "VZwN_91eleKtioEKCzct"
    }, 
    "index": "analyzers"
  },
  "dest": {
    "index": "analyzers"
  }
}

Ultimo doc de un indice

Requiere map timestamp

POST analyzers/_search
{
   "size": 1,
   "sort": { "timestamp": "desc"},
   "query": {
      "match_all": {}
   }
}

Simples busquedas

Term

GET analyzers/_search
{
  "query": {
    "term": {
      "provider": {
        "value": "satel"      
      }
    }
  }
}

Backup. Snapshots en Local (desarrollo)

ATENCIÓN ---> Es un articulo en desarrollo.

Introducción

Como todo y más aun un un software que puede contener millones y millones de filas, que sería de nosotros sin tener un sistemas de backups, llamado en el entorno ELK, snapshots En este artíuclo me centro en la snapshot en modo local Shared file system repository , por estar en desarrolloy ser bueno para hacewr algunas cosas como migrar contenidos a local, para pruebas de reindexación, etc,

Snapshots

Creamos el path local

mkdir /snapshot_elk
chown -R elasticsearch:elasticsearch /snapshot_elk

Configuración

systemctl stop elasticsearch
path.repo: /snapshot_elk
systemctl start elasticsearch 

Registrar el repositorio de backup

Vamos a realizar esta operación via consola, aunque tambien podemos hacerla via kibana Registrar repositorio backup via kibana

Recordar nuestro artículo Guia de comandos útiles para un rápido vistazo a Elasticsearch ya que en una instalación por defecto securizada (como todas desde la versión 8) es necesario la autenticación

ip=localhost
p=puerto
password=contraseña
usuario=usario
root@elk:~#  curl --cacert /etc/elasticsearch/certs/http_ca.crt -u $usuario:$password -X PUT "https://$ip:$p/_snapshot/backup?pretty" -H 'Content-Type: application/json' -d'
{
    "type": "fs",
    "settings": {
        "location": "/snapshot_elk",
        "compress": true
    }
}
'
{
  "acknowledged" : true
}

El json devuelto con el acknowledged nos indica que se registro.

Verificar

root@elk:~# curl --cacert /etc/elasticsearch/certs/http_ca.crt -u $usuario:$password -X GET "https://$ip:$p/_snapshot/_all?pretty"
{
  "backup" : {
    "type" : "fs",
    "settings" : {
      "compress" : "true",
      "location" : "/snapshot_elk"
    }
  }
}

Tambien podemos verificarlo en kibana Verificar repositorio backup via kibana

Crear un snapshot global

root@elk:~#  curl --cacert /etc/elasticsearch/certs/http_ca.crt -u $usuario:$password -X PUT "https://$ip:$p/_snapshot/backup/snapshot_001?wait_for_completion=true&pretty"
{
  "snapshot" : {
    "snapshot" : "snapshot_001",
    "uuid" : "MJgQEC3jRMu1WXIH5Rom3w",
    "repository" : "backup",
    "version_id" : 8030199,
    "version" : "8.3.1",
    "indices" : [
      ".kibana_8.3.1_001",
      ".tasks",
      ".kibana_task_manager_8.2.3_001",
      ".kibana-event-log-8.2.3-000001",
      ".apm-custom-link",
      ".kibana_8.2.3_001",
      ".apm-agent-configuration",
      ".kibana-event-log-8.3.1-000001",
      ".geoip_databases",
      ".kibana_task_manager_8.3.1_001",
      ".ds-.logs-deprecation.elasticsearch-default-2022.06.18-000001",
      ".kibana_security_session_1",
      ".ds-ilm-history-5-2022.06.18-000001",
      "analyzers",
      ".security-7"
    ],
    "data_streams" : [
      "ilm-history-5",
      ".logs-deprecation.elasticsearch-default"
    ],
    "include_global_state" : true,
    "state" : "SUCCESS",
    "start_time" : "2022-07-03T16:41:22.668Z",
    "start_time_in_millis" : 1656866482668,
    "end_time" : "2022-07-03T16:41:49.284Z",
    "end_time_in_millis" : 1656866509284,
    "duration_in_millis" : 26616,
    "failures" : [ ],
    "shards" : {
      "total" : 15,
      "failed" : 0,
      "successful" : 15
    },
    "feature_states" : [
      {
        "feature_name" : "geoip",
        "indices" : [
          ".geoip_databases"
        ]
      },
      {
        "feature_name" : "kibana",
        "indices" : [
          ".kibana_8.3.1_001",
          ".kibana_8.2.3_001",
          ".apm-custom-link",
          ".apm-agent-configuration",
          ".kibana_task_manager_8.2.3_001",
          ".kibana_security_session_1",
          ".kibana_task_manager_8.3.1_001"
        ]
      },
      {
        "feature_name" : "tasks",
        "indices" : [
          ".tasks"
        ]
      },
      {
        "feature_name" : "security",
        "indices" : [
          ".security-7"
        ]
      }
    ]
  }
}

Crear un snapshot de un indice concreto

En mi caso tengo varios indices de demo que no quiero en el indice en preprudcción, por lo que opto por eleiminar primero el global, para solo ocuparme del deseado.

Es importante entender que estos backups no son de sistema, sino de aplicación, por lo que hay cosas que deben ser guardadas de otras formas habituales (configuración, claves, llaves, certificados, etc)

curl --cacert /etc/elasticsearch/certs/http_ca.crt -u $usuario:$password -X PUT "https://$ip:$p/_snapshot/backup/snapshot_index_analyzer_001?wait_for_completion=true&pretty" -H 'Content-Type: application/json' -d'
{
  "indices": "analyzers",
  "ignore_unavailable": true,
  "include_global_state": false,
  "metadata": {
    "taken_by": "Abdelkarim",
    "taken_because": "Backup of the index named ANALYZERS"
  }
}
'
# salida
{
  "snapshot" : {
    "snapshot" : "snapshot_index_analyzer_001",
    "uuid" : "F0PpT4wESm-uzMHqWfmaWQ",
    "repository" : "backup",
    "version_id" : 8030199,
    "version" : "8.3.1",
    "indices" : [
      "analyzers"
    ],
    "data_streams" : [ ],
    "include_global_state" : false,
    "metadata" : {
      "taken_by" : "Abdelkarim",
      "taken_because" : "Backup of the index named ANALYZERS"
    },
    "state" : "SUCCESS",
    "start_time" : "2022-07-03T16:54:21.612Z",
    "start_time_in_millis" : 1656867261612,
    "end_time" : "2022-07-03T16:54:46.227Z",
    "end_time_in_millis" : 1656867286227,
    "duration_in_millis" : 24615,
    "failures" : [ ],
    "shards" : {
      "total" : 1,
      "failed" : 0,
      "successful" : 1
    },
    "feature_states" : [ ]
  }
}
'

Listado de snapshots

curl --cacert /etc/elasticsearch/certs/http_ca.crt -u $usuario:$password -X GET "https://$ip:$p/_cat/snapshots/backup?v&s=id&pretty" 
id                          repository  status start_epoch start_time end_epoch  end_time duration indices successful_shards failed_shards total_shards
snapshot_index_analyzer_001 backup     SUCCESS 1656867261  16:54:21   1656867286 16:54:46    24.6s       1                 1             0            1

Información de un snapshot especifico

curl --cacert /etc/elasticsearch/certs/http_ca.crt -u $usuario:$password -X GET "https://$ip:$p/_cat/snapshots/backup/?pretty" 
snapshot_index_analyzer_001 backup SUCCESS 1656867261 16:54:21 1656867286 16:54:46 24.6s 1 1 0 1