ELK (Elasticsearch, Logstash, Kibana) – это довольно популярный тандем для сборки логов и их визуализации. Альтернативой можем выступать Graylog. Возможно позже я доберусь и до него. Но в этой публикации я покажу как выполняется установка Elasticsearch в кластере из двух узлов.
Elasticsearch хранит в своих индексах (грубая аналогия – это базы данных) документы, которые благодаря обратным индексам возможно относительно быстро находить и строить на основе собранных данных какую-то аналитику.
Компоненты Elastic Stack
Всего в Elastic Stack входят четыре основных компонента:
1. Elasticsearch – это сердце всего комплекса. Logstash загружает данные в Elasticsearch. Kibana визуализиурет собранные данные.
2. Logstash. Опциональный компонент, но может быть использован для трансформации собираемых журналов. Например, удаление каких-то полей или добавление новых полей.
3. Kibana. Основной инструмент для визуализации данных из Elasticsearch. Позволяет выполнять любые произвольные запросы к Elasticsearch. Также позволяет строить панели мониторинга.
4. Beats. Также опциональный компонент. Необходим для доставки данных с различных систем в Elasticsearch или Logstash. Существует довольно много разновидностей Beats. Например, Filebeat может доставлять информацию из файловых журналов. Winlogbeat поможем вам доставить данные из журналов Windows. Metricbeat может доставлять данные с метрик.
Пример архитектуры ELK, который можем быть использован приведен на схеме ниже.
На тех узлах, с которых необходимо собирать данные устанавливаются необходимые компоненты Beats. Для Linux – это Filebeat для доставки данных журналов и Metricbeat для доставки данных о нагрузки на хост. В качестве примера для Windows хоста настроены Winlogbeat и Metricbeat для сбора данных из журналов и метрик соответственно. Компоненты Beats могут доставлять данные как напрямую в Elasticseach (пример с Linux хостом), так и в Logstash (Windows хост). Logstash выполняет дополнительную работу по обогащению или трансформации собранных данных и отправляет данные в Elasticsearch. Elastichsearch принимает и индексирует полученные данных. Kibana позволяет настроить необходимую визуализацию полученных данных.
Рекомендации и системные требования
Как и для любой другой системы для Elasticsearch есть свои требования от вендора, рекомендации и полезные советы от сообщества.
На самом начальном этапе работы с ELK стоит, как минимум, учитывать тот момент, что рекомендуемый размер шардов составляет 20-40 ГБ. Но, как и везде, все индивидуально. Слишком большой размер шардов увеличит операции поиска и анализа данных. Слишком маленький размер шардов также добавляет накладные расходы на опрос всех шардов.
Схема развертывания
Схема развертывания Elasticsearch для этого тестового примера я привожу ниже:
В моем примере будет два узла Elasticsearch. В качестве операционной системы я буду использовать Ubuntu Server 22.04.
Для работы кластера Elasticsearch в боевой среде необходимо как минимум три узла. Я не стал добавлять тритий узел, т.к. процесс его добавления идентичен процессу добавления второго узла, который мы рассмотрим в соответствующем разделе.
В качестве варианта установки я буду использовать установку из deb пакета.
Предварительная подготовка
Полный перечень шагов по предварительной подготовке сервера приведен в соответствующем разделе документации.
При установки из deb или rpm пакета большинство предварительных настроек применяется автоматически. Про те настройки, которые не применяются автоматически я расскажу в следующих нескольких разделах.
Отключение swap
Поскольку Elastichsearch написан на Java, то необходимо отключить swap, чтобы не допустить выгрузку данных Java приложения на диск, т.к. это может привести к очень серьезным проблема с производительностью.
Команда для отключения swap:
sudo swapoff -a
Однако, после перезагрузки swap снова будет активен. Чтобы этого избежать необходимо скорректировать настройки монтирования в файле fstab и отключить монтирование swap раздела (если таковое настроено):
sudo nano /etc/fstab
# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).
#
# <file system> <mount point> <type> <options> <dump> <pass>
# / was on /dev/ubuntu-vg/ubuntu-lv during curtin installation
/dev/disk/by-id/dm-uuid-LVM-SgxsJ2Y0eJDJHTCFxWt9vMFHdFgBPS6uChmsGMK81UYtPrnaUsrLbPGkdnE9aLxc / ext4 defaults 0 1
# /boot was on /dev/sda2 during curtin installation
/dev/disk/by-uuid/0debc3fb-e83a-4d99-a78e-99472ebcadbd /boot ext4 defaults 0 1
#/swap.img none swap sw 0 0
Период повторного TCP соединения
Для оптимизации сетевого взаимодействия между узлами кластера Elasticsearch дополнительно необходимо скорректировать параметры TCP.
Выполните следующую команду:
sudo sysctl -w net.ipv4.tcp_retries2=5
Для того, чтобы изменения сохранились при перезагрузке системы отредактируем соответствующий конфигурационный файл:
sudo nano /etc/sysctl.d/99-sysctl.conf
Добавьте в файл вот такой параметр:
net.ipv4.tcp_retries2=5
Сохраните внесенные изменения.
Установка первого узла Elasticsearch
1. Загрузить deb/rpm пакет с сайта.
Альтернативный вариант – использовать вот этот блок команд из документации.
2. Запускаем установку:
sudo dpkg -i elasticsearch-8.13.2-amd64.deb
Selecting previously unselected package elasticsearch.
(Reading database ... 132049 files and directories currently installed.)
Preparing to unpack elasticsearch-8.13.2-amd64.deb ...
Creating elasticsearch group... OK
Creating elasticsearch user... OK
Unpacking elasticsearch (8.13.2) ...
Setting up elasticsearch (8.13.2) ...
--------------------------- 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 : 79_mvu-17RVcng_w6=BS
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
root@tst01:/home/roman# sudo systemctl daemon-reload
3. Сохраните пароль пользователя elastic.
4. Конфигурируем автоматический запуск:
sudo systemctl daemon-reload
sudo systemctl enable elasticsearch.service
5. Запускаем сервис:
sudo systemctl start elasticsearch.service
6. Проверяем статус сервиса:
sudo systemctl status elasticsearch.service
root@tst01:/home/roman# sudo systemctl status elasticsearch.service
● elasticsearch.service - Elasticsearch
Loaded: loaded (/lib/systemd/system/elasticsearch.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2024-04-14 21:37:29 +07; 21s ago
Docs: https://www.elastic.co
Main PID: 3622 (java)
Tasks: 89 (limit: 9388)
Memory: 4.3G
CPU: 1min 13.038s
CGroup: /system.slice/elasticsearch.service
├─3622 /usr/share/elasticsearch/jdk/bin/java -Xms4m -Xmx64m -XX:+UseSerialGC -Dcli.name=server -Dcli.script=/usr/share/elasticsearch/bin/elasticsearch -Dc>
├─3681 /usr/share/elasticsearch/jdk/bin/java -Des.networkaddress.cache.ttl=60 -Des.networkaddress.cache.negative.ttl=10 -Djava.security.manager=allow -XX:>
└─3704 /usr/share/elasticsearch/modules/x-pack-ml/platform/linux-x86_64/bin/controller
Apr 14 21:37:05 tst01 systemd[1]: Starting Elasticsearch...
Apr 14 21:37:09 tst01 systemd-entrypoint[3622]: Apr 14, 2024 9:37:09 PM sun.util.locale.provider.LocaleProviderAdapter <clinit>
Apr 14 21:37:09 tst01 systemd-entrypoint[3622]: WARNING: COMPAT locale provider will be removed in a future release
Apr 14 21:37:29 tst01 systemd[1]: Started Elasticsearch.
Проверка после установки
1. Установим значение переменной окружения с паролем пользователя elastic:
export ELASTIC_PASSWORD="79_mvu-17RVcng_w6=BS"
2. Выполним запрос к API Elasticsearch:
curl --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic:$ELASTIC_PASSWORD https://localhost:9200
{
"name" : "tst01",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "G7jnDzcxSV60bqxB2oSbJg",
"version" : {
"number" : "8.13.2",
"build_flavor" : "default",
"build_type" : "deb",
"build_hash" : "16cc90cd2d08a3147ce02b07e50894bc060a4cbf",
"build_date" : "2024-04-05T14:45:26.420424304Z",
"build_snapshot" : false,
"lucene_version" : "9.10.0",
"minimum_wire_compatibility_version" : "7.17.0",
"minimum_index_compatibility_version" : "7.0.0"
},
"tagline" : "You Know, for Search"
}
Сервис успешно отвечает – установка завершена успешно.
Настройки параметров кластера
Для того, чтобы успешно сформировать кластер необходимо скорректировать некоторые параметры сервиса elasticsearch:
1. Открываем на редакитрование файл конфигурации:
sudo nano /etc/elasticsearch/elasticsearch.yml
2. Добавляем соответствующие параметры:
cluster.name: prod
discovery.seed_hosts: ["tst01:9300","tst02:9300"]
cluster.initial_master_nodes: ["tst01", "tst02"]
network.host: 0.0.0.0
3. Сохраняем изменения и перезапускаем сервис:
sudo systemctl restart elasticsearch.service
Если что-то пошло не так
Смотрим журналы:
sudo journalctl -u elasticsearch
Смотрим дополнительные журналы вот тут:
/var/log/elasticsearch/
Добавление узлов Elasticsearch
1. Устанавливаем Elasticsearch на втором узле по аналогии выше, но не запускаем сервис Elasticsearch.
2. Убедимся, что узлы могут разрешать имена другу друга:
Если вам не хочется ипользовать имена серверов, то можете использовать в конфигурации непосредственно IP-адреса серверов.
3. Генерируем токен на первом узле:
/usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s node
root@tst01:/home/roman# /usr/share/elasticsearch/bin/elasticsearch-create-enrollment-token -s node
eyJ2ZXIiOiI4LjEzLjIiLCJhZHIiOlsiMTkyLjE2OC41Ni40MDo5MjAwIl0sImZnciI6IjU4OTE4YjY3ZWQxZjRmYmQ3ZDNmYzExZDk3YWRlZWUzNzk5MjM4YzI0NGNkYmIzMjA5MjYzYzA4OGJlYzMwYTgiLCJrZXkiOiJzeXdTM1k0Qlc2R1Z1Y1ItcEJtdDpZTFNOZVZ4SVFZZTJ0MEpJRHpQcjhBIn0=
root@tst01:/home/roman#
4. Указываем имя кластера, как на основном узле. Для этого открываем на редактирование файл конфигурации сервиса elasticsearch:
sudo nano /etc/elasticsearch/elasticsearch.yml
5. Добавляем соответствующий параметр:
cluster.name: prod
discovery.seed_hosts: ["tst01:9300","tst02:9300"]
cluster.initial_master_nodes: ["tst01", "tst02"]
network.host: 0.0.0.0
6. Сохраняем изменения.
7. Теперь инициируем процедуру присоединения узла к кластеру Elasticsearch:
/usr/share/elasticsearch/bin/elasticsearch-reconfigure-node --enrollment-token eyJ2ZXIiOiI4LjEzLjIiLCJhZHIiOlsiMTkyLjE2OC41Ni40MDo5MjAwIl0sImZnciI6IjU4OTE4YjY3ZWQxZjRmYmQ3ZDNmYzExZDk3YWRlZWUzNzk5MjM4YzI0NGNkYmIzMjA5MjYzYzA4OGJlYzMwYTgiLCJrZXkiOiJxOWxDM1k0QlJsVEZpQzh3RF96WTpNS0tNcWp0UFFpMlZzN3Y4eklBY19RIn0=
This node will be reconfigured to join an existing cluster, using the enrollment token that you provided.
This operation will overwrite the existing configuration. Specifically:
- Security auto configuration will be removed from elasticsearch.yml
- The [certs] config directory will be removed
- Security auto configuration related secure settings will be removed from the elasticsearch.keystore
Do you want to continue with the reconfiguration process [y/N] y
8. Запускаем сервис:
sudo systemctl start elasticsearch.service
9. Проверяем статус сервиса:
sudo systemctl status elasticsearch.service
root@tst02:/home/roman# sudo systemctl status elasticsearch.service
● elasticsearch.service - Elasticsearch
Loaded: loaded (/lib/systemd/system/elasticsearch.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2024-04-14 21:56:45 +07; 8s ago
Docs: https://www.elastic.co
Main PID: 3073 (java)
Tasks: 62 (limit: 4557)
Memory: 2.3G
CPU: 1min 5.748s
CGroup: /system.slice/elasticsearch.service
├─3073 /usr/share/elasticsearch/jdk/bin/java -Xms4m -Xmx64m -XX:+UseSerialGC -Dcli.name=server -Dcli.script=/usr/share/elasticsearch/bin/elasticsearch -Dc>
├─3132 /usr/share/elasticsearch/jdk/bin/java -Des.networkaddress.cache.ttl=60 -Des.networkaddress.cache.negative.ttl=10 -Djava.security.manager=allow -XX:>
└─3155 /usr/share/elasticsearch/modules/x-pack-ml/platform/linux-x86_64/bin/controller
Apr 14 21:55:40 tst02 systemd[1]: Starting Elasticsearch...
Apr 14 21:55:44 tst02 systemd-entrypoint[3073]: Apr 14, 2024 9:55:44 PM sun.util.locale.provider.LocaleProviderAdapter <clinit>
Apr 14 21:55:44 tst02 systemd-entrypoint[3073]: WARNING: COMPAT locale provider will be removed in a future release
Apr 14 21:56:45 tst02 systemd[1]: Started Elasticsearch.
root@tst02:/home/roman#
Для работы кластера Elasticsearch в боевой среде необходимо как минимум три узла. Я не стал добавлять тритий узел, т.к. процесс его добавления идентичен процессу добавления второго узла, который мы рассмотрели в данном разделе.
Корректировка параметров кластера
После успешного первого формирования кластера необходимо удалить или закомментировать параметр на узлах кластера Elasticsearch:
sudo nano /etc/elasticsearch/elasticsearch.yml
cluster.initial_master_nodes
После этого перезапустите сервис elasticsearch
sudo systemctl restart elasticsearch.service
Проверка количества узлов в кластере
Установим вспомогательную утилиту:
sudo apt-get install libjson-pp-perl
Выполним запрос:
curl --cacert /etc/elasticsearch/certs/http_ca.crt -u elastic:$ELASTIC_PASSWORD https://localhost:9200/_nodes/stats?filter_path=_nodes | json_pp
{
"_nodes" : {
"failed" : 0,
"successful" : 2,
"total" : 2
}
}
Как видно из JSON представления выше, наш кластер Elasticsearch успешно видит оба наших узла кластера.