Вернуть пропавший скутер, или история одного IoT мониторинга

Год назад мы запустили пилотную версию промо проекта по децентрализованному прокату электроскутеров.

Изначально проект назывался Road-To-Barcelona, позже стал Road-To-Berlin (отсюда встречающиеся на скриншотах R2B), а в итоге и вовсе был назван xRide.

Основная идея проекта была в следующем: вместо того чтобы иметь централизованный сервис проката автомобилей или скутеров (речь пойдет о скутерах aka электро-мотоциклах, а не kickscooter/самокатах)
мы хотели сделать платформу для децентрализованной аренды. О сложностях с которыми мы столкнулись уже писали ранее.

Изначально проект ориентировался на автомобили, но из-за сроков, крайне долгих общений с производителями и огромного количества ограничений по безопасности, для пилота были выбраны электрические скутеры.

Пользователь устанавливал iOS или Android приложение на телефон, подходил к понравившемуся ему скутеру, после чего телефон и скутер устанавливали peer-to-peer соединение, происходил обмен ETH и пользователь мог начать поездку включив скутер через телефон. По завершении поездки так же можно было провести оплату поездки за счет эфира из кошелька пользователя на телефоне.

Помимо скутеров пользователь видел в приложении «умные зарядки», посетив которую пользователь мог сам сменить текущую батарею, если она разрядилась.

Так в целом и выглядел наш пилот, запущенный в сентябре прошлого года в двух городах Германии: Бонн и Берлин.

6s8cwvwf37qkdvcby3yoiyl8wyo.jpeg

И вот, однажды, в Бонне, ранним утром наша команда поддержки (находящаяся в локации для поддержания скутеров в работоспособном состоянии) была поднята по тревоге: один из скутеров бесследно исчез.
Как его найти и вернуть?

В этой статье я расскажу об этом, но для начала — о том как мы построили нашу собственную IoT платформу и как мы осуществляли мониторинг над ней.


Что и зачем мониторить: скутеры, инфраструктура, зарядки?

Итак, что же мы хотели мониторить в нашем проекте?
В первую очередь это сами скутеры — электроскутеры сами по себе довольно дорогие, нельзя запускать такой проект не будучи достаточно подготовленными, по возможности хочется собирать как можно больше информации о скутерах: об их местоположении, уровне заряда, итд.

Помимо этого, хотелось бы отслеживать состояние нашей собственной IT инфраструктуры — базы, сервисы и все что им необходимо для работы. Нужно было отслеживать и состояние «умных зарядок», на случай если они сломались или в них кончились полные батареи.


Скутеры

Что же из себя представляли наши скутеры и что мы хотели о них знать?
1dua3eem6jykxer_axhdqds2dko.jpeg

Первое, и самое существенное — GPS координаты, так как благодаря им мы можем понимать, где они находятся и куда двигаются.

Далее — заряд батареи, благодаря ему мы можем определять, что зарядка скутеров подходит к концу и отправить juicer’а или хотя бы предупредить пользователя.

Конечно, необходимо также проверять что происходит с нашими Hardware компонентами:


  • работает ли Bluetooth?
  • работает ли сам GPS модуль?
    • так же у нас была проблема с тем, что GPS мог отсылать неверные координаты и «залипать», а определить это можно было только на уровне дополнительных проверок на скутере,
      и нотифицировать поддержку как можно скорее для устранения проблемы

И последнее: проверки софтверной части, начиная с ОС и загрузки процессора, сети и диска, заканчивая уже более специфичными для нас проверками наших собственных модулей (jolocom, keycloak).


Hardware

2oinowseorswzayy7xixcxdl-2a.jpeg

Что же представляла наша «железная» часть?
Учитывая максимально сжатые сроки и необходимость быстрого прототипирования мы выбрали для себя максимально простой для реализации и подбора компонентов вариант — 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 серверу и держали возможность подключения к ним. Этот туннель и использовался для доставки обновлений.

guqkf5w8wyzrmcugnuzp8m-p95u.png

В теории, тот же туннель можно было использовать и для мониторинга, но такое подключение было сложнее и менее надежным чем простой push.


Облачные ресурсы

Последнее — необходимо отслеживать наши облачные сервисы и БД, так как для них мы используем Kubernetes, в идеале чтобы разворачивание мониторинга в кластере было максимально простым. В идеале — с использованием Helm, так как для деплоя, мы в большинстве случаев используем его. И, само собой, для мониторинга облака нужно использовать те же решения, что и для самих скутеров.


Дано

Фуф, вроде с описанием разобрались, давайте составим список того, что нам было нужно в итоге:


  • Быстрое решение, так как мониторить необходимо уже во время процесса разработки
  • Объем/количество — нужно множество метрик
  • Сбор логов обязателен
  • Надежность — данные критически важны для успеха запуска
  • Нельзя использовать pull модель — нужен push
  • Нужен единый мониторинг не только железа, но и облака

Конечная картинка выглядела примерно так

yz34djetqzrpicmbg-mdrb5rbhk.jpeg


Выбор стека

Итак, перед нами встал вопрос выбора стека для мониторинга.

В первую очередь, мы искали наиболее полноценное all-in-one решение, которое одновременно покрывало бы все наши требования, но при этом и было бы достаточно гибким чтобы подогнать его использование под наши нужды. Все-таки, у нас было много ограничений наложенных на нас железом, архитектурой и сроками.

Существует огромное множество решений для мониторинга,
начиная полноценными системами вроде Nagios, icinga или zabbix и заканчивая уже готовыми решениями по Fleet management.

ad3oztwklrkxbqgnrcbwax1aalo.jpeg

Изначально, последние казались идеальным для нас решением, но в одних не было полноценного мониторинга, в других были сильно урезаны возможности бесплатных версий, а третьи просто не покрывали наши «хотелки» или не были достаточно гибкими для подгонки под наши сценарии. Некоторые просто устарели.

После анализа какого-то количества подобных решений мы быстро пришли к выводу, что проще и быстрее будет собрать схожий стек самостоятельно. Да, это будет чуть сложнее чем разворачивание полностью готовой Fleet management платформы, но зато нам не придется идти на компромиссы.
Почти наверняка, во всем огромном обилии решений и есть уже готовое которое полностью бы нам подошло,
но в нашем случае значительно быстрее было собрать некий стек самостоятельно и подогнать «под себя», нежели тестировать готовые продукты.

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


(B)ELK?

Первое решение, которое реально рассматривалось — широко известный ELK стек.
На самом деле он должен называться BELK, ведь начинается все с Beats — https://www.elastic.co/what-is/elk-stack

n-_dmxyim19evsjhbgcp9it1axs.png

Конечно, 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.

o3m_eykqqh-d5s_a952vetetq9k.png

Я опишу все компоненты ниже более подробно, но в целом идея такая:


  • Telegraf — агент для сборки метрик
  • InfluxDB — база данных метрик
  • Kapacitor — обработчик метрик в реальном времени для алертинга
  • Chronograf — веб панель для визуализации

Для InfluxDB, Kapacitor и Chronograf есть официальные helm чарты, которые мы использовали для их разворачивания.

Надо отметить, что в свежей версии Influx 2.0 (beta) Kapacitor и Chronograf стали частью InfluxDB и больше не существуют отдельно


Telegraf

5kuja1hbbcbkrfw0bkyihl5iymq.png

Telegraf — это очень легковесный агент для сбора метрик на конечной машине.
Он умеет мониторить огромное количество всего, от nginx до
сервера minecraft.

У него есть ряд классных преимуществ:


  • Быстрый и легкий (написан на Go)
    • Ест минимальное количество ресурсов
  • Push метрик по умолчанию
  • Собирает все необходимые метрики
    • Системные метрики без каких-либо настроек
    • Хардварные метрики вроде информации с датчиков
    • Очень легко добавлять собственные метрики
  • Много плагинов «из коробки»
  • Собирает логи

Так как push метрик был для нас необходим, все остальные преимущества были более чем приятными дополнениями.

Сборка логов самим же агентом так же очень удобна, так как нет необходимости подключать дополнительные утилиты для тейлинга логов.
Influx предлагает максимально удобный опыт работы с логами если вы используете syslog.

Telegraf вообще отличный агент для сборки метрик, даже если вы не используете весь остальной ICK стек.
Многие скрещивают его и с ELK и с различными другими time-series базами по удобству, так как он умеет писать метрики почти куда угодно.


InfluxDB

59o5ibiot6o9epb2-1ffngmaqs0.png

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.

zxulqwvsed3yyvfpuvsao1zqano.png

Time-series баз немало, но наиболее подающая надежды — Victoria Metrics, у нее целый ряд плюсов:


  • Быстрая и легкая, по крайней мере по результатам бенчмарков
  • Есть кластерная версия, про которую сейчас даже есть хорошие отзывы
    • Она можешь шардироваться
  • Поддерживает InfluxDB протокол

Мы не собирались строить полностью кастомный стек на основе Victoria и основная надежда была на то, что мы сможем воспользоваться ею как drop-in заменой для InfluxDB.

К сожалению, это невозможно, несмотря на то, что поддерживается протокол InfluxDB, это работает только для записи метрик — «наружу» доступно только Prometheus API,
а значит натравить Chronograf на нее не получится.
Более того, для метрик поддерживаются только числовые значения (мы использовали строковые значения для кастомных метрик — об этом в разделе админка).
Очевидно, по той же причине VM не может хранить логи, как это делает Influx.

Также, надо отметить, что на момент поиска оптимального решения Victoria Metrics еще не была так популярна, документация была значительно меньше и функционал был слабее
(не припоминаю подробного описания кластерной версии и шардирования).


Выбор базы

В результате было принято решение, что для пилота мы все же ограничимся одиночной нодой InfluxDB.

Основных причин такого выбора было несколько:


  • Нам очень нравился функционал TICK стека целиком
  • Мы уже успели его развернуть и оно отлично работало
  • Сроки поджимали и не оставалось много времени тестировать другие варианты
  • У нас не ожидалось такой большой нагрузки

Скутеров у нас для первой фазы пилота было не так много, и тестирование во время разработки не выявило каких-либо проблем с производительностью.
Поэтому мы решили, что для данного проекта нам вполне хватит и одно ноды Influx без необходимости скалирования (cм выводы в конце).

Со стеком и базой решили — теперь об остальных компонентах TICK стека.


Kapacitor

megg1sq7umhu8tc_ambhqw-wv-w.png

Kapacitor — это часть TICK стека, сервис который может следить за попадающими в базу метриками в реальном времени и выполнять на основе правил различные действия.

Вообще он позиционируется как тул для потенциального отслеживания аномалий и машинного обучения (не уверен что эти функции востребованы),
но наиболее популярный кейс его использования более банален — это алертинг.

Так и мы его использовали для нотификаций. Мы настроили Slack оповещения о том, что тот или иной скутер отключился,
то же самое было сделано для умных зарядок и важных компонентов инфраструктуры.

bsb_xpzguzvrajsqqxusyxpjug8.png

Это позволяло быстро реагировать на проблемы, а также получать нотификации о том, что все пришло в норму.
Простой пример — сломалась или по какой-то причине разрядилась дополнительная батарея для питания нашей «коробочки»,
просто поставив новую мы должны через некоторое время получить нотификацию о восстановлении работоспособности скутера.

В Influx 2.0 Kapacitor стал частью DB


Chronograf

lfpnpb-zddwm0tvebuvfdyflct4.png

Я повидал много различных UI решений для мониторинга, но могу сказать, что по функционалу и UX ничто не сравнится с Chronograf’ом.

Начинали мы использовать TICK стек, как ни странно, с Grafan’ой в качестве веб-интерфейса.
Описывать ее функционал не буду, всем известны ее широкие возможности по настройке всего что угодно.

Однако, Grafana все же представляет из себя совсем универсальный инструмент, тогда как Chronograf в основном заточен под использование с Influx.
И конечно, благодаря этому, Chronograf может позволить себя куда более хитрый или удобный функционал.

Пожалуй, основное удобство работы с Chronograf в том, что вы можете смотреть внутренности вашей InfluxDB через Explore.

Казалось бы, в Grafana есть почти идентичный функционал, но в реальности настройка дашборда в Chronograf может осуществляться несколькими кликами мыши
(попутно смотря на визуализацию там же), тогда как в Grafana вам все равно рано или поздно придется редактировать JSON конфигурацию
(само собой Chronograf позволяет выгрузить ваши настроенные «руками» даши и редактировать в виде JSON если необходимо —, но мне никогда не приходилось их трогать после создания на UI).

В Kibana куда более богатые возможности по созданию дашбордов и контролов для них, но и UX для таких операций ну очень сложный.
Потребуется неплохо разобраться чтобы создать себе удобный дашборд. И хотя функционал дашбордов у Chronograf меньше, делать и настраивать их значительно проще.

Сами дашборды, помимо приятного визуального стиля, фактически ничем от дашбордов в Grafana или Kibana не отличаются:
ns9d50qhcenl1hahjtsf13eho9y.png

Так выглядит то самое окно запросов:
y-yn1zrkjco-szw9_z-_dqdsfoc.png

Важно отметить, помимо прочего, что зная типы полей в базе InfluxDB хронограф иногда сам может
автоматически помогать вам с написанием Query или выбором правильной функции агрегации типа mean.

Ну и конечно же, Chronograf максимально удобен для просмотра логов. Выглядит это так:

1dxwldaervkeo2ils7e64z9fve8.jpeg

По умолчанию 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.

Кстати, мы называли скутеры по именами персонажей из Симпсонов — так их было удобно отличать друг от друга

Да и вообще так было веселее. Постоянно звучали фразы вроде «Ребята — Смитерс умер!»

lyrbhd5kgtvkac2p2l1fvumvrcm.png


Строковые метрики

Важно, что InfluxDB позволяет хранить не только числовые значения, как в случае с Victoria Metrics.

Казалось бы, это не так важно — ведь если не считать логов, любые метрики можно хранить в виде чисел (всего лишь добавить маппинг для известных состояний — своего рода enum)?

В нашем случае, был как минимум один сценарий, когда строковые метрики были очень полезны.
Так уж получилось, что поставщик наших «умных зарядок» был сторонним, мы не имели никакого контроля над процессом разработки и информацией, которую эти зарядки могут поставлять.

В результате API зарядок было далеко от идеала, но основной проблемой было то, что мы не всегда могли понять их состояние.
Тут на помощь и пришел Influx. Мы просто-напросто записывали приходящий нам строковый status в поле базы InfluxDB без изменений.

Какое-то время туда попадали только значения вида «online» и «offline», на основе чего у нас в админке отображалась информация,
а в Slack приходили уведомления. Однако в какой-то момент туда стали попадать так же значения вида «disconnected».
Как позже выяснилось, этот статус высылался однократно после потери связи, если зарядка не могла установить соединение с сервером после какого-то количества попыток.

Таким образом, если бы мы использовали только фиксированный набор значений — мы могли бы не увидеть этих изменений в прошивке в нужный момент времени.

Да и вообще, строковые метрики дают куда больше возможностей для использования, записывать в них можно фактически любую информацию. Хотя, конечно, использовать этот инструмент тоже нужно аккуратно.

lupoz_-gq4t0l181skfetbnm2ny.png

Помимо обычных метрик, мы так же записывали в InfluxDB информацию о GPS локации. Это было невероятно удобно для мониторинга местонахождения скутеров в нашей админской панели.
Фактически, мы всегда знали где и какой скутер был в нужный нам момент времени.

Очень сильно нам это пригодилось, когда мы разыскивали скутер (смотри выводы в конце).


Мониторинг инфраструктуры

Помимо самих скутеров, нам было необходимо мониторить и всю нашу (довольно обширную) инфраструктуру.
Очень обобщенная архитектура выглядела примерно так:

kgkrmh0zqqfqcgftfe7lehhif-u.png

Если выделить чисто стек мониторинга, то он выглядит следующим образом:
u_jlhjthcj4mtm9ls1q6ftc1i2u.png

Из того что мы хотели бы проверять в облаке, это:


  • Базы данных
  • 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и-секунд

© Habrahabr.ru