Разработка Плагина Для Grafana: История Больших Успехов

Всем привет! Несколько месяцев назад мы запустили в производство наш новый open-source проект — плагин Grafana для мониторинга kubernetes, который мы назвали DevOpsProdigy KubeGraf .

Исходный код плагина доступен по адресу публичный репозиторий на GitHub .

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

Пойдем!



Часть 0 – вводная: как мы дошли до этого момента?

Идея написать собственный плагин для Grafana пришла к нам совершенно случайно.

Наша компания занимается сопровождением веб-проектов различного уровня сложности более 10 лет. За это время мы накопили большой объем экспертизы, интересных кейсов и опыта использования различных систем мониторинга.

И в какой-то момент мы спросили себя: «Есть ли волшебный инструмент для мониторинга Kubernetes, чтобы, как говорится, «поставил и забыл»Э».

Отраслевым стандартом мониторинга k8s, конечно, уже давно является Комбинация Прометей + Графана.

А в качестве готовых решений для этого стека имеется большой набор разного рода инструментов: prometheus-operator, набор дашбордов kubernetes-mixin, grafana-kubernetes-app. Плагин grafana-kubernetes-app показался нам наиболее интересным вариантом, но он не поддерживается уже больше года и, более того, не может работать с новыми версиями node-exporter и kube-state-metrics. И в какой-то момент мы решили: «А не стоит ли нам принять собственное решениеЭ» Какие идеи мы решили реализовать в нашем плагине:

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

    ;

  • визуализация связей типа «развертывание — сервис (+порты)».

  • визуализация распределения приложений кластера по узлам кластера.

  • сбор метрик и информации из нескольких источников: Prometheus и API-сервера k8s.
  • мониторинг как инфраструктурной части (использование процессорного времени, памяти, дисковой подсистемы, сети), так и логики приложения — работоспособность подов, количество доступных реплик, информация о прохождении тестов живучести/готовности.



Часть 1. Что такое «плагин Grafana»?

С технической точки зрения плагин для Grafana представляет собой контроллер angular, который хранится в каталоге данных Grafana ( /вар/графана/плагины/ /dist/module.js ) и может быть загружен как модуль SystemJS. Также в этом каталоге должен находиться файл плагина.

json, содержащий всю метаинформацию о вашем плагине: имя, версию, тип плагина, ссылки на репозиторий/сайт/лицензию, зависимости и так далее.



Разработка плагина для Grafana: история больших успехов

модуль.

ts

Разработка плагина для Grafana: история больших успехов

плагин.

json Как вы можете видеть на скриншоте, мы указали плагин.

type = app. Потому что плагины для Grafana могут быть трёх типов: панель : самый распространенный тип плагина — это панель для визуализации каких-либо метрик, используемая для построения различных дашбордов.

источник данных : плагин-коннектор к какому-либо источнику данных (например, источнику данных Prometheus, источнику данных ClickHouse, источнику данных ElasticSearch).

приложение : Плагин, который позволяет вам создавать собственное внешнее приложение внутри Grafana, создавать собственные html-страницы и вручную получать доступ к источнику данных для визуализации различных данных.

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



Разработка плагина для Grafana: история больших успехов

Пример зависимостей плагина с type=app .

В качестве языка программирования вы можете использовать как JavaScript, так и TypeScript (мы выбрали именно его).

Подготовка к плагинам hello-world любого типа, который вы можете найди ссылку : в этом репозитории содержится большое количество starter-паков (есть даже экспериментальный пример плагина на React) с предустановленными и настроенными сборщиками.



Часть 2: подготовка местной среды

Для работы над плагином нам естественно понадобится кластер kubernetes со всеми предустановленными инструментами: prometheus, node-exporter, kube-state-metrics, grafana. Среда должна быть настроена быстро, легко и естественно, а для обеспечения горячей перезагрузки каталог данных Grafana должен быть смонтирован непосредственно с машины разработчика.

Самый удобный, на наш взгляд, способ локальной работы с kubernetes — это миникуб .

Следующим шагом будет установка комбинации Prometheus + Grafana с помощью prometheus-operator. В Эта статья Подробно описан процесс установки prometheus-operator на миникубе.

Чтобы включить сохранение, необходимо установить параметр настойчивость: правда в файлеcharts/grafana/values.yaml добавьте свои собственные PV и PVC и укажите их в параметре persistence.existingClaim Наш окончательный сценарий запуска миникуба выглядит так:

  
  
  
   

minikube start --kubernetes-version=v1.13.4 --memory=4096 --bootstrapper=kubeadm --extra-config=scheduler.address=0.0.0.0 --extra-config=controller-manager.address=0.0.0.0 minikube mount /home/sergeisporyshev/Projects/Grafana:/var/grafana --gid=472 --uid=472 --9p-version=9p2000.L



Часть 3: фактическое развитие

Объектная модель Готовясь к реализации плагина, мы решили описать все основные сущности Kubernetes, с которыми будем работать, в виде классов TypeScript: pod, Deployment, daemonset, statefulset, job, cronjob, service, node, namespace. Каждый из этих классов наследуется от общего класса BaseModel, который описывает конструктор, деструктор, методы обновления и переключения видимости.

Каждый из классов описывает вложенные связи с другими сущностями, например список модулей для сущности типа развертывание.



import {Pod} from ".

/pod"; import {Service} from ".

/service"; import {BaseModel} from '.

/traits/baseModel'; export class Deployment extends BaseModel{ pods: Array<Pod>; services: Array<Service>; constructor(data: any){ super(data); this.pods = []; this.services = []; } }

С помощью геттеров и сеттеров мы можем отображать или задавать нужные нам метрики сущности в удобной и читаемой форме.

Например, форматированный вывод выделяемых узлов процессора:

get cpuAllocatableFormatted(){ let cpu = this.data.status.allocatable.cpu; if(cpu.indexOf('m') > -1){ cpu = parseInt(cpu)/1000; } return cpu; }

Страницы Список всех страниц нашего плагина изначально описан в нашем pluing.json в разделе зависимостей:

Разработка плагина для Grafana: история больших успехов

В блоке для каждой страницы мы должны указать ИМЯ СТРАНИЦЫ (оно потом преобразуется в слаг, по которому эта страница будет доступна); название компонента, отвечающего за работу этой страницы (список компонентов экспортируется в модуль.

ts); указание роли пользователя, для которого доступна работа с данной страницей, и настройки навигации по боковой панели.

В компоненте, отвечающем за работу страницы, мы должны задать templateUrl, передав туда путь к html-файлу с разметкой.

Внутри контроллера посредством внедрения зависимостей мы можем получить доступ к двум важным сервисам Angular:

  • backendSrv — сервис, обеспечивающий взаимодействие с API-сервером Grafana;
  • datasourceSrv — сервис, обеспечивающий локальное взаимодействие со всеми источниками данных, установленными в вашей Grafana (например, метод .

    getAll() — возвращает список всех установленных источников данных; .

    get( ) — возвращает объект экземпляра определенного источника данных.



Разработка плагина для Grafana: история больших успехов



Разработка плагина для Grafana: история больших успехов



Разработка плагина для Grafana: история больших успехов



Часть 4: источник данных

С точки зрения Grafana, datasource — это точно такой же плагин, как и все остальные: у него есть своя точка входа Module.js, есть файл с метаинформацией плагин.

json. При разработке плагина с type=app мы можем взаимодействовать как с существующими источниками данных (например, prometheus-datasource), так и со своими собственными, которые мы можем хранить непосредственно в каталоге плагина (dist/datasource/*) или устанавливать как зависимость.

В нашем случае источник данных поставляется с кодом плагина.

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

В плагине KubeGraf с точки зрения пользовательского интерфейса источником данных является экземпляр кластера kubernetes, реализующий следующие возможности (исходный код доступен связь ):

  • сбор данных с api-сервера k8s (получение списка пространств имен, развертываний.

    )

  • проксирование запросов к prometheus-datasource (который выбирается в настройках плагина для каждого конкретного кластера) и форматирование ответов для использования данных как на статических страницах, так и в дашбордах.

  • обновление данных на статических страницах плагина (с заданной частотой обновления).

  • обработка запросов для создания листа-шаблона в grafana-dashboards (метод metriFindQuery())


Разработка плагина для Grafana: история больших успехов



Разработка плагина для Grafana: история больших успехов



Разработка плагина для Grafana: история больших успехов

  • проверка соединения с финальным кластером k8s.


testDatasource(){ let url = '/api/v1/namespaces'; let _url = this.url; if(this.accessViaToken) _url += '/__proxy'; _url += url; return this.backendSrv.datasourceRequest({ url: _url, method: "GET", headers: {"Content-Type": 'application/json'} }) .

then(response => { if (response.status === 200) { return {status: "success", message: "Data source is OK", title: "Success"}; }else{ return {status: "error", message: "Data source is not OK", title: "Error"}; } }, error => { return {status: "error", message: "Data source is not OK", title: "Error"}; }) }

Отдельный интересный момент, на наш взгляд, — реализация механизма аутентификации и авторизации источника данных.

Обычно по умолчанию мы можем использовать встроенный компонент DatasourceHttpSettings компонента Grafana для настройки доступа к конечному источнику данных.

Используя этот компонент, мы можем настроить доступ к источнику данных http, указав URL-адрес и базовые настройки аутентификации/авторизации: логин-пароль или client-cert/client-key. Чтобы реализовать возможность настройки доступа с помощью токена-носителя (фактический стандарт для k8s), нам пришлось провести небольшую доработку.

Для решения этой проблемы можно использовать встроенный в Grafana механизм «Plugin Routes» (подробнее на сайте).

официальная страница документации ).

В настройках нашего источника данных мы можем объявить набор правил маршрутизации, которые будут обрабатываться прокси-сервером Grafana. Например, для каждого отдельного эндпоинта можно задать заголовки или урлы с возможностью шаблонизации, данные для которых можно брать из полей jsonData и secureJsonData (для хранения паролей или токенов в зашифрованном виде).

В нашем примере запросы типа /__proxy/api/v1/пространства имен будет проксировано на URL-адрес формы /api/v1/namespaces с заголовком Authorization: Bearer.

Разработка плагина для Grafana: история больших успехов



Разработка плагина для Grafana: история больших успехов

Естественно, для работы с API-сервером k8s нам понадобится пользователь с доступом только для чтения, манифесты для создания которого вы также можете найти в исходный код плагина .



Часть 5: выпуск



Разработка плагина для Grafana: история больших успехов

Написав собственный плагин Grafana, вы, естественно, захотите сделать его общедоступным.

В Grafana это библиотека плагинов, доступная здесь.

grafana.com/grafana/plugins Для того, чтобы ваш плагин был доступен в официальном магазине, вам необходимо сделать пиар в этот репозиторий добавив такой контент в файл repo.json:

Разработка плагина для Grafana: история больших успехов

где версия — это версия вашего плагина, URL — это ссылка на репозиторий, а коммит — это хеш коммита, для которого будет доступна конкретная версия плагина.

И на выходе вы увидите чудесную картинку типа:

Разработка плагина для Grafana: история больших успехов

Данные для него будут автоматически получены из ваших Readme.md, Changelog.md и файла plugin.json с описанием плагина.



Часть 6: вместо выводов

Мы не прекратили разработку нашего плагина после его выпуска.

И сейчас мы работаем над корректным мониторингом использования ресурсов узлов кластера, внедряем новые функции для улучшения UX, а также собираем большое количество отзывов, полученных после установки плагина как от наших клиентов, так и от людей на GitHub (если вы оставите ваш вопрос или запрос на вытягивание, я буду очень рад :-)).

Надеемся, что эта статья поможет вам разобраться в таком замечательном инструменте, как Grafana, и, возможно, написать свой плагин.

Спасибо!) Теги: #github #DIY или Сделай сам #it инфраструктура #открытый исходный код #Kubernetes #разработка #Управление продуктом #мониторинг #k8s #itsumma #Grafana #plugin

Вместе с данным постом часто просматривают: