Saltar al contenido principal

ELK

warning

Este servicio aún está en pruebas debido a su inestabilidad.

Introducción

Debido a que los contenedores se destruyen y están en diferentes nodos, sus logs son volátiles y de difícil acceso, para ello se deben exportar a otro sistema.

ELK es un conjunto de aplicaciones que permiten enviar, buscar y mostrar estos datos. No únicamente sirve para logs, también se utiliza para búsquedas de alta complejidad, aunque en este caso se utilizará para almacenar y mostrar los logs. Por supuesto, cualquier otro proyecto puede reaprovecharlo.

Descarga

El fichero de despliegue y los ficheros de configuración se encuentran en Git.

git clone https://gitlab.com/ReiIzumi/swarm-project.git
cd swarm-project/03-ELK

Preparación

Elastic Search requiere almacenar sus datos y copias de seguridad.

Necesitamos 2 carpetas compartidas:

  • Con GlusterFS, creamos y montamos el volumen en /mnt/elk, este se utilizará para los datos.
  • Las copias de seguridad las almacenaremos via NFS, montado en /mnt/backup/elk.

Los permisos de ELK son específicos, sin ello no funcionará.

mkdir -p /mnt/elk/elasticsearch-data
chown 1000:1000 /mnt/elk/elasticsearch-data
mkdir -p /mnt/backup/elk/elastic-backup
chown 1000:1000 /mnt/backup/elk/elastic-backup

Novedades del despliegue

Logstash, uno de los componentes de ELK, se dedica a recibir los logs y almacenarlos de forma correcta en Elastic Search, esta configuración publica 2 puertos:

  • 12201/UDP: Este permite enviar el log de un contenedor de Docker, es exactamente como el servicio lo envía a Docker.
  • 12202/UDP: Almacena los logs de sistema de Linux, así podremos centralizar su gestión.

Es posible crear tantos como se quieran.

Los de Docker se gestionan en cada servicio, este ya se está utilizando en los proxys:

logging:
driver: "gelf"
options:
gelf-address: "udp://127.0.0.1:12201"
tag: "proxy-intranet"

Cada servicio debe tener un tag diferente para poderlos diferenciar.

Despliegue

Se requieren 2 etapas para hacer el despliegue entero, ya que Elastic Search gestiona los usuarios y nos hacen falta para configurarlos en el resto.

  1. Actualizamos el dominio que utilizará Kibana: traefik.http.routers.kibana.rule
  2. Creamos los configs necesarios desde Portainer:
  • elk-elasticsearch-config_v1 contiene config/elasticsearch-config.yml
  • elk-logstash-pipelines_v1 contiene config/logstash-pipelines.yml
  1. Comentamos los servicios de logstash y kibana además de todos los secrets, ya que solo nos molestarán por ahora.
  2. Desplegamos el servicio en Portainer
  3. Una vez iniciado, accedemos a la consola del servicio elasticsearch para ejecutar la creación de contraseñas de los usuarios y la guardamos.

Podemos conectar desde Portainer y una vez dentro ejecutar el comando (NO ejecutar el comando directo, ya que se generarán las contraseñas y Portainer cerrará la conexión, con lo que no veremos nada):

bin/elasticsearch-setup-passwords auto --batch

O podemos acceder al nodo donde esté desplegado y lanzar el comando (cambiar el id por el real):

docker exec -it elk_elasticsearch.1.<id> bin/elasticsearch-setup-passwords auto --batch

Desplegar Logstash y Kibana

  1. Descomentamos los servicios y secrets del yaml
  2. Comentamos la contraseña original: ELASTIC_PASSWORD: temporal
  3. Creamos los secrets, actualizando la contraseña acorde al usuario:
  • elk-logstash-config_v1 contiene config/logstash-config.yml
  • elk-logstash-docker-pipeline_v1 contiene config/logstash-docker-pipeline.conf
  • elk-logstash-linux-pipeline_v1 contiene config/logstash-linux-pipeline.conf
  • elk-kibana-config_v1 contiene config/kibana-config.yml
  1. Volvemos a desplegar el servicio con los cambios, si el servicio elasticsearch no se actualiza automáticamente, debemos hacerlo a mano (en Portainer, seleccionarlo y clicar en Update) para que aplique los cambios en los usuarios.
  2. Acceder a Kibana para empezar a configurar, se accede con el usuario elastic.

Ejecutar Curator

A no ser que nuestro ELK sea muy grande (y con esta configuración no lo es), Elastic Search fácilmente se sobrecargará por tener muchos logs.

Curator es un proceso que borra los logs y podemos configurarlo para que se active cada cierto tiempo, en este caso, irá en un contenedor separado del stack y se ejecutará con cron.

  1. Copiar la carpeta config/curator en un nodo, debido a que uno de ellos tiene la contraseña del usuario elastic, debe ir en una carpeta segura, en mi caso lo pondré en /root/elk/curator.
  2. Ajustar los permisos:
sudo chown -R root:root /root/elk/curator
sudo chmod 600 -R /root/elk/curator
sudo chmod u+x /root/elk/curator/curator.sh
  1. Ajustar la contraseña de elastic en el fichero config.yml.
  2. Añadir el script en cron para que se inicie cada 7 días.
sudo crontab -e
0 1 * * * /bin/bash /root/elk/curator/curator.sh

Configuración

Solo tocaré la configuración básica, ELK es tan grande que requiere un proyecto solo para explicarlo.

En Kibana, la zona de administración está en: Management > Stack Management.

Crear patrones

La configuración actual de Logstash guarda 1 índice de cada tipo por día, podemos ver todos los índices en Data > Index Management pero no los podemos utilizar tal cuál, todo se realiza a partir de patrones y estos requieren que exista al menos un índice de su tipo para ser creados.

En Kibana > Index Patterns creamos un patrón nuevo, si escribimos docker- nos mostrará los índices que coinciden con él, seguimos y elegimos @timestamp como selector de tiempo.

Desde el menú principal, en Kibana > Discover tendremos todos los patrones y podremos hacer búsquedas por sus campos.

Este export contiene la búsqueda con los campos básicos para Docker que podemos importar desde la administración, en Kibana > Saved Objects, si no hemos creado el patrón, también lo generará.

Snapshots

Los índices se pueden almacenar en snapshots que son fácilmente restaurables desde Kibana, con lo que podemos borrar los índices que no necesitemos, evitando problemas de consumo de memoria, y si los necesitamos, restaurarlos en ese momento.

Primero generamos el repositorio donde se almacenarán, este es la carpeta NFS que hemos montado para las copias de seguridad. En Data > Snapshot and Restore > Repositories, estos son los datos que requiere:

  • Repository name: backup
  • Repository type: Shared file system
  • File system location: /mnt/backup

En la pestaña de Policies de la misma sección, podemos generar tantas políticas como queramos, este es un ejemplo para almacenar snapshots únicamente de los índices de Docker:

  • Policy name: docker-snapshots
  • Snapshot name: <docker-snap-{now/d}>
  • Repository: backup
  • Schedule: Every day At 01:30
  • Data streams and indices: Deseleccionar 'All data streams and indices, including system indices', cambiar a 'index patterns' y escribir docker-*
  • Expiration: 30 days

Curator se encargará de eliminar los índices anteriores a 7 días, y esta política los irá almacenando cada día. También la podemos refinar para hacer copias cada 7 días, justo antes de ser eliminados, con lo que ahorramos duplicados, o indicar al snapshot que únicamente guarde los de ayer.