ELK 6.x в production: убираем множественные типы и поднимаем Cross-Cluster Search
Обновляем Elasticsearch до 6.x: один тип на индекс как новое требование и Cross-Cluster Search для консолидации логов с нескольких площадок.
Elasticsearch 6.0/6.x - принудительный переход на один тип на индекс и появление Cross-Cluster Search как стандартного механизма объединения нескольких кластеров
Elasticsearch 6.0 вышел в ноябре 2017-го, и с тех пор мы откладывали обновление двух клиентских ELK-стеков под нашим управлением. Причина понятная: там живые логи, туда смотрит дежурная смена, и «упало на несколько часов пока разбирались с миграцией» - это не опция. Неделю назад всё-таки сделали. Разбираем что было.
Про «один тип на индекс» - не паника, но и не мелочь
В Elasticsearch исторически был mapping types - возможность хранить в одном индексе несколько типов документов, как таблицы в базе данных. Удобно казалось: один индекс logs-2018.02, а в нём типы nginx, app, syslog. На практике это создавало неочевидные проблемы: поля с одинаковыми именами разных типов разделяли один Lucene-индекс под капотом, и если в nginx.status было число, а в app.status - строка, это приводило к конфликтам маппинга которые потом больно лечить.
В 6.0 правило одно: на индекс - один тип. Создать второй тип в существующем индексе нельзя. Старые индексы с несколькими типами Elasticsearch 6.x читает нормально - совместимость по данным есть, но новые данные туда писать с несколькими типами уже не выйдет.
У нас в обоих стеках ситуация была такая:
- Первый стек - по одному типу на индекс и без того, просто потому что Logstash так настраивали. Там вопрос закрылся за тридцать минут - обновили ES, Kibana, Logstash, проверили что данные пишутся.
- Второй стек - три типа в одном индексе, наследие старой конфигурации. Вот там пришлось думать.
Решение для второго: разделили один физический индекс на три - logs-nginx-*, logs-app-*, logs-syslog-*. В Logstash добавили routing по полю type и прописали три output-блока с соответствующими паттернами. Kibana index patterns пришлось создать заново. Исторические данные не мигрировали - просто с определённой даты пишем в новую схему, старое читается пока есть retention.
Kibana 6 это обновление пережила нормально: старые index patterns на старые индексы продолжают работать, новые создали поверх. Временное двоевластие в интерфейсе выглядит странно, но жить можно.
Cross-Cluster Search: зачем и как
У одного из клиентов две площадки - основная и резервная, плюс отдельный стенд с теми же сервисами для тестирования. Логи с каждой площадки идут в свой ELK. Пока площадки работали независимо, это было нормально. Но когда понадобилось искать инциденты которые затронули обе площадки одновременно - начались танцы: открой Kibana на первой, посмотри там, открой на второй, сравни. Корреляция руками, раздражает всех.
Cross-Cluster Search в Elasticsearch появился в 5.3 как xpack-фича, в 6.x остаётся частью X-Pack (Gold/Platinum). Механика простая: один кластер объявляется координирующим, остальные регистрируются в нём как remote. Запрос из Kibana уходит на координирующий кластер, тот транслирует его на remote-кластеры и агрегирует результат.
Настройка в elasticsearch.yml координирующего узла:
search:
remote:
site-a:
seeds:
- es-site-a-node1:9300
- es-site-a-node2:9300
site-b:
seeds:
- es-site-b-node1:9300
Или через API (удобнее когда нужно менять без рестарта):
PUT /_cluster/settings
{
"persistent": {
"search.remote.site-a.seeds": ["es-site-a-node1:9300", "es-site-a-node2:9300"],
"search.remote.site-b.seeds": ["es-site-b-node1:9300"]
}
}
После этого к индексам на remote-кластерах обращаются через алиас cluster-name:index-pattern. В Kibana index pattern выглядит так: site-a:logs-*,site-b:logs-* - и всё, один дашборд, все площадки. Kibana 6.x это умеет из коробки.
Важный момент по сети: между кластерами нужен доступ по порту 9300 (transport), а не только 9200 (HTTP). В конкретном случае клиента площадки соединены VPN, так что это уже работало. Если сеть разделена - придётся открывать транспортный порт, и это отдельный разговор с безопасниками.
Что поехало при обновлении
Несколько вещей которые не были очевидны заранее:
- Logstash 6.x и поле
type. В Logstash 6 полеtypeв событии теперь только для внутренней маршрутизации внутри pipeline, в Elasticsearch оно не пробрасывается автоматически как раньше. Если строили routing по%{type}в output - нужно явно добавить поле через mutate или использовать другой признак для разделения индексов. - Kibana 6 и .kibana индекс. При обновлении Kibana 5 -> 6 старый
.kibanaиндекс мигрируется автоматически при первом запуске. Это занимает время и в этот момент Kibana недоступна - предупредить пользователей заранее. - X-Pack лицензия. В 6.x структура лицензий изменилась. Basic-лицензия бесплатна но требует регистрации. Если старый стек работал без x-pack совсем - нужно включить и активировать Basic, это не автоматически.
Где стоим
На managed-инфраструктуре оба ELK-стека теперь на 6.x. Cross-Cluster Search на клиентской инсталляции поднят и дашборды работают. Дежурная смена клиента первые два дня поглядывала с подозрением - привыкли к двум отдельным Kibana, а теперь один интерфейс. Привыкли быстро.
Следующий вопрос который нас ждёт - ILM (Index Lifecycle Management). В 6.3 обещают полноценную политику управления жизненным циклом индексов прямо из Elasticsearch без curator на крон. Пока используем curator, но посмотрим что выйдет.
- Prometheus 2.0: новый TSDB и план миграции с 1.x без боли · 2 февраля 2018
- Kubernetes 1.9: Workloads API в GA - планируем миграцию stateful-сервисов · 23 января 2018