Vývoj doplnku pre Grafana: história veľkých záberov

Ahojte všetci! Pred pár mesiacmi sme spustili do produkcie náš nový open-source projekt - plugin Grafana na monitorovanie kubernetes, ktorý sme nazvali DevOpsProdigy KubeGraf. Zdrojový kód pluginu je dostupný na verejné úložisko na GitHub. A v tomto článku sa s vami chceme podeliť o príbeh, ako sme plugin vytvorili, aké nástroje sme použili a na aké úskalia sme narazili počas procesu vývoja. Poďme!

0. časť – úvodná: ako sme sa dostali k tomuto bodu?

Nápad napísať vlastný plugin pre Grafan k nám prišiel celkom náhodou. Naša spoločnosť už viac ako 10 rokov monitoruje webové projekty rôznych úrovní zložitosti. Za tento čas sme nazbierali veľké množstvo odborných znalostí, zaujímavých prípadov a skúseností s používaním rôznych monitorovacích systémov. A v určitom momente sme sa sami seba spýtali: „Existuje magický nástroj na monitorovanie Kubernetes, aby, ako sa hovorí, „nastavil a zabudol“?“.. Priemyselným štandardom pre monitorovanie k8 je, samozrejme, už dlho Kombinácia Prometheus + Grafana. A ako hotové riešenia pre tento zásobník existuje veľká sada rôznych druhov nástrojov: prometheus-operator, sada dashboardov kubernetes-mixin, grafana-kubernetes-app.

Ako najzaujímavejšia možnosť sa nám zdal plugin grafana-kubernetes-app, ktorý však už viac ako rok nie je podporovaný a navyše nevie pracovať s novými verziami node-exporter a kube-state-metrics. A v určitom bode sme sa rozhodli: "Nemali by sme sa rozhodnúť sami?"

Aké nápady sme sa rozhodli implementovať do nášho pluginu:

  • vizualizácia „aplikačnej mapy“: pohodlná prezentácia aplikácií v klastri, zoskupených podľa menných priestorov, nasadení...;
  • vizualizácia spojení ako „nasadenie – služba (+porty)“.
  • vizualizácia distribúcie klastrových aplikácií cez uzly klastra.
  • zber metrík a informácií z niekoľkých zdrojov: server Prometheus a k8s api.
  • monitorovanie ako časti infraštruktúry (využitie CPU času, pamäte, diskového subsystému, siete), tak aplikačnej logiky - health-status pods, počet dostupných replík, informácie o absolvovaní testov životnosti/pripravenosti.

Časť 1: Čo je to „Grafana plugin“?

Z technického hľadiska je plugin pre Grafana uhlový ovládač, ktorý je uložený v adresári údajov Grafana (/var/grafana/plugins/ /dist/module.js) a možno ho načítať ako modul SystemJS. V tomto adresári by mal byť aj súbor plugin.json obsahujúci všetky meta informácie o vašom plugine: názov, verzia, typ pluginu, odkazy na úložisko/stránku/licenciu, závislosti atď.

Vývoj doplnku pre Grafana: história veľkých záberov
modul.ts

Vývoj doplnku pre Grafana: história veľkých záberov
plugin.json

Ako môžete vidieť na snímke obrazovky, zadali sme plugin.type = app. Pretože pluginy pre Grafana môžu byť troch typov:

panel: najbežnejší typ pluginu - je to panel na vizualizáciu akýchkoľvek metrík, ktorý sa používa na zostavenie rôznych dashboardov.
Zdroj dát: konektor doplnku k nejakému zdroju údajov (napríklad Prometheus-datasource, ClickHouse-datasource, ElasticSearch-datasource).
aplikácie: Plugin, ktorý vám umožňuje vytvoriť si vlastnú frontendovú aplikáciu v Grafane, vytvoriť si vlastné html stránky a manuálne pristupovať k zdroju údajov na vizualizáciu rôznych údajov. Ako závislosti možno použiť aj pluginy iných typov (zdroj údajov, panel) a rôzne dashboardy.

Vývoj doplnku pre Grafana: história veľkých záberov
Príklad závislostí doplnkov s type=app.

Ako programovací jazyk môžete použiť JavaScript aj TypeScript (vybrali sme si ho). Prípravy na hello-world pluginy akéhokoľvek typu nájsť odkaz: toto úložisko obsahuje veľké množstvo štartovacích balíčkov (v Reacte je dokonca experimentálny príklad pluginu) s predinštalovanými a nakonfigurovanými buildermi.

Časť 2: Príprava miestneho prostredia

Na prácu na doplnku prirodzene potrebujeme klaster kubernetes so všetkými predinštalovanými nástrojmi: prometheus, node-exporter, kube-state-metrics, grafana. Prostredie by malo byť nastavené rýchlo, jednoducho a prirodzene a aby sa zabezpečilo rýchle opätovné načítanie, mal by byť dátový adresár Grafana pripojený priamo z vývojárskeho stroja.

Najpohodlnejší spôsob, ako pracovať lokálne s kubernetes, je podľa nášho názoru minikube. Ďalším krokom je inštalácia kombinácie Prometheus + Grafana pomocou prometheus-operátor. IN tento článok Proces inštalácie prometheus-operátora na minikube je podrobne popísaný. Ak chcete povoliť vytrvalosť, musíte nastaviť parameter vytrvalosť: pravda v súbore charts/grafana/values.yaml pridajte svoje vlastné PV a PVC a špecifikujte ich v parametri persistence.existingClaim

Náš posledný spúšťací skript minikube vyzerá takto:

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

Časť 3: skutočný vývoj

Objektový model

V rámci prípravy na implementáciu pluginu sme sa rozhodli popísať všetky základné entity Kubernetes, s ktorými budeme pracovať vo forme tried TypeScript: pod, deployment, daemonset, statefulset, job, cronjob, service, node, namespace. Každá z týchto tried dedí zo spoločnej triedy BaseModel, ktorá popisuje konštruktor, deštruktor, metódy aktualizácie a prepínania viditeľnosti. Každá z tried popisuje vnorené vzťahy s inými entitami, napríklad zoznam modulov pre entitu typu nasadenia.

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 = [];
   }
}

Pomocou getterov a nastavovačov vieme zobraziť alebo nastaviť potrebné metriky entity v pohodlnej a čitateľnej forme. Napríklad formátovaný výstup alokovateľných uzlov CPU:

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

stránky

Zoznam všetkých našich stránok doplnkov je na začiatku popísaný v našom súbore pluing.json v sekcii závislostí:

Vývoj doplnku pre Grafana: história veľkých záberov

V bloku pre každú stránku musíme uviesť NÁZOV STRÁNKY (ten sa potom skonvertuje na slug, pomocou ktorého bude táto stránka prístupná); názov komponentu zodpovedného za fungovanie tejto stránky (zoznam komponentov je exportovaný do module.ts); označujúce rolu používateľa, pre ktorú je práca s touto stránkou dostupná, a nastavenia navigácie pre bočný panel.

V komponente zodpovednom za fungovanie stránky musíme nastaviť templateUrl a odovzdať tam cestu k súboru html s označením. Vo vnútri ovládača môžeme prostredníctvom vstrekovania závislostí pristupovať až k 2 dôležitým uhlovým službám:

  • backendSrv - služba, ktorá poskytuje interakciu so serverom Grafana API;
  • datasourceSrv – služba, ktorá poskytuje lokálnu interakciu so všetkými zdrojmi údajov nainštalovanými vo vašej Grafane (napríklad metóda .getAll() – vracia zoznam všetkých nainštalovaných zdrojov údajov; .get( ) - vráti objekt inštancie konkrétneho zdroja údajov.

Vývoj doplnku pre Grafana: história veľkých záberov

Vývoj doplnku pre Grafana: história veľkých záberov

Vývoj doplnku pre Grafana: história veľkých záberov

Časť 4: Zdroj údajov

Z pohľadu Grafany je datasource úplne rovnaký plugin ako všetky ostatné: má svoj vlastný vstupný bod module.js, existuje súbor s meta informáciami plugin.json. Pri vývoji doplnku s type = app môžeme interagovať s existujúcimi zdrojmi údajov (napríklad prometheus-datasource) aj s našimi vlastnými, ktoré môžeme uložiť priamo do adresára pluginu (dist/datasource/*) alebo nainštalovať ako závislosť. V našom prípade sa zdroj údajov dodáva s kódom doplnku. Je tiež potrebné mať šablónu config.html a radič ConfigCtrl, ktorý sa použije na konfiguračnú stránku inštancie zdroja údajov a radič zdroja údajov, ktorý implementuje logiku vášho zdroja údajov.

V doplnku KubeGraf je z pohľadu používateľského rozhrania zdrojom údajov inštancia klastra kubernetes, ktorý implementuje nasledujúce funkcie (zdrojový kód je k dispozícii по ссылке):

  • zbieranie údajov z k8s api-serveru (získanie zoznamu menných priestorov, nasadení...)
  • proxy požiadavky na prometheus-datasource (ktorý je vybraný v nastaveniach pluginu pre každý konkrétny klaster) a formátovanie odpovedí na použitie údajov na statických stránkach aj v dashboardoch.
  • aktualizácia údajov na stránkach statických doplnkov (s nastavenou obnovovacou frekvenciou).
  • spracovanie dopytov na generovanie šablóny v grafana-dashboardoch (metóda metriFindQuery())

Vývoj doplnku pre Grafana: história veľkých záberov

Vývoj doplnku pre Grafana: história veľkých záberov

Vývoj doplnku pre Grafana: história veľkých záberov

  • test spojenia s finálnym klastrom 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"};
       })
}

Samostatným zaujímavým bodom je podľa nášho názoru implementácia autentifikačného a autorizačného mechanizmu pre zdroj údajov. Zvyčajne môžeme použiť vstavaný komponent Grafana datasourceHttpSettings na konfiguráciu prístupu ku konečnému zdroju údajov. Pomocou tohto komponentu môžeme nakonfigurovať prístup k http zdroju údajov zadaním adresy URL a základných nastavení autentifikácie/autorizácie: login-password, alebo client-cert/client-key. Aby sme implementovali možnosť konfigurácie prístupu pomocou nosného tokenu (de facto štandard pre k8), museli sme urobiť malé úpravy.

Na vyriešenie tohto problému môžete použiť vstavaný mechanizmus Grafana „Plugin Routes“ (viac podrobností na oficiálna dokumentačná stránka). V nastaveniach nášho dátového zdroja môžeme deklarovať sadu smerovacích pravidiel, ktoré spracuje grafana proxy server. Napríklad pre každý jednotlivý koncový bod je možné nastaviť hlavičky alebo url s možnosťou šablónovania, pre ktoré je možné dáta preberať z polí jsonData a secureJsonData (na ukladanie hesiel alebo tokenov v zašifrovanej podobe). V našom príklade sú otázky ako /__proxy/api/v1/namespaces bude presmerovaný na adresu URL formulára
/api/v8/namespaces s hlavičkou Authorization: Bearer.

Vývoj doplnku pre Grafana: história veľkých záberov

Vývoj doplnku pre Grafana: história veľkých záberov

Na prácu so serverom k8s api samozrejme potrebujeme používateľa s prístupom len na čítanie, manifesty na vytváranie, ktoré nájdete aj v zdrojový kód pluginu.

Časť 5: uvoľnenie

Vývoj doplnku pre Grafana: história veľkých záberov

Keď si napíšete svoj vlastný doplnok Grafana, prirodzene ho budete chcieť sprístupniť verejnosti. V Grafane je to knižnica doplnkov dostupných tu grafana.com/grafana/plugins

Aby bol váš plugin dostupný v oficiálnom obchode, musíte urobiť PR toto úložiskopridaním obsahu, ako je tento, do súboru repo.json:

Vývoj doplnku pre Grafana: história veľkých záberov

kde version je verzia vášho doplnku, url je odkaz na úložisko a commit je hash odovzdania, pre ktorý bude k dispozícii konkrétna verzia doplnku.

A na výstupe uvidíte nádherný obrázok ako:

Vývoj doplnku pre Grafana: história veľkých záberov

Údaje preň budú automaticky získané z vášho súboru Readme.md, Changelog.md a súboru plugin.json s popisom pluginu.

Časť 6: namiesto záverov

Po vydaní sme neprestali vyvíjať náš plugin. A teraz pracujeme na správnom monitorovaní využívania zdrojov uzlov klastra, zavádzaní nových funkcií na zlepšenie UX a tiež zbierame veľké množstvo spätnej väzby získanej po inštalácii pluginu od našich klientov aj od ľudí na GitHub (ak odídete váš problém alebo žiadosť o stiahnutie, budem veľmi rád :)

Dúfame, že vám tento článok pomôže pochopiť taký úžasný nástroj, akým je Grafana, a možno si napíšete svoj vlastný doplnok.

Ďakujem!)

Zdroj: hab.com

Pridať komentár