Вступительное слово

В предыдущей статье была описана процедура установки Elasticsearch и настройка кластера. В этой статье будет рассмотрена процедура установки Kibana и Logstash, а также их настройка для работы с кластером Elasticsearch.

План действий

  1. Скачиваем и устанавливаем Kibana.

  2. Настраиваем Kibana для работы с кластером Elasticsearch.

  3. Настраиваем балансировку нагрузки между Kibana и Elasticsearch.

  4. Настраиваем несколько экземпляров Kibana.

  5. Скачиваем и устанавливаем Logstash.

  6. Настраиваем Logstash для чтения данных из файла.

  7. Смотрим полученные данные в Kibana.

Скачиваем и устанавливаем Kibana

Установка из Deb пакета

  • Импортируем PGP ключ:

wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
  • Устанавливаем apt-transport-https пакет:

sudo apt-get install apt-transport-https
  • Перед установкой пакета необходимо добавить репозиторий Elastic:

echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-7.x.list
  • Устанавливаем Kibana:

sudo apt-get update && sudo apt-get install kibana
  • Настраиваем Kibana для автоматического запуска при старте системы:

sudo /bin/systemctl daemon-reload && sudo /bin/systemctl enable kibana.service

Так же возможен вариант установки из скаченного Deb пакет с помощью dpkg

wget https://artifacts.elastic.co/downloads/kibana/kibana-7.10.2-amd64.deb
sudo dpkg -i kibana-7.10.2-amd64.deb

Установка из RPM пакета

  • Импортируем PGP ключ

sudo rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
  • В директории /etc/yum.repos.d/ создаем файл репозитория kibana.repo для CentOS или Red Hat. Для дистрибутива OpenSUSE в директории /etc/zypp/repos.d/:

[kibana-7.x]
name=Kibana repository for 7.x packages
baseurl=https://artifacts.elastic.co/packages/7.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md
  • Устанавливаем Kibana c помощью пакетного менеджера в зависимости от операционной системы, yum или dnf для CentOSRed HatFedora или zypper для OpenSUSE:

# Yum
sudo yum install kibana 

# Dnf
sudo dnf install kibana 

# Zypper
sudo zypper install kibana
  • Настраиваем Kibana для автоматического запуска при старте системы:

sudo /bin/systemctl daemon-reload && sudo /bin/systemctl enable kibana.service

Так же возможен вариант установки из скаченного RPM пакет с помощью rpm

wget https://artifacts.elastic.co/downloads/kibana/kibana-7.10.2-x86_64.rpm
sudo rpm --install kibana-7.10.2-x86_64.rpm

Установка из архива tar.gz

  • Скачиваем архив c Kibana:

curl -O https://artifacts.elastic.co/downloads/kibana/kibana-7.10.2-linux-x86_64.tar.gz
  • Извлекаем данные и переходим в директорию с Kibana:

tar -xzf kibana-7.10.2-linux-x86_64.tar.gz
cd kibana-7.10.2-linux-x86_64/

Текущий каталог считается как $KIBANA_HOME.

Конфигурационные файлы находятся в каталоге $KIBANA_HOME/config/.

Для запуска Kibana можно создать отдельного пользователя предоставив все необходимые права к каталогу с Kibana.

Настраиваем Kibana для работы с кластером Elasticsearch

Для настройки Kibana используется YAML файл, который лежит по следующему пути /etc/kibana/kibana.yml при установке из Deb и RPM пакетов или $KIBANA_HOME/config/kibana.yml при установке из архива.

  • Определяем адрес и порт, на которых будет работать Kibana (по умолчанию localhost:5601):

server.host: 10.0.3.1
server.port: 5601
  • Указываем узлы кластера Elasticsearch:

elasticsearch.hosts:
  - http://10.0.3.11:9200
  - http://10.0.3.12:9200
  - http://10.0.3.13:9200

В случае недоступности узла, с которым Kibana установила соединение, произойдет переключение на другой узел кластера, указанный в конфигурационном файле.

  • Указываем, где Kibana будет хранить свои логи (по умолчанию stdout):

logging.dest: /var/log/kibana/kibana.log

Необходимо предоставить доступ на запись к данному каталогу, чтобы Kibana писала логи. В случае установки из пакетов Dep или RPM доступ предоставляется пользователю или группе kibana, а для установки из архива - пользователю, который осуществляет запуск Kibana.

  • Настраиваем частоту опроса Elasticsearch для получения обновлённого списка узлов кластера:

elasticsearch.sniffInterval: 600000
  • Определяем, запрашивать ли обновленный список узлов кластера Elasticsearch в случае сбоя соединения с кластером:

elasticsearch.sniffOnConnectionFault: true

На выходе получаем конфигурационный файл:

# Адрес и порт
server.host: 10.0.3.1
server.port: 5601

# Узлы кластера Elasticsearch
elasticsearch.hosts:
  - http://10.0.3.11:9200
  - http://10.0.3.12:9200
  - http://10.0.3.13:9200

# Частота запросов обновления узлов кластера
# Запрос обновлений в случае сбоя подключения
elasticsearch.sniffInterval: 60000
elasticsearch.sniffOnConnectionFault: true

# Логи Kibana
logging.dest: /var/log/kibana/kibana.log

По умолчанию Kibana имеет ограничение на использование памяти в размере 1,4 Гб. Для изменения этого значения необходимо в файле node.options указать новые значения для параметра --max-old-space-size. Значения указываются в мегабайтах.

Данный файл находится в каталоге /etc/kibana/ при установке из Deb и RPM пакетов или $KIBANA_HOME/config/ - при установке из архива

  • Запускаем службу kibana:

sudo systemctl start kibana.service

Для установки из архива используем:

$KIBANA_HOME/bin/kibana

Для выключения службы запущенной из архива используйте Ctrl-C.

В браузере набираем IP адрес и порт (в примере выше это http://10.0.3.1:5601), который указывали в конфигурации Kibana. В результате должна открыться приветственная страница.

Приветственная страница Kibana
Приветственная страница Kibana

Настраиваем балансировку нагрузки между Kibana и Elasticsearch

Для организации балансировки между Kibana и узлами Elastcisearch в Elastcisearch имеется встроенный механизм. На хост c установленной Kibana, ставится Elasticsearch с ролью Coordinating only. Узел Elasticsearch с данной ролью обрабатывает HTTP запросы и распределяет их между узлами кластера.

Установка и настройка Elasticsearch

  • Устанавливаем Elasticseach на узел с Kibana. Как это сделать описано в предыдущей статье.

  • Настраиваем новому узлу роль Coordinating only. Для этого для ролей master, data и ingest указываем параметр false:

node.master: false
node.data: false
node.ingest: false

ingest роль позволяет построить конвейер дополнительной обработки данных до их индексирования. Выделения отдельных узлов с этой ролью снижает нагрузку на другие узлы. Узел с ролью master и/или data имеют эту роль по умолчанию.

  • Указываем имя Elasticsearch кластера:

cluster.name: es_cluster  # Имя кластера
  • Указываем адреса узлов текущего кластера. Для этого создадим файл unicast_hosts.txt с перечнем узлов в директории с конфигурационными файлами Elasticsearch. Для установки из Deb и RPM пакетов это /etc/elasticsearch/ или $ES_HOME/config/ при установке из архива:

# Список узлов кластера
10.0.3.11
10.0.3.12
10.0.3.13
  • Указываем, что адреса узлов кластера нужно брать из файла:

discovery.seed_providers: file

Данный метод имеет преимущество над методом из предыдущей статьи (discovery.seed_hosts). Elasticsearch следит за изменением файла и применяет настройки автоматически без перезагрузки узла.

  • Настраиваем IP адрес и порт для приема запросов от Kibana (network.host и http.port) и для коммуникации с другими узлами кластера Elasticsearch(transport.host и transport.tcp.port). По умолчанию параметр transport.host равен network.host:

network.host: 10.0.3.1	          # Адрес узла
http.port: 9200					          # Порт
transport.host: 10.0.3.1          # Адрес для связи с кластером
transport.tcp.port: 9300-9400   	# Порты для коммуникации внутри кластера

Итоговый конфигурационный файл:

# ------------------------------------ Node ------------------------------------
# Имя узла
node.name: es-nlb01

# Указываем роль Coordinating only
node.master: false
node.data: false
node.ingest: false
#
# ---------------------------------- Cluster -----------------------------------
#
cluster.name: es_cluster  # Имя кластера
#
# --------------------------------- Discovery ----------------------------------
discovery.seed_providers: file                       
#
# ---------------------------------- Network -----------------------------------
#
network.host: 10.0.3.1	          # Адрес узла
http.port: 9200					          # Порт
transport.host: 10.0.3.1          # Адрес для связи с кластером
transport.tcp.port: 9300-9400     # Порты для коммуникации внутри кластера
#
# ----------------------------------- Paths ------------------------------------
#
path.data: /var/lib/elasticsearch # Директория с данными
path.logs: /var/log/elasticsearch # Директория с логами
  • Запускаем Elasticsearch и проверяем, что узел присоединился к кластеру:

curl -X GET "http://10.0.3.1:9200/_cluster/health?pretty"

{
  "cluster_name" : "es_cluster",
  "status" : "green",
  "timed_out" : false,
  "number_of_nodes" : 4,
  "number_of_data_nodes" : 3,
  "active_primary_shards" : 6,
  "active_shards" : 12,
  "relocating_shards" : 0,
  "initializing_shards" : 0,
  "unassigned_shards" : 0,
  "delayed_unassigned_shards" : 0,
  "number_of_pending_tasks" : 0,
  "number_of_in_flight_fetch" : 0,
  "task_max_waiting_in_queue_millis" : 0,
  "active_shards_percent_as_number" : 100.0
}

Теперь в кластере 4 узла, из них 3 с ролью data.

Настраиваем Kibana

  • В конфигурации Kibana указываем адрес Coordinating only узла:

elasticsearch.hosts:
  - http://10.0.3.1:9200
  • Перезапускаем Kibana и проверяем, что служба запустилась, а UI Kibana открывается в браузере.

Настраиваем несколько экземпляров Kibana

Чтобы организовать работу нескольких экземпляров Kibana, размещаем их за балансировщиком нагрузки. Для каждого экземпляра Kibana необходимо:

  • Настроить уникальное имя:

    • server.name уникальное имя экземпляра. По умолчанию имя узла.

В документации к Kibana указана необходимость настройки server.uuid, однако, в списке параметров конфигурации данный параметр отсутствует. На практике uuid генерируется автоматически и хранится в директории, в которой Kibana хранит свои данные. Данная директория определяется параметром path.data. По умолчанию для установки из Deb и RPM пакетов это /var/lib/kibana/ или $KIBANA_HOME/data/ для установки из архива.

  • Для каждого экземпляра в рамках одного узла необходимо указать уникальные настройки:

    • logging.dest директория для хранения логов;

    • path.data директория для хранения данных;

    • pid.file файл для записи ID процесса;

    • server.port порт, который будет использовать данный экземпляр Kibana ;

  • Указать следующие параметры одинаковыми для каждого экземпляра:

    • xpack.security.encryptionKey произвольный ключ для шифрования сессии. Длина не менее 32 символов.

    • xpack.reporting.encryptionKey произвольный ключ для шифрования отчетов. Длина не менее 32 символов.

    • xpack.encryptedSavedObjects.encryptionKey ключ для шифрования данных до отправки их в Elasticsearch. Длина не менее 32 символов.

    • xpack.encryptedSavedObjects.keyRotation.decryptionOnlyKeys список ранее использованных ключей. Позволит расшифровать ранее сохраненные данные.

Настройки безопасности(xpack) ELK будут рассмотрены в отдельной статье.

Чтобы запустить несколько экземпляров Kibana на одном узле, необходимо указать путь к файлу конфигурации каждого из них. Для этого используется ключ -c:

bin/kibana -c <путь_к_файлу_конфигурации_#1>
bin/kibana -c <путь_к_файлу_конфигурации_#2>

Скачиваем и устанавливаем Logstash

Установка из Deb пакета

  • Импортируем GPG ключ:

wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
  • Устанавливаем apt-transport-https пакет:

sudo apt-get install apt-transport-https
  • Добавляем репозиторий Elastic:

echo "deb https://artifacts.elastic.co/packages/7.x/apt stable main" | sudo tee -a /etc/apt/sources.list.d/elastic-7.x.list
  • Устанавливаем Logstash:

sudo apt-get update && sudo apt-get install logstash
  • Настраиваем Logstash для автоматического запуска при старте системы:

sudo /bin/systemctl daemon-reload && sudo /bin/systemctl enable logstash.service

Установка из RPM пакета

  • Импортируем PGP ключ

sudo rpm --import https://artifacts.elastic.co/GPG-KEY-elasticsearch
  • В директории /etc/yum.repos.d/ создаем файл репозитория logstash.repo для CentOS или Red Hat. Для дистрибутива OpenSUSE - в директории /etc/zypp/repos.d/

[logstash-7.x]
name=Elastic repository for 7.x packages
baseurl=https://artifacts.elastic.co/packages/7.x/yum
gpgcheck=1
gpgkey=https://artifacts.elastic.co/GPG-KEY-elasticsearch
enabled=1
autorefresh=1
type=rpm-md
  • Устанавливаем Logstash c помощью пакетного менеджера в зависимости от операционной системы, yum или dnf для CentOSRed HatFedora или zypper для OpenSUSE:

# Yum
sudo yum install logstash 

# Dnf
sudo dnf install logstash 

# Zypper
sudo zypper install logstash
  • Настраиваем Logstash для автоматического запуска при старте системы:

sudo /bin/systemctl daemon-reload && sudo /bin/systemctl enable logstash.service

Установка из архива

  • Скачиваем архив с Logstash:

curl -O https://artifacts.elastic.co/downloads/logstash/logstash-7.10.2-linux-x86_64.tar.gz
  • Извлекаем данные и переходим в директорию с Logstash:

tar -xzf logstash-7.10.2-linux-x86_64.tar.gz
cd logstash-7.10.2/

Текущий каталог считается как $LOGSTASH_HOME.

Конфигурационные файлы находятся в каталоге $LOGSTASH_HOME/config/.

Помимо архива сайта можно скачать Deb или RPM пакет и установить с помощью dpkg или rpm.

Настраиваем Logstash для чтения данных из файла

В качестве примера настроим считывание собственных логов Logstash из директории /var/log/logstash/. Для этого необходимо настроить конвейер (pipeline).

Logstash имеет два типа файлов конфигурации. Первый тип описывает запуск и работу Logstash (settings files).

Второй тип отвечает за конфигурацию конвейера (pipeline) обработки данных. Этот файл состоит из трех секций: input, filter и output.

  • Чтобы описать конвейер создаем файл logstash.conf в директории /etc/logstash/conf.d/, если установка была из Deb и RPM, или в директории $LOGSTASH_HOME/conf.d/ для установки из архива, предварительно создав эту директорию.

Для установки из архива необходимо в конфигурационном файле $LOGSTASH_HOME/config/pipelines.yml указать путь до директории с настройками конвейера:

- pipeline.id: main
  path.config: "./conf.d/*.conf"

Для установки из архива также требуется указать, где хранить логи в файле конфигурации $LOGSTASH_HOME/config/logstash.yml:

path.logs: /var/log/logstash/		# логи Logstash

Не забудьте предоставить доступ на запись к данному каталогу пользователю, который осуществляет запуск Logstash.

  • В файле logstash.conf настроим плагин file в секции input для чтения файлов. Указываем путь к файлам через параметр path, а через параметр start_position указываем, что файл необходимо читать с начала:

input {
  file {
    path => ["/var/log/logstash/*.log"]
    start_position => "beginning"
  }
}

Каждое событие журнала логов будет представлять собой JSON документ и будет записано целиком в поле с ключом message. Чтобы из каждого события извлечь дату, время, источник и другую информацию, необходимо использовать секцию filter.

  • В секции filter с помощью плагина grok и встроенных шаблонов извлекаем из каждой записи (message) журнала логов необходимую информацию:

filter {
  grok {
    match => { "message" => "\[%{TIMESTAMP_ISO8601:timestamp}\]\[%{DATA:severity}%{SPACE}\]\[%{DATA:source}%{SPACE}\]%{SPACE}%{GREEDYDATA:message}" }
    overwrite => [ "message" ]
  }
}

Шаблон имеет формат %{SYNTAX:SEMANTIC} и по сути это оболочка над регулярным выражением, соответственно шаблон можно описать регулярным выражением. С перечнем всех встроенных шаблоном можно ознакомится тут.

SEMANTIC - это ключ поля с данными, которые извлекаются с помощью шаблона, и под этим ключом будут храниться в JSON документе.

С помощью параметра match указываем, из какого поля (message) извлекаем данные по описанным шаблонам. Параметр overwrite сообщает, что оригинальное поле message необходимо перезаписать в соответствии с теми данными, которые мы получили с помощью шаблона %{GREEDYDATA:message}.

  • Для сохранения данных в Elasticsearch настраиваем плагин elasticsearch в секции output. Указываем адреса узлов кластера Elasticseach и имя индекса.

Индекс (index) - оптимизированный набор JSON документов, где каждый документ представляет собой набор полей ключ - значение. Каждый индекс сопоставляется с одним или более главным шардом (primary shard) и может иметь реплики главного шарда (replica shard).

Что такое индекс, шард и репликация шардов рассмотрю в отдельной статье.

output {
  elasticsearch {
    hosts => ["http://10.0.3.11:9200","http://10.0.3.12:9200","http://10.0.3.13:9200"]
    index => "logstash-logs-%{+YYYY.MM}"
  }
}

К названию индекса добавлен шаблон %{+YYYY.MM}, описывающий год и месяц. Данный шаблон позволит создавать новый индекс каждый месяц.

Итоговый файл:

# Читаем файл
input {
  file {
    path => ["/var/log/logstash/*.log"]
    start_position => "beginning"
  }
}

# Извлекаем данные из событий
filter {
  grok {
    match => { "message" => "\[%{TIMESTAMP_ISO8601:timestamp}\]\[%{DATA:severity}%{SPACE}\]\[%{DATA:source}%{SPACE}\]%{SPACE}%{GREEDYDATA:message}" }
    overwrite => [ "message" ]
  }
}

# Сохраняем все в Elasticsearch
output {
  elasticsearch {
    hosts => ["http://10.0.3.11:9200","http://10.0.3.12:9200","http://10.0.3.13:9200"]
    index => "logstash-logs-%{+YYYY.MM}"
  }
}
  • Запускаем Logstash:

sudo systemctl start logstash.service

Для установки из архива:

$LOGSTASH_HOME/bin/logstash

Смотрим полученные данные в Kibana

Открываем Kibana, в верхнем левом углу нажимаем меню и в секции Management выбираем Stack Management. Далее слева выбираем Index patterns и нажимаем кнопку Create Index Patern. В поле Index pattern name описываем шаблон logstash* , в который попадут все индексы, начинающиеся с logstash.

Создание шаблона индекса
Создание шаблона индекса

Жмем Next step и выбираем Time field поле timestamp, чтобы иметь возможность фильтровать данные по дате и времени. После жмем Create index pattern:

Выбор Time field
Выбор Time field

Logstash при анализе событий добавил поле @timestamp, в результате получилось 2 поля с датой и временем. Это поле содержит дату и время обработки события, следовательно, эти даты могут различаться. Например, если анализируемый файл имеет старые записи, то поле timestamp будет содержать данные из записей, а @timestamp текущее время, когда каждое событие были обработано.

После создания шаблона индексов Kibana покажет информацию об имеющихся полях, типе данных и возможности делать агрегацию по этим полям.

Чтобы посмотреть полученные данные на основе созданного шаблона нажимаем меню и в секции Kiban выбираем Discover.

Kibana Discover
Kibana Discover

В правой части экрана можно выбрать интервал в рамках которого отображать данные.

Выбор временного интервала
Выбор временного интервала

В левой часте экрана можно выбрать шаблон индекса или поля для отображения из списка Available fields. При нажатии на доступные поля можно получить топ-5 значений.

Шаблон индекса и доступные поля
Шаблон индекса и доступные поля

Для фильтрации данных можно использовать Kibana Query Language (KQL). Запрос пишется в поле Search. Запросы можно сохранять, чтобы использовать их в будущем.

Фильтрация данных с помощью KQL
Фильтрация данных с помощью KQL

Для визуализации полученных данных нажимаем меню и в секции Kiban выбираем Visualize. Нажав Create new visualization , откроется окно с перечнем доступных типов визуализации.

Типы визуализации Kibana
Типы визуализации Kibana

Для примера выбираем Pie, чтобы построить круговую диаграмму. В качестве источника данных выбираем шаблон индексов logstash*. В правой части в секции Buckets жмем Add , далее - Split slices. Тип агрегации выбираем Terms, поле severity.keyword. Жмем Update в правом нижнем углу и получаем готовую диаграмму. В секции Options можно добавить отображение данных или изменить вид диаграммы.

Если вместо графика отобразилась надпись No results found, проверьте выбранный интервал времени.

Круговая диаграмма
Круговая диаграмма

Чтобы посмотреть данные в Elasticsearch необходимо сделать GET запрос /имя_индекса/_search к любому узлу кластера. Добавление параметра pretty позволяет отобразить данные в читабельном виде. По умолчанию вывод состоит из 10 записей, чтобы увеличить это количество необходимо использовать параметр size:

curl -X GET "http://10.0.3.1:9200/logstash-logs-2021.01/_search?pretty&size=100"

...
{
        "_index" : "logstash-logs-2021.01",
        "_type" : "_doc",
        "_id" : "XlXeQncBKsFiW7wX45A0",
        "_score" : 1.0,
        "_source" : {
          "path" : "/var/log/logstash/logstash-plain.log",
          "@version" : "1",
          "source" : "logstash.outputs.elasticsearch",
          "message" : "[main] Restored connection to ES instance {:url=>\"http://10.0.3.11:9200/\"}",
          "host" : "logstash01",
          "timestamp" : "2021-01-27T08:03:55,979",
          "@timestamp" : "2021-01-27T08:03:58.907Z",
          "severity" : "WARN"
        }
      },
...

Заключение

В рамках этой статьи была рассмотрена процедура установки и настройки Kibana и Logstash, настройка балансировки трафика между Kibana и Elasticsearch и работа нескольких экземпляров Kibana. Собрали первые данные с помощью Logstash, посмотрели на данные с помощью Kibana Discover и построили первую визуализацию.

Прежде чем углубляться в изучение плагинов Logstash, сбор данных с помощью Beats, визуализацию и анализ данных в Kibana, необходимо уделить внимание очень важному вопросу безопасности кластера. Об этом также постоянно намекает Kibana, выдавая сообщение Your data is not secure.

Теме безопасности будет посвящена следующая статья данного цикла.

Полезные ссылки