Pozdravljeni vsi skupaj! Pred nekaj meseci smo v produkcijo lansirali naš nov odprtokodni projekt - vtičnik Grafana za spremljanje kubernetes, ki smo ga poimenovali
0. del – uvod: kako smo prišli do te točke?
Ideja, da bi napisali svoj vtičnik za Grafan, se nam je porodila čisto po naključju. Naše podjetje že več kot 10 let spremlja spletne projekte različnih stopenj zahtevnosti. V tem času smo si nabrali ogromno strokovnega znanja, zanimivih primerov in izkušenj z uporabo različnih nadzornih sistemov. In na neki točki smo se vprašali: "Ali obstaja čarobno orodje za spremljanje Kubernetesa, tako da, kot pravijo, "nastavite in pozabite"?".. Industrijski standard za spremljanje k8s je seveda že dolgo Kombinacija Prometej + Grafana. Kot že pripravljene rešitve za ta sklad je na voljo velik nabor različnih vrst orodij: prometheus-operator, nabor nadzornih plošč kubernetes-mixin, grafana-kubernetes-app.
Vtičnik grafana-kubernetes-app se nam je zdel najbolj zanimiva možnost, vendar ni bil podprt že več kot eno leto in poleg tega ne more delovati z novimi različicami node-exporter in kube-state-metrics. In na neki točki smo se odločili: "Ali se ne bi morali odločiti sami?"
Katere ideje smo se odločili implementirati v naš vtičnik:
- vizualizacija “karte aplikacij”: priročna predstavitev aplikacij v gruči, razvrščenih po imenskih prostorih, razmestitvah...;
- vizualizacija povezav, kot je "razmestitev - storitev (+vrata)".
- vizualizacija porazdelitve aplikacij gruče po vozliščih gruče.
- zbiranje metrik in informacij iz več virov: Prometheus in k8s api strežnik.
- spremljanje tako infrastrukturnega dela (uporaba procesorskega časa, pomnilnika, diskovnega podsistema, omrežja) kot aplikacijske logike - podi za zdravstveno stanje, število razpoložljivih replik, informacije o opravljenih testih pripravljenosti.
1. del: Kaj je »vtičnik Grafana«?
S tehničnega vidika je vtičnik za Grafano kotni krmilnik, ki je shranjen v podatkovnem imeniku Grafana (/var/grafana/plugins/ /dist/module.js) in se lahko naloži kot modul SystemJS. V tem imeniku mora biti tudi datoteka plugin.json, ki vsebuje vse meta informacije o vašem vtičniku: ime, različica, vrsta vtičnika, povezave do repozitorija/mesta/licence, odvisnosti itd.
modul.ts
plugin.json
Kot lahko vidite na posnetku zaslona, smo določili plugin.type = app. Ker so vtičniki za Grafano lahko treh vrst:
plošča: najpogostejša vrsta vtičnika - je plošča za vizualizacijo katere koli metrike, ki se uporablja za izdelavo različnih nadzornih plošč.
vir podatkov: priključek vtičnika za neki vir podatkov (na primer Prometheus-datasource, ClickHouse-datasource, ElasticSearch-datasource).
aplikacija: Vtičnik, ki vam omogoča, da zgradite svojo lastno čelno aplikacijo znotraj Grafane, ustvarite lastne html strani in ročno dostopate do vira podatkov za vizualizacijo različnih podatkov. Kot odvisnosti se lahko uporabljajo tudi vtičniki drugih vrst (vir podatkov, plošča) in različne nadzorne plošče.
Primeri odvisnosti vtičnika s tipom=app.
Kot programski jezik lahko uporabljate JavaScript in TypeScript (izbrali smo ga mi). Priprave za vtičnike hello-world katere koli vrste
2. del: priprava lokalnega okolja
Za delo na vtičniku seveda potrebujemo gručo kubernetes z vsemi vnaprej nameščenimi orodji: prometheus, node-exporter, kube-state-metrics, grafana. Okolje mora biti nastavljeno hitro, enostavno in naravno, za zagotovitev vročega ponovnega nalaganja pa je treba podatkovni imenik Grafana namestiti neposredno z razvijalčevega stroja.
Po našem mnenju je najprimernejši način za lokalno delo s kubernetes
Naš zadnji skript za zagon minikube izgleda takole:
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. del: dejanski razvoj
Objektni model
Pri pripravah na implementacijo vtičnika smo se odločili opisati vse osnovne entitete Kubernetes, s katerimi bomo delali, v obliki razredov TypeScript: pod, uvajanje, daemonset, statefulset, job, cronjob, service, node, namespace. Vsak od teh razredov podeduje skupni razred BaseModel, ki opisuje konstruktor, destruktor, metode za posodabljanje in preklapljanje vidnosti. Vsak od razredov opisuje ugnezdena razmerja z drugimi entitetami, na primer seznam podov za entiteto razmestitve tipa.
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 = [];
}
}
S pomočjo pridobivalnikov in nastavljalcev lahko prikažemo ali nastavimo metrike entitet, ki jih potrebujemo, v priročni in berljivi obliki. Na primer, formatiran izhod vozlišč CPU, ki jih je mogoče dodeliti:
get cpuAllocatableFormatted(){
let cpu = this.data.status.allocatable.cpu;
if(cpu.indexOf('m') > -1){
cpu = parseInt(cpu)/1000;
}
return cpu;
}
Strani
Seznam vseh naših strani vtičnikov je na začetku opisan v našem pluing.json v razdelku odvisnosti:
V bloku za vsako stran moramo navesti IME STRANI (takrat bo pretvorjeno v polž, s katerim bo ta stran dostopna); ime komponente, odgovorne za delovanje te strani (seznam komponent se izvozi v module.ts); ki označuje uporabniško vlogo, za katero je na voljo delo s to stranjo, in navigacijske nastavitve za stransko vrstico.
V komponenti, ki je odgovorna za delovanje strani, moramo nastaviti templateUrl, tja posredovati pot do datoteke html z oznako. Znotraj krmilnika lahko prek vbrizgavanja odvisnosti dostopamo do 2 pomembnih kotnih storitev:
- backendSrv - storitev, ki omogoča interakcijo s strežnikom Grafana API;
- datasourceSrv – storitev, ki zagotavlja lokalno interakcijo z vsemi viri podatkov, nameščenimi v vaši Grafani (na primer metoda .getAll() – vrne seznam vseh nameščenih virov podatkov; .get( ) - vrne objekt primerka določenega vira podatkov.
4. del: vir podatkov
Z Grafaninega vidika je datasource popolnoma enak vtičnik kot vsi ostali: ima svojo vstopno točko module.js, obstaja datoteka z metainformacijami plugin.json. Ko razvijamo vtičnik s tipom = app, lahko komuniciramo z obstoječimi viri podatkov (na primer prometheus-datasource) in lastnimi, ki jih lahko shranimo neposredno v imenik vtičnikov (dist/datasource/*) ali namestimo kot odvisnost. V našem primeru je vir podatkov opremljen s kodo vtičnika. Prav tako je potrebno imeti predlogo config.html in krmilnik ConfigCtrl, ki se bo uporabljal za konfiguracijsko stran primerka vira podatkov in krmilnik vira podatkov, ki implementira logiko vašega vira podatkov.
V vtičniku KubeGraf je z vidika uporabniškega vmesnika vir podatkov primerek gruče kubernetes, ki izvaja naslednje zmožnosti (izvorna koda je na voljo
- zbiranje podatkov iz k8s api-strežnika (pridobivanje seznama imenskih prostorov, razmestitev ...)
- posredovanje zahtevkov prometheus-datasource (ki je izbran v nastavitvah vtičnika za vsako specifično gručo) in oblikovanje odgovorov za uporabo podatkov tako na statičnih straneh kot na nadzornih ploščah.
- posodabljanje podatkov na statičnih straneh vtičnikov (z nastavljeno hitrostjo osveževanja).
- obdelava poizvedb za ustvarjanje lista s predlogo v nadzornih ploščah grafana (metoda metriFindQuery())
- test povezave s končno gručo 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"};
})
}
Ločena zanimiva točka je po našem mnenju implementacija mehanizma za preverjanje pristnosti in avtorizacije za vir podatkov. Običajno lahko takoj po namestitvi uporabimo vgrajeno komponento Grafana datasourceHttpSettings za konfiguracijo dostopa do končnega vira podatkov. S to komponento lahko konfiguriramo dostop do podatkovnega vira http tako, da podamo url in osnovne nastavitve za preverjanje pristnosti/pooblastitev: prijavno geslo ali klient-cert/klient-ključ. Za uvedbo zmožnosti konfiguriranja dostopa z uporabo nosilnega žetona (dejanski standard za k8s) smo morali malo prilagoditi.
Za rešitev te težave lahko uporabite vgrajen mehanizem Grafana “Plugin Routes” (več podrobnosti na
/api/v8/namespaces z glavo Authorization: Bearer.
Za delo s strežnikom api k8s seveda potrebujemo uporabnika z dostopom samo za branje, manifeste za ustvarjanje katerih lahko najdete tudi v
5. del: sprostitev
Ko enkrat napišete svoj vtičnik Grafana, ga boste seveda želeli narediti javno dostopnega. V Grafani je to knjižnica vtičnikov, ki so na voljo tukaj
Da bo vaš vtičnik na voljo v uradni trgovini, morate narediti PR
kjer je različica različica vašega vtičnika, url je povezava do repozitorija, commit pa je zgoščena vrednost objave, za katero bo na voljo določena različica vtičnika.
In na izhodu boste videli čudovito sliko, kot je:
Podatki zanj bodo samodejno zbrani iz datoteke Readme.md, Changelog.md in datoteke plugin.json z opisom vtičnika.
6. del: namesto zaključkov
Po izdaji nismo nehali razvijati našega vtičnika. In zdaj delamo na pravilnem spremljanju uporabe virov vozlišč gruče, uvajamo nove funkcije za izboljšanje UX in zbiramo veliko količino povratnih informacij, ki jih po namestitvi vtičnika prejmejo naše stranke in ljudje na GitHubu (če zapustite vaše težave ali zahteve po vleki, bom zelo vesel :)
Upamo, da vam bo ta članek pomagal razumeti tako čudovito orodje, kot je Grafana, in morda napisati svoj vtičnik.
Hvala vam!)
Vir: www.habr.com