Год назад мы запустили пилотную версию промо проекта по децентрализованному прокату электроскутеров.
Изначально проект назывался Road-To-Barcelona, позже стал Road-To-Berlin (отсюда встречающиеся на скриншотах R2B), а в итоге и вовсе был назван xRide.
Основная идея проекта была в следующем: вместо того чтобы иметь централизованный сервис проката автомобилей или скутеров (речь пойдет о скутерах aka электро-мотоциклах, а не kickscooter/самокатах) мы хотели сделать платформу для децентрализованной аренды. О сложностях с которыми мы столкнулись уже писали ранее.
Изначально проект ориентировался на автомобили, но из-за сроков, крайне долгих общений с производителями и огромного количества ограничений по безопасности, для пилота были выбраны электрические скутеры.
Пользователь устанавливал iOS или Android приложение на телефон, подходил к понравившемуся ему скутеру, после чего телефон и скутер устанавливали peer-to-peer соединение, происходил обмен ETH и пользователь мог начать поездку включив скутер через телефон. По завершении поездки так же можно было провести оплату поездки за счет Ethereum из кошелька пользователя на телефоне.
Помимо скутеров пользователь видел в приложении "умные зарядки", посетив которую пользователь мог сам сменить текущую батарею, если она разрядилась.
Так в целом и выглядел наш пилот, запущенный в сентябре прошлого года в двух городах Германии: Бонн и Берлин.
И вот, однажды, в Бонне, ранним утром наша команда поддержки (находящаяся в локации для поддержания скутеров в работоспособном состоянии) была поднята по тревоге: один из скутеров бесследно исчез.
Как его найти и вернуть?
В этой статье я расскажу об этом, но для начала — о том как мы построили нашу собственную IoT платформу и как мы осуществляли мониторинг над ней.
Что и зачем мониторить: скутеры, инфраструктура, зарядки?
Итак, что же мы хотели мониторить в нашем проекте?
В первую очередь это сами скутеры — электроскутеры сами по себе довольно дорогие, нельзя запускать такой проект не будучи достаточно подготовленными, по возможности хочется собирать как можно больше информации о скутерах: об их местоположении, уровне заряда, итд.
Помимо этого, хотелось бы отслеживать состояние нашей собственной IT инфраструктуры — базы, сервисы и все что им необходимо для работы. Нужно было отслеживать и состояние "умных зарядок", на случай если они сломались или в них кончились полные батареи.
Скутеры
Что же из себя представляли наши скутеры и что мы хотели о них знать?
Первое, и самое существенное — GPS координаты, так как благодаря им мы можем понимать, где они находятся и куда двигаются.
Далее — заряд батареи, благодаря ему мы можем определять, что зарядка скутеров подходит к концу и отправить juicer'а или хотя бы предупредить пользователя.
Конечно, необходимо также проверять что происходит с нашими Hardware компонентами:
- работает ли Bluetooth?
- работает ли сам GPS модуль?
- так же у нас была проблема с тем, что GPS мог отсылать неверные координаты и "залипать", а определить это можно было только на уровне дополнительных проверок на скутере,
и нотифицировать поддержку как можно скорее для устранения проблемы
- так же у нас была проблема с тем, что GPS мог отсылать неверные координаты и "залипать", а определить это можно было только на уровне дополнительных проверок на скутере,
И последнее: проверки софтверной части, начиная с ОС и загрузки процессора, сети и диска, заканчивая уже более специфичными для нас проверками наших собственных модулей (Jolocom, Keycloak).
Hardware
Что же представляла наша "железная" часть?
Учитывая максимально сжатые сроки и необходимость быстрого прототипирования мы выбрали для себя максимально простой для реализации и подбора компонентов вариант — Raspberry Pi.
Помимо самого Rpi мы имели кастомную борду (которые мы сами разработали и заказывали в Китае для ускорения процесса сборки конечного решения) и набор компонентов — реле (для включения/выключения скутера), считыватель заряда батареи, модем, антенны. Все это было компактно укомплектовано в специальную коробочку "xRide box".
Следует также отметить, что вся коробочка питалась дополнительным павербанком, который в свою очередь питался от основной батареи скутера.
Это позволяло использовать мониторинг и включать скутер, даже после окончания поездки, так как основная батарея отключалась сразу после поворота ключа зажигания в положение "off".
Docker? Plain linux? и деплой
Вернемся к мониторингу, итак Raspberry — что же мы имеем?
Одна из первых вещей которую мы хотели использовать для ускорения процесса деплоя, обновления и доставки компонентов на физические устройства был Docker.
К сожалению, довольно быстро стало ясно что Docker на RPi хоть и работает, но дает достаточно много накладных расходов, в частности по энергопотреблению.
Разница с использованием "нативной" ОС пусть и не была настолько сильной, но все же достаточной чтобы мы опасались возможности слишком быстрой потери заряда.
Второй причиной стала одна из библиотек наших партнеров на Node.js (sic!) — единственный компонент системы, который не был написан на Go/C/C++.
Авторы библиотеки не успели вовремя предоставить рабочую версию на любом из "нативных" языков.
Мало того, что нода сама по себе не является самым элегантным решением для низкопроизводительных девайсов, так ещё и сама библиотека была весьма прожорлива по ресурсам.
Мы поняли, что при всем желании использование Docker для нас будет слишком большим оверхедом. Был сделан выбор в пользу нативной OS и работы под ней напрямую.
OS
В итоге, в качестве ОС мы, опять же, избрали самый простой вариант и использовали Raspbian (сборка Debian для Pi).
Весь наш софт мы пишем на Go, поэтому и основной hardware-агент модуль в нашей системе мы также написали на Go.
Именно он и отвечает за работу с GPS, Bluetooth, считывание заряда, включение скутера, итд.
Деплой
Тут же встал вопрос о необходимости реализации механизма доставки обновлений на девайсы (OTA) — как обновлений самого нашего агента/приложения, так и обновления самой ОС/"прошивки" (так как новые версии агента могли требовать обновлений ядра или компонентов системы, библиотек итд).
После довольно долгого анализа рынка выяснилось, что существует довольно много решений для доставки обновлений на девайс.
От относительно простых утилит, по большей части ориентированных на обновление/dual-boot вроде swupd/SWUpdate/OSTree до полноценных платформ вроде Mender и Balena.
В первую очередь мы решили, что нас интересуют именно end-to-end решения, поэтому выбор сразу пал на платформы.
Сама Balena была исключена ввиду того, что фактически использует тот же самый Docker внутри своего balenaEngine.
Но отмечу, что несмотря на это, в конечном итоге мы постоянно использовали их продукт Balena Etcher для флеша прошивок на SD карты — простая и крайне удобная утилита для этого.
Поэтому в итоге выбор пал на Mender. Mender представляет из себя полноценную платформу для сборки, доставки и установки прошивок.
В целом платформа выглядит просто замечательно, но нам потребовалось около полутора недель только на то, чтобы собрать правильную версию нашей прошивки с помощью сборщика mender.
И чем больше мы погружались в тонкости его использования, тем больше становилось ясно, что на полноценное его развертывание нам понадобилось бы сильно больше времени, чем у нас было.
Увы, наши сжатые сроки привели к тому, что мы вынуждены были отказаться от использования Mender и выбрать ещё более простой пусть.
Ansible
Самым простым решением в нашей ситуации оказалось использование Ansible. Пары playbook'ов для начала было вполне достаточно.
Суть их сводилась к тому, что мы просто подключались с хоста (CI сервер) по ssh к нашим расберри и разливали на них обновления.
В самом начале все было просто — нужно было находиться в единой сети с устройствами, разливка шла через Wi-Fi.
В офисе просто находилось десяток тестовых малинок, подключенных к одной сети, каждое устройство имело статический IP адрес так же указанный в Ansible Inventory.
Именно Ansible доставлял наш мониторинг-агент на конечные устройства
3G/LTE
К сожалению, такой вариант использования Ansible мог работать только в режиме разработки, пока у нас ещё не было реальных скутеров.
Потому что скутеры, как вы понимаете, не стоят подключенные к одному Wi-Fi роутеру постоянно ожидая обновления по сети.
В реальности у скутеров вообще не может быть никакого соединения кроме мобильного 3G/LTE (и то не постоянно).
Это накладывает сразу много проблем и ограничений, вроде низкой скорости соединения и нестабильной связи.
Но самое главное — в 3G/LTE сети мы не можем просто надеяться на статичный IP присвоенный в сети.
Это частично решается некоторыми провайдерами SIM карт, есть даже специальные симки предназначенные для IoT устройств со статическими IP адресами. Но мы не имели доступа к таким SIM картам и не могли использовать IP адреса.
Конечно, были идеи делать некую регистрацию IP адресов aka service discovery где-то вроде Consul, но от подобных идей пришлось отказаться, так как у нас в тестах IP адрес мог меняться слишком часто, что приводило к большой нестабильности работы.
По этой причине, наиболее удобное использование для доставки метрик было бы не с использованием pull модели, где мы ходили бы за нужными метриками на устройства, а push с доставкой метрик с устройства напрямую на сервер
VPN
В качестве решения этой проблемы мы выбрали VPN — а конкретно Wireguard.
Клиенты (скутеры) на старте системы подключались к VPN серверу и держали возможность подключения к ним. Этот туннель и использовался для доставки обновлений.
В теории, тот же туннель можно было использовать и для мониторинга, но такое подключение было сложнее и менее надежным чем простой push.
Облачные ресурсы
Последнее — необходимо отслеживать наши облачные сервисы и БД, так как для них мы используем Kubernetes, в идеале чтобы разворачивание мониторинга в кластере было максимально простым. В идеале — с использованием Helm, так как для деплоя, мы в большинстве случаев используем его. И, само собой, для мониторинга облака нужно использовать те же решения, что и для самих скутеров.
Дано
Фуф, вроде с описанием разобрались, давайте составим список того, что нам было нужно в итоге:
- Быстрое решение, так как мониторить необходимо уже во время процесса разработки
- Объем/количество — нужно множество метрик
- Сбор логов обязателен
- Надежность — данные критически важны для успеха запуска
- Нельзя использовать pull модель — нужен push
- Нужен единый мониторинг не только железа, но и облака
Конечная картинка выглядела примерно так
Выбор стека
Итак, перед нами встал вопрос выбора стека для мониторинга.
В первую очередь, мы искали наиболее полноценное all-in-one решение, которое одновременно покрывало бы все наши требования, но при этом и было бы достаточно гибким чтобы подогнать его использование под наши нужды. Все-таки, у нас было много ограничений наложенных на нас железом, архитектурой и сроками.
Существует огромное множество решений для мониторинга, начиная полноценными системами вроде Nagios, icinga или zabbix и заканчивая уже готовыми решениями по Fleet management.
Изначально, последние казались идеальным для нас решением, но в одних не было полноценного мониторинга, в других были сильно урезаны возможности бесплатных версий, а третьи просто не покрывали наши "хотелки" или не были достаточно гибкими для подгонки под наши сценарии. Некоторые просто устарели.
После анализа какого-то количества подобных решений мы быстро пришли к выводу, что проще и быстрее будет собрать схожий стек самостоятельно. Да, это будет чуть сложнее чем разворачивание полностью готовой Fleet management платформы, но зато нам не придется идти на компромиссы.
Почти наверняка, во всем огромном обилии решений и есть уже готовое которое полностью бы нам подошло, но в нашем случае значительно быстрее было собрать некий стек самостоятельно и подогнать "под себя", нежели тестировать готовые продукты.
При всем этом, мы не стремились собирать целиковую платформу для мониторинга самостоятельно, а искали максимально функциональные "готовые" стеки, только с возможностью их гибко настраивать.
(B)ELK?
Первое решение, которое реально рассматривалось — широко известный ELK стек.
На самом деле он должен называться BELK, ведь начинается все с Beats — https://www.elastic.co/what-is/elk-stack
Конечно, ELK это одно из самых известных и мощных решений в области мониторинга, а уж в сборе и обработке логов, так и самое.
Мы подразумевали, что ELK будет использоваться для сбора логов и, так же как долговременное хранилище метрик полученных из Prometheus.
Для визуализации можно использовать Grafan'у.
На самом деле, свежий ELK стек умеет собирать метрики и самостоятельно (metricbeat), Kibana так же умеет показывать их.
Но все-таки изначально ELK вырос из логов и пока функционал метрик имеет ряд серьезных недостатков:
- Значительно медленнее Prometheus
- Интегрируется в куда меньшее количество мест чем Prometheus
- Сложно настроить алертинг по ним
- Метрики занимают большое количество места
- Настройка дашбордов с метриками в Kiban'е значительно сложнее Grafan'ы
В общем, метрики в ELK тяжелые и пока не такие удобные как в других решениях, которых сейчас на самом деле значительно больше чем просто Prometheus: TSDB, Victoria Metrics, Cortex итд итп. Конечно, очень бы хотелось иметь сразу полноценное all-in-one решение, но в случае с metricbeat выходило слишком много компромиссов.
Да и у самого ELK стека есть ряд непростых моментов:
- Он тяжелый, порой даже очень, если у вас собирается довольно большое количество данных
- Его нужно "уметь готовить" — скалировать его необходимо, но делается это нетривиально
- Урезанная бесплатная версия — в бесплатной версии нет нормального алертинга, на момент выбора не было и аутентификации
Надо сказать, что в последнее время с последним пунктом стало получше и помимо вывода в open-source X-pack (в том числе аутентификация) начала меняться сама модель прайсинга.
Но на момент, когда мы собирались разворачивать это решение, алертинга не было совсем.
Возможно, можно было попробовать собрать что-то с использованием ElastAlert или других community решений, но все же решили рассмотреть другие альтернативы.
Loki — Grafana — Prometheus
На данный момент неплохим решением может быть сборка стека мониторинга на основе чисто Prometheus как поставщика метрик, Loki для логов, а для визуализации можно использовать все ту же Grafana.
К сожалению, на момент старта прода пилота проекта (сентябрь-октябрь 19ого года) Loki ещё находился в бета версии 0.3-0.4, а на момент старта разработки и вовсе не мог рассматриваться как produtcion решение.
Я пока не имею опыта реального использования Loki в серьезных проектах, но могу сказать, что Promtail (агент для сбора логов) здорово работает как для bare-metal, так и для подов в kubernetes.
TICK
Пожалуй, наиболее достойной (единственной?) полнофункциональной альтернативой ELK стеку сейчас можно назвать только TICK стек — Telegraf, InfluxDB, Chronograf, Kapacitor.
Я опишу все компоненты ниже более подробно, но в целом идея такая:
- Telegraf — агент для сборки метрик
- InfluxDB — база данных метрик
- Kapacitor — обработчик метрик в реальном времени для алертинга
- Chronograf — веб панель для визуализации
Для InfluxDB, Kapacitor и Chronograf есть официальные helm чарты, которые мы использовали для их разворачивания.
Надо отметить, что в свежей версии Influx 2.0 (beta) Kapacitor и Chronograf стали частью InfluxDB и больше не существуют отдельно
Telegraf
Telegraf — это очень легковесный агент для сбора метрик на конечной машине.
Он умеет мониторить огромное количество всего, от nginx до
сервера minecraft.
У него есть ряд классных преимуществ:
- Быстрый и легкий (написан на Go)
- Ест минимальное количество ресурсов
- Push метрик по умолчанию
- Собирает все необходимые метрики
- Системные метрики без каких-либо настроек
- Хардварные метрики вроде информации с датчиков
- Очень легко добавлять собственные метрики
- Много плагинов "из коробки"
- Собирает логи
Так как push метрик был для нас необходим, все остальные преимущества были более чем приятными дополнениями.
Сборка логов самим же агентом так же очень удобна, так как нет необходимости подключать дополнительные утилиты для тейлинга логов.
Influx предлагает максимально удобный опыт работы с логами если вы используете syslog.
Telegraf вообще отличный агент для сборки метрик, даже если вы не используете весь остальной ICK стек.
Многие скрещивают его и с ELK и с различными другими time-series базами по удобству, так как он умеет писать метрики почти куда угодно.
InfluxDB
InfluxDB — основное ядро TICK стека, а именно time-series база данных для метрик.
Помимо метрик Influx также может хранить и логи, хотя, по сути логи для него это всего лишь такие же метрики, только вместо обычных числовых показателей основную функцию несет строка текста лога.
InfluxDB тоже написан на Go и работает, по ощущениям, значительно быстрее в сравнении с ELK на нашем (не самом мощном) кластере.
К одним из крутых преимуществ Influx я бы также отнес очень удобное и богатое API для запросов к данным, которые мы очень активно использовали.
Недостатки — $$$ или скалирование?
У TICK стека есть только один обнаруженный нами недостаток — он дорогой. Даже очень.
А что есть в платной версии, чего нет в бесплатной?
Насколько нам удалось понять, единственное чем отличается платная версия TICK стека от бесплатной — возможности скалирования.
А именно — поднять кластер с High availability можно только в Enterprise версии.
Хотите полноценное HA — нужно либо платить, либо городить какие-нибудь костыли. Есть пара решений сообщества — например influxdb-ha похоже на грамотное решение, но написано что не подходит для продакшена, а так же
influx-spout — простое решение с прокачкой данных через NATS (его тоже придется скалировать, но это решаемо).
Жаль, но оба они, похоже, заброшены — нет свежих коммитов, предположу, что дело в скором ожидаемом выходе новой версии Influx 2.0 в которой многое будет иначе (пока информации о скалировании в ней нет).
Официально для бесплатной версии существует Relay — фактически это примитивное HA, но только посредством балансировки,
так как все данные будут писаться во все инстансы InfluxDB за load balancer'ом.
У него есть некоторые недостатки вроде потенциальных проблем с перезаписью точек и необходимости создавать базы для метрик заранее
(что при обычной работе с InfluxDB происходит автоматически).
К тому же шардирование не поддерживается, это означает дополнительные накладные расходы на дуплицированные метрики (и обработка и хранение), которые могли вам быть не нужны, но разделить их возможности нет.
Victoria Metrics?
В итоге, несмотря на то, что во всем помимо платного скалирования TICK стек нас полностью устраивал, мы решили посмотреть нет ли бесплатных решений, которыми можно заменить InfluxDB базу, оставив при этом остальные компоненты T_CK.
Time-series баз немало, но наиболее подающая надежды — Victoria Metrics, у нее целый ряд плюсов:
- Быстрая и легкая, по крайней мере по результатам бенчмарков
- Есть кластерная версия, про которую сейчас даже есть хорошие отзывы
- Она можешь шардироваться
- Поддерживает InfluxDB протокол
Мы не собирались строить полностью кастомный стек на основе Victoria и основная надежда была на то, что мы сможем воспользоваться ею как drop-in заменой для InfluxDB.
К сожалению, это невозможно, несмотря на то, что поддерживается протокол InfluxDB, это работает только для записи метрик — "наружу" доступно только Prometheus API, а значит натравить Chronograf на нее не получится.
Более того, для метрик поддерживаются только числовые значения (мы использовали строковые значения для кастомных метрик — об этом в разделе админка).
Очевидно, по той же причине VM не может хранить логи, как это делает Influx.
Также, надо отметить, что на момент поиска оптимального решения Victoria Metrics еще не была так популярна, документация была значительно меньше и функционал был слабее
(не припоминаю подробного описания кластерной версии и шардирования).
Выбор базы
В результате было принято решение, что для пилота мы все же ограничимся одиночной нодой InfluxDB.
Основных причин такого выбора было несколько:
- Нам очень нравился функционал TICK стека целиком
- Мы уже успели его развернуть и оно отлично работало
- Сроки поджимали и не оставалось много времени тестировать другие варианты
- У нас не ожидалось такой большой нагрузки
Скутеров у нас для первой фазы пилота было не так много, и тестирование во время разработки не выявило каких-либо проблем с производительностью.
Поэтому мы решили, что для данного проекта нам вполне хватит и одно ноды Influx без необходимости скалирования (cм выводы в конце).
Со стеком и базой решили — теперь об остальных компонентах TICK стека.
Kapacitor
Kapacitor — это часть TICK стека, сервис который может следить за попадающими в базу метриками в реальном времени и выполнять на основе правил различные действия.
Вообще он позиционируется как тул для потенциального отслеживания аномалий и машинного обучения (не уверен что эти функции востребованы), но наиболее популярный кейс его использования более банален — это алертинг.
Так и мы его использовали для нотификаций. Мы настроили Slack оповещения о том, что тот или иной скутер отключился, то же самое было сделано для умных зарядок и важных компонентов инфраструктуры.
Это позволяло быстро реагировать на проблемы, а также получать нотификации о том, что все пришло в норму.
Простой пример — сломалась или по какой-то причине разрядилась дополнительная батарея для питания нашей "коробочки", просто поставив новую мы должны через некоторое время получить нотификацию о восстановлении работоспособности скутера.
В Influx 2.0 Kapacitor стал частью DB
Chronograf
Я повидал много различных UI решений для мониторинга, но могу сказать, что по функционалу и UX ничто не сравнится с Chronograf'ом.
Начинали мы использовать TICK стек, как ни странно, с Grafan'ой в качестве веб-интерфейса.
Описывать ее функционал не буду, всем известны ее широкие возможности по настройке всего что угодно.
Однако, Grafana все же представляет из себя совсем универсальный инструмент, тогда как Chronograf в основном заточен под использование с Influx.
И конечно, благодаря этому, Chronograf может позволить себя куда более хитрый или удобный функционал.
Пожалуй, основное удобство работы с Chronograf в том, что вы можете смотреть внутренности вашей InfluxDB через Explore.
Казалось бы, в Grafana есть почти идентичный функционал, но в реальности настройка дашборда в Chronograf может осуществляться несколькими кликами мыши (попутно смотря на визуализацию там же), тогда как в Grafana вам все равно рано или поздно придется редактировать JSON конфигурацию (само собой Chronograf позволяет выгрузить ваши настроенные "руками" даши и редактировать в виде JSON если необходимо — но мне никогда не приходилось их трогать после создания на UI).
В Kibana куда более богатые возможности по созданию дашбордов и контролов для них, но и UX для таких операций ну очень сложный.
Потребуется неплохо разобраться чтобы создать себе удобный дашборд. И хотя функционал дашбордов у Chronograf меньше, делать и настраивать их значительно проще.
Сами дашборды, помимо приятного визуального стиля, фактически ничем от дашбордов в Grafana или Kibana не отличаются:
Так выглядит то самое окно запросов:
Важно отметить, помимо прочего, что зная типы полей в базе InfluxDB хронограф иногда сам может автоматически помогать вам с написанием Query или выбором правильной функции агрегации типа mean.
Ну и конечно же, Chronograf максимально удобен для просмотра логов. Выглядит это так:
По умолчанию Influx логи заточны под использование syslog и поэтому в них есть важный параметр — severity.
Особенно полезен график сверху, на нем можно увидеть возникающие ошибки и цветом сразу отчетливо видно если severity более высокий.
Пару раз таким образом мы ловили важные баги, зайдя в просмотр логов за последнюю неделю и увидев красный спайк.
Конечно, в идеале было бы настроить алертинг на такие ошибки, благо у нас уже было все для этого.
Мы даже на какое-то время включали это, но, в процессе подготовки пилота выяснилось, что у нас возникает довольно много ошибок (в том числе системных вроде недоступности LTE сети), которые слишком сильно "спамят" в Slack канал, при этом не неся большой пользы.
Правильным решением было бы обработать большинство подобных типов ошибок, настроить для них severity и уже потом включить алертинг.
Таким образом в Slack попадали бы только новые или важные ошибки. На подобный сетап банально не хватило времени в условиях сжатых сроков.
Аутентификация
Отдельно стоит упомянуть то, что Chronograf поддерживает OAuth и OIDC в качестве аутентификации.
Это очень удобно, так как позволяет легко прикрутить его к вашему серверу и сделать полноценное SSO.
В нашем случае — сервером был Keycloak — он использовался для подключения к мониторингу, но при этом тот же сервер использовался и для аутентификации скутеров и запросов на back-end.
“Админка”
Последний компонент, который я опишу — это наша самописная "админка" на Vue.
В целом это просто отдельный сервис, который отображает информацию о скутерах одновременно из наших собственных баз данных, микросервисов и данные метрик из InfluxDB.
Помимо того, туда были вынесены многие административные функции, вроде экстренной перезагрузки или удаленного открытия замка для команды поддержки.
Также там были карты. Я уже упоминал, что начинали мы с Grafana вместо Chronograf — потому что для Grafana в виде плагинов доступны карты, на которых можно было смотреть координаты скутеров. К сожалению, возможности виджетов карт для Grafana очень ограничены, и в результате было гораздо проще за несколько дней написать свое собственное веб приложение с картами, для того чтобы не только видеть координаты в данный момент, но и отображать пройденный скутером маршрут, уметь фильтровать данные на карте, итд (весь тот функционал, который мы не смогли бы настроить в простом дашборде).
Один из уже упомянутых плюсов Influx — возможность легко создавать свои собственные метрики.
Это позволяет использовать его для огромного множества сценариев.
Мы старались записывать туда всю полезную информацию: заряд батареи, состояние замка, работоспособность датчиков, bluetooth, GPS, множество других healthcheck'ов.
Все это мы и отображали на админ панели.
Конечно, самым главным критерием для нас было состояние работы скутера — фактически Influx проверяет это сам и показывает в разделе Nodes "зелеными лампочками".
Делается это функцией deadman — мы использовали ее же для понимания работоспособности нашей коробочки и отсылки тех самых алертов в Slack.
Кстати, мы называли скутеры по именами персонажей из Симпсонов — так их было удобно отличать друг от друга
Да и вообще так было веселее. Постоянно звучали фразы вроде "Ребята — Смитерс умер!"
Строковые метрики
Важно, что InfluxDB позволяет хранить не только числовые значения, как в случае с Victoria Metrics.
Казалось бы, это не так важно — ведь если не считать логов, любые метрики можно хранить в виде чисел (всего лишь добавить маппинг для известных состояний — своего рода enum)?
В нашем случае, был как минимум один сценарий, когда строковые метрики были очень полезны.
Так уж получилось, что поставщик наших "умных зарядок" был сторонним, мы не имели никакого контроля над процессом разработки и информацией, которую эти зарядки могут поставлять.
В результате API зарядок было далеко от идеала, но основной проблемой было то, что мы не всегда могли понять их состояние.
Тут на помощь и пришел Influx. Мы просто-напросто записывали приходящий нам строковый status в поле базы InfluxDB без изменений.
Какое-то время туда попадали только значения вида "online" и "offline", на основе чего у нас в админке отображалась информация, а в Slack приходили уведомления. Однако в какой-то момент туда стали попадать так же значения вида "disconnected".
Как позже выяснилось, этот статус высылался однократно после потери связи, если зарядка не могла установить соединение с сервером после какого-то количества попыток.
Таким образом, если бы мы использовали только фиксированный набор значений — мы могли бы не увидеть этих изменений в прошивке в нужный момент времени.
Да и вообще, строковые метрики дают куда больше возможностей для использования, записывать в них можно фактически любую информацию. Хотя, конечно, использовать этот инструмент тоже нужно аккуратно.
Помимо обычных метрик, мы так же записывали в InfluxDB информацию о GPS локации. Это было невероятно удобно для мониторинга местонахождения скутеров в нашей админской панели.
Фактически, мы всегда знали где и какой скутер был в нужный нам момент времени.
Очень сильно нам это пригодилось, когда мы разыскивали скутер (смотри выводы в конце).
Мониторинг инфраструктуры
Помимо самих скутеров, нам было необходимо мониторить и всю нашу (довольно обширную) инфраструктуру.
Очень обобщенная архитектура выглядела примерно так:
Если выделить чисто стек мониторинга, то он выглядит следующим образом:
Из того что мы хотели бы проверять в облаке, это:
- Базы данных
- Keycloak
- Микросервисы
Так как все наши облачные сервисы находятся в Kubernetes, то было бы неплохо собирать информацию и о его состоянии.
К счастью, Telegraf "из коробки" может собирать огромное количество метрик о состоянии Kubernetes кластера, а Chronograf сразу предлагает для этого красивые дашборды.
Мы следили в основном за работоспособностью подов и потреблением памяти. В случае падения — алерты в Slack.
Для отслеживания подов в Kubernetes есть два пути: DaemonSet и Sidecar.
Оба способа подробно описаны в этом блог посте.
Мы использовали Telegraf Sidecar и помимо метрик собирали логи подов.
В нашем случае с логами пришлось повозится. Несмотря на то что Telegraf умеет вытаскивать логи из Docker API, мы хотели иметь единообразный сбор логов с нашими конечными устройствами и настраивали для этого syslog для контейнеров. Возможно, это решение не было красивым, но нареканий в его работе не было и логи хорошо отображались в Chronograf'e.
Мониторить мониторинг???
В конце концов встал извечный вопрос мониторинга систем мониторинга, но к счастью, или к сожалению, на это у нас просто не хватило времени.
Хотя Telegraf легко умеет отправлять свои собственные метрики или собирать метрики InfluxDB базы для отправки либо в тот же Influx, либо куда-то ещё.
Выводы
Какие выводы мы сделали по результатам пилота?
Как можно делать мониторинг
В первую очередь — TICK стек полностью оправдал наши ожидания, и дал нам даже больше возможностей, чем те на которые мы рассчитывали изначально.
Весь функционал, который был нам необходим, присутствовал. Все что мы с ним делали — работало без проблем.
Производительность
Основная проблема TICK стека в бесплатной версии — отсутствие возможностей по скалированию. Для нас это не стало проблемой.
Мы не собирали точных данных/цифр о нагрузке, но мы собирали данные с примерно 30и скутеров одновременно.
Каждый из них собирал более трех десятков метрик. Одновременно собирались логи с устройств. Сбор и отправка данных происходили каждые 10 секунд.
Важно отметить, что спустя полторы недели пилота, когда основную массу "детских болячек" удалось исправить и самые важные проблемы уже были решены, нам пришлось снизить частоту отправки данных на сервер до 30и секунд. Это стало необходимо, потому что трафик на наших LTE SIM картах начал быстро таять.
Основную массу трафика съедали логи, сами метрики даже с 10и-секундным интервалом практически не тратили его.
В итоге, спустя ещё какое-то время мы совсем отключили сбор логов на устройствах, так как конкретные проблемы уже были очевидны и без постоянного сбора.
В некоторых случаях, если просмотр логов все же был необходим — мы просто подключались через WireGuard по VPN.
Ещё добавлю, что каждый отдельный environment у нас был отделен друг от друга, и вышеописанная нагрузка была актуальна только для продакшен среды.
В среде разработчиков у нас был поднят отдельный инстанс InfluxDB который продолжал собирать данные раз в 10 секунд и мы не уткнулись в какие-либо проблемы с производительностью.
TICK — идеально для небольших-средних проектов
На основе этой информации я бы сделал вывод, что TICK стек идеально подходит для относительно небольших проектов или проектов, у которых точно не ожидается какого-либо HighLoad.
Если у вас нет тысяч подов или сотен машин — даже один инстанс InfluxDB прекрасно справится с нагрузкой.
В некоторых случаях вас может устроить Influx Relay как примитивное решение по High Availability.
И, само собой, никто не мешает вам настраивать "вертикальное" скалировние и просто выделить различные сервера под различные типы метрик.
Если же вы не уверены в ожидаемой нагрузке на сервисы мониторинга, или у вас гарантированно есть/будет очень "тяжелая" архитектура — бесплатную версию TICK стека использовать я бы не порекомендовал.
Конечно, простым решением было бы приобретение InfluxDB Enterprise — но тут я не могу как-то прокомментировать, так как сам не знаком с тонкостями. Кроме того, что это очень дорого и точно не подойдет для мелких компаний.
В таком случае, на сегодняшний день, я бы порекомендовал посмотреть в сторону сбора метрик через Victoria Metrics и логов с помощью Loki.
Правда, снова оговорюсь, что Loki/Grafana значительно менее удобны (в виду своей большей универсальности) чем готовый TICK, но зато они бесплатны.
Важно: вся описанная здесь информация актуальна для версии Influx 1.8, в данный момент вот-вот должен выйти в релиз Influx 2.0.
Пока не довелось попробовать его в боевых условиях и сложно делать выводы об улучшениях, точно еще лучше стал интерфейс, упростилась архитектура (без kapacitor и chronograf),
появились темплейты ("киллер фича" — можно отслеживать игроков в Fortnite и получать нотификации когда твой любимый игрок выигрывает партию). Но, к сожалению, в данный момент в версии 2 нет ключевой вещи, по которой мы выбрали первую версию — нет сбора логов.
Этот функционал в Influx 2.0 тоже появится, но каких-либо сроков, даже примерных, найти не удалось.
Как не нужно делать IoT платформы (теперь)
В конце концов, запустив пилот мы сами собрали свой полноценный IoT стек, за неимением подходящей по нашим меркам альтернативы.
Однако, с недавнего времени в Beta версии доступна OpenBalena — жаль ее не было когда мы начинали делать проект.
Конечный результат и та платформа на основе Ansible + TICK + WireGuard, которую мы собрали самостоятельно нас полностью устраивает. Но на сегодняшний день, я бы порекомендовал внимательней посмотреть на Balena прежде чем пытаться собрать свою IoT платформу самим.
Потому что, в конечном итоге она умеет делать большую часть того, что мы делали, при этом OpenBalena бесплатна, а код открыт.
Оно уже умеет не просто рассылать обновления, но и VPN там уже вшит и заточен под использование в IoT среде.
А совсем недавно — они и вовсе выпустили свою Hardware, которая легко подключается в их экосистему.
Эй, а что с пропавшим скутером?
Итак скутер, "Ральф", бесследно исчез.
Мы сразу побежали смотреть карту в нашей "админке", с данными GPS метрик из InfluxDB.
Благодаря данным мониторинга, мы легко определили, что парковку скутер покинул около 21:00 прошлого дня, проехал где-то полчаса до какого-то района и был запаркован до 5и утра рядом с каким-то немецким домом.
После 5и утра данных мониторинга не поступало — это означало либо полный разряд дополнительной батареи, либо злоумышленник догадался-таки извлечь умную начинку из скутера.
Несмотря на это, по тому адресу, где находился скутер все же была вызвана полиция. Скутера там не оказалось.
Однако владелец дома тоже был этому удивлен, так как он действительно вчера вечером приехал на этом скутере из офиса домой.
Как выяснилось, один из сотрудников поддержки приехал рано утром и забрал скутер, увидев, что у него полностью разрядилась дополнительная батарея и повез его (пешком) на парковку. А дополнительная батарея вышла из строя из-за попадания влаги.
Мы украли скутер сами у себя. Не знаю, кстати, как и кто потом разруливал вопрос с делом в полиции, но мониторинг отработал отлично...