Tere kĂ”ik! Mitme kuu eest kĂ€ivitasime tootmisse meie uue avatud lĂ€htekoodiga projekti â Grafana plugina, mis on mĂ”eldud Kubernetes'e jĂ€lgimiseks ja mille nimeks saime . Plugina lĂ€htekood on saadaval . Selles artiklis soovime jagada teiega lugu sellest, kuidas me plugina lĂ”ime, milliseid tööriistu kasutasime ja milliste takistustega arendamise kĂ€igus silmitsi seisisime. Alustame!
Osa 0 â sissejuhatus: kuidas me niimoodi siia jĂ”udsime?
Idee kirjutada oma plugina Grafanale tuli meile tĂ€iesti juhuslikult. Meie ettevĂ”te on juba ĂŒle 10 aasta tegelenud erineva keerukusega veebiprojektide monitooringuga. Selle aja jooksul oleme kogunud suure hulga teadmisi, huvitavaid nĂ€iteid ja kogemusi erinevate monitooringusĂŒsteemide kasutamisel. Ja mingil hetkel kĂŒsisime endalt: "Kas on olemas maagiline tööriist Kubernetes'e monitooringuks, et, nagu öeldakse, 'pane ja unusta'"?.. K8s monitooringu standardiks on loomulikult ammu juba kombinatsioon Prometheus + Grafana. Ja antud tehnoloogiakomplekti jaoks on olemas suur hulk erinevaid lahendusi: prometheus-operator, kubernetes-mixin dashi komplekt, grafana-kubernetes-app.
Meie jaoks tundus kÔige huvitavam variant olema plugina grafana-kubernetes-app, kuid seda ei toetata enam rohkem kui aasta ja lisaks ei suuda see töötada uute node-exporteri ja kube-state-metrics'e versioonidega. Ja mingil hetkel otsustasime: "Kas me ei peaks tegema oma lahenduse?"
Milliseid ideid otsustasime oma plugina ellu viia:
- rakenduste "rakenduse kaart": mugav rakenduste esitamine klassis, rĂŒhmitatuna namespace'i ja deployment'ite kaupaâŠ;
- seoste visualiseerimine tĂŒĂŒbis "deployment â teenus (+ports)".
- rakenduste jaotuse visualiseerimine klassi nod'ides.
- mÔÔdikute ja teabe kogumine mitmest allikast: Prometheus ja k8s api server.
- monitoring nii infrastruktuuri osana (kasutatud protsessori aega, mĂ€lu, diskiallikat, vĂ”rku) kui ka rakenduste loogika â pod'ide health-status, saadaval olevate replikate arv, teave liveness/readyness testide lĂ€bimise kohta.
Osa 1: Mis on "Grafana plugin"?
Tehnilisest vaatepunktist on Grafana plugin angular-kontroller, mis asub Grafana data-kaustas (/var/grafana/plugins/<your_plugin_name>/dist/module.js) ja saab laadida SystemJS-moodulina. Samuti peaks selles kaustas olema fail plugin.json, mis sisaldab kogu metaandmeid teie plugina kohta: nimi, versioon, plugina tĂŒĂŒp, lingid hoidla/veebi/ litsentsi, sĂ”ltuvused jne.

module.ts

plugin.json
Kuidas on pildil nĂ€ha, oleme mÀÀranud plugin.type = app. Sest Grafana pluginad vĂ”ivad olla kolme tĂŒĂŒpi:
paneel: kĂ”ige levinum pluginatĂŒĂŒp â esindab paneeli, mis visualiseerib teatud nĂ€itajaid, ja kasutatakse erinevate juhtpaneelide loomiseks.
andmeallikaks: andmeallika konnektoriplaan (nt Prometheus-datasource, ClickHouse-datasource, ElasticSearch-datasource).
app: plugin, mis vĂ”imaldab teil luua omaenda front-end rakenduse Grafana-s, luua oma HTML-lehti ja manuaalselt pöörduda andmeallika poole erinevate andmete visualiseerimiseks. Samuti vĂ”ivad sĂ”ltuvustena kasutada teisi tĂŒĂŒpe pluginaid (datasource, panel) ja erinevaid juhtpaneele.

Pluginate sĂ”ltuvuste nĂ€idis tĂŒĂŒbi = rakendus.
Programmeerimiskeelena saab kasutada nii JavaScripti kui ka TypeScripti (meie valik langes viimasele). Igasuguste pluginatĂŒĂŒbi hello-world malli leiate : selles hoidlas on suur hulk starter-packe (seal on isegi eksperimentaalne Reacti plugin) eelinstallitud ja konfigureeritud ehitajatega.
Osa 2: kohaliku keskkonna ettevalmistamine
Pluginiga töötamiseks on meil loomulikult vaja kubernetes-klĂ”ster kĂ”igi eelinstallitud tööriistadega: prometheus, node-exporter, kube-state-metrics, grafana. Keskkond peab olema kiiresti, lihtsalt ja mugavalt seadistatud ning hot-reloadi tagamiseks peab Grafana andmekaust olema otse arendaja masina kĂŒlge monteeritud.
Meie arvates on mugavaim viis kohaliku töö tegemiseks kubernetesega . JĂ€rgmise sammu kĂ€igus installime Prometheus + Grafana komplekti prometheus-operatori abil. Protsessi prometheus-operatori installimiseks minikubes on kirjeldatud ĂŒksikasjalikult. PĂŒsivuse lubamiseks tuleb seadistada parameeter persistence: true failis charts/grafana/values.yaml, lisada oma PV ja PVC ning viidata neile parameetriga persistence.existingClaim.
LÔppkokkuvÔttes nÀeb meie minikube'i kÀivitus skript vÀlja selline:
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.LOsa 3: arendustöö
Objekti mudel
Plugin'i rakendamiseks valmistudes otsustasime kirjeldada kĂ”iki Kubernetes'i pĂ”hielemente, millega me töötame, TypeScript'i klasside kujul: pod, deployment, daemonset, statefulset, job, cronjob, service, node, namespace. IgaĂŒks neist klassidest pĂ€rineb ĂŒhest baasklassist BaseModel, kus on kirjeldatud konstruktor, deconstructor, meetodid uuendamiseks ja nĂ€htavuse muutmiseks. Igas klassis on kirjas loetelud, mis on seotud teiste elementidega, nĂ€iteks deployment'i tĂŒĂŒpi elemendi pod'ide nimekiri.
import {Pod} from "./pod";
import {Service} from "./service";
import {BaseModel} from './traits/baseModel';
export class Deployment extends BaseModel{
pods: Array;
services: Array;
constructor(data: any){
super(data);
this.pods = [];
this.services = [];
}
}Getter'ite ja setter'ite abil saame nÀidata vÔi mÀÀrata vajalikud elemendi mÔÔdikud mugavas ja arusaadavas vormingus. NÀiteks vormindatud vÀljund allocatable cpu nod'ile:
get cpuAllocatableFormatted(){
let cpu = this.data.status.allocatable.cpu;
if(cpu.indexOf('m') > -1){
cpu = parseInt(cpu)/1000;
}
return cpu;
}Lehed
Meie plugina kÔigi lehtede loetelu on algselt kirjeldatud meie pluing.json-is sÔltuvuste jaos:

Iga lehe jaotises peame nĂ€itama LEHE PEALKIRJA (see konverteeritakse hiljem slug'iks, mille kaudu see leht on saadaval); komponendi nimetuse, mis vastutab selle lehe toimimise eest (komponentide nimekiri eksporditakse module.ts); kasutaja rolli mÀÀramine, kellele see leht on saadaval ja kĂŒlgriba navigeerimise seadistamine.
Lehe töötluse komponendis peame seadma templateUrl, edastades sinna html-faili tee, kus on mÀrgistamine. Kontrolleris saame dependency injection'i kaudu ligipÀÀsu kahele olulisele angular-teenusele:
- backendSrv â teenus, mis tagab suhtlemise grafana api-serveriga;
- datasourceSrv â teenus, mis tagab kohaliku suhtluse kĂ”igi teie Grafanas installitud andmeallikatega (nĂ€iteks meetod .getAll() â tagastab kĂ”igi installitud andmeallikate nimekirja; .get(<nаme>) â tagastab kindla andmeallika objekti-instantsse.



Osa 4: andmeallikas
Grafana vaatepunktist on andmeallikas tĂ€pselt samasugune plugin nagu kĂ”ik teised: sellel on oma sissejuhatus module.js, ning metainfo fail plugin.json. Rakenduse tĂŒĂŒbi plugina arendamisel saame suhelda nii olemasolevate andmeallikatega (nĂ€iteks prometheus-datasource) kui ka meie enda andmeallikatega, mida saame hoida otse plugina kataloogis (dist/datasource/*) vĂ”i installida sĂ”ltuvusena. Meie puhul tuleb andmeallikas koos plugina koodiga. Samuti on vajalik config.html malli olemasolu ja ConfigCtrl kontroller, mida kasutatakse andmeallika eksemplari konfigureerimise lehe jaoks ning andmeallika kontroller, mille sees toimub teie andmeallika toimimisloogika.
KubeGraf plugina puhul, kasutajaliidese vaatepunktist, on andmeallikas kubernetes klastrite eksemplar, millel on jÀrgmised vÔimalused (allikakood on saadaval ):
- andmete hankimine k8s api-server'ist (namespace'ide, deployment'ide jne loetelu saamineâŠ)
- proksimise pĂ€ringud prometheus-datasource'is (mida valitakse plugina seadetes iga konkreetse rĂŒhma jaoks) ja vastuste vormindamine andmete kasutamiseks nii staatilistes lehtedes kui ka armatuurlaudades.
- andmete uuendamine plugina staatilistes lehtedes (kindlaksmÀÀratud uuendamise ajaga).
- pÀringute töötlemine template-loendi koostamiseks grafana-dashboards'is (meetod .metriFindQuery())



- ĂŒhenduse testimine lĂ”pliku k8s-rĂŒhma suhtes.
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: "Andmeallikas on OK", title: "Edulugu"};
}else{
return {status: "error", message: "Andmeallikas ei ole OK", title: "Viga"};
}
}, error => {
return {status: "error", message: "Andmeallikas ei ole OK", title: "Viga"};
})
}Meie arvates on eriliselt huvitav punkt andmeallika autentimise ja autoriseerimise mehhanismi rakendamine. TĂŒĂŒpiliselt saame andmeallika lĂ”pp-punkti ligipÀÀsu konfigureerimiseks kasutada Grafana sisseehitatud komponenti â datasourceHttpSettings. Selle komponendi abil saame seadistada ligipÀÀsu http-andmeallikale, mÀÀrates url ja autentimise/autoriseerimise pĂ”hiseaded: kasutajanimi-parool vĂ”i client-cert/client-key. Bearer-tunnuse (de facto standard k8s-i jaoks) abil ligipÀÀsu seadistamine nĂ”udis natuke âkeemiatâ.
Selle ĂŒlesande tĂ€itmiseks vĂ”ime kasutada Grafana sisseehitatud mehhanismi âPlugin Routesâ (lisainfot leiate ). Andmeallika seadistustes saame deklareerida reeglite kogumi, mida töötleb Grafana proxy-server. NĂ€iteks iga eraldi lĂ”pp-punkti jaoks on vĂ”imalus mÀÀrata pĂ€iseid vĂ”i url-e ĆĄabloonimise vĂ”imalusega, mille andmed vĂ”ivad pĂ€rineda jsonData ja secureJsonData vĂ€ljadest (paroolide vĂ”i tokenite salvestamiseks krĂŒpteeritud kujul). Meie nĂ€ites sarnased pĂ€ringud /__proxy/api/v1/namespaces proksitakse url vormis
/api/v1/namespaces, lisades Authorization: Bearer pÀise.


Muidugi on k8s api-serveriga suhtlemiseks vajalik kasutaja, kellel on ainult lugemisÔigused; manifeste nende loomiseks leiate samuti .
Osa 5: vÀljaanne

PÀrast oma plugina kirjutamist Grafa jaoks soovite loomulikult selle avatud juurdepÀÀsu jaoks jagada. Grafanas on see pluginabiblioteek, mis on saadaval aadressil
Et teie plugin oleks ametlikus poes saadaval, peate tegema PR , lisades repo.json faili sisu jÀrgmisel kujul:

kus version on teie plugin`i versioon, url on lingi allikas ja commit on hash, mille jÀrgi on saadaval konkreetne versioon.
Ja vÀlja tulevad uimastavad pildid nagu see:

Andmed selle jaoks hangitakse automaatselt teie Readme.md, Changelog.md ja plugin.json failist, kus on plugina kirjeldus.
Osa 6: jÀrelduste asemel
Me ei ole pĂ€rast vĂ€ljalaskmist meie pistikprogrammi arendamist lĂ”petanud. Töö kĂ€ib praegu korrektse jĂ€lgimise kallal, et jĂ€lgida klastrite sĂ”lmede ressursikasutust, uute funktsioonide rakendamiseks kasutajakogemuse parandamiseks ning lahendame suure hulga tagasisidet, mida oleme saanud pistikprogrammi installimise ajal nii meie klientidelt kui ka GitHubis esitatud kĂŒsimustest (kui jĂ€tate oma kĂŒsimuse vĂ”i pull request'i, oleksin ma vĂ€ga Ă”nnelik đ ).
Loodame, et see artikkel aitab teil tutvuda sellise toreda tööriistaga nagu Grafana ja vÔib-olla kirjutada oma pistikprogrammi.
AitÀh!)
Allikas: habr.com
