Zdravo svima! Prije nekoliko mjeseci pokrenuli smo u produkciju naš novi open-source projekat - dodatak Grafana za praćenje kubernetesa, koji smo nazvali
Deo 0 - uvodni: kako smo došli do ove tačke?
Ideja da napišemo vlastiti plugin za Grafan došla nam je sasvim slučajno. Naša kompanija prati web projekte različitih nivoa složenosti više od 10 godina. Za to vrijeme stekli smo veliku količinu stručnosti, zanimljivih slučajeva i iskustva u korištenju različitih sistema za praćenje. I u nekom trenutku smo se zapitali: „Postoji li čarobni alat za praćenje Kubernetesa, pa da, kako kažu, „podesi i zaboravi“?“ Industrijski standard za praćenje k8s, naravno, odavno je Kombinacija Prometej + Grafana. A kao gotova rješenja za ovaj stek, postoji veliki skup raznih vrsta alata: prometheus-operator, set kubernetes-mixin nadzornih ploča, grafana-kubernetes-app.
Dodatak grafana-kubernetes-app nam se činio najzanimljivijom opcijom, ali nije podržan više od godinu dana i, osim toga, ne može raditi s novim verzijama node-exporter-a i kube-state-metrics. I u jednom trenutku smo odlučili: "Zar ne bismo trebali sami donijeti odluku?"
Koje smo ideje odlučili implementirati u našem dodatku:
- vizualizacija “mape aplikacija”: pogodna prezentacija aplikacija u klasteru, grupisanih po imenskim prostorima, implementacijama...;
- vizualizacija konekcija kao što je “ugradnja - usluga (+portovi)”.
- vizualizacija distribucije klaster aplikacija po čvorovima klastera.
- zbirka metrike i informacija iz nekoliko izvora: Prometheus i k8s api server.
- praćenje i infrastrukturnog dijela (upotreba CPU vremena, memorije, diskovnog podsistema, mreže) i logike aplikacije - podovi zdravstvenog statusa, broj dostupnih replika, informacije o prolaznosti testova živosti/spremnosti.
Dio 1: Šta je “Grafana dodatak”?
Sa tehničke tačke gledišta, dodatak za Grafanu je ugaoni kontroler, koji je pohranjen u direktoriju podataka Grafana (/var/grafana/plugins/ /dist/module.js) i može se učitati kao SystemJS modul. Takođe u ovom direktorijumu treba da postoji plugin.json fajl koji sadrži sve meta informacije o vašem dodatku: ime, verziju, tip dodatka, veze do spremišta/stranice/licence, zavisnosti, itd.
module.ts
plugin.json
Kao što možete vidjeti na snimku ekrana, specificirali smo plugin.type = app. Jer dodaci za Grafanu mogu biti tri tipa:
panel: najčešći tip dodatka - to je panel za vizualizaciju bilo koje metrike, koji se koristi za pravljenje raznih nadzornih ploča.
izvor podataka: priključak priključka za neki izvor podataka (na primjer, Prometheus-datasource, ClickHouse-datasource, ElasticSearch-datasource).
aplikacija: Dodatak koji vam omogućava da napravite vlastitu frontend aplikaciju unutar Grafane, kreirate vlastite html stranice i ručno pristupite izvoru podataka za vizualizaciju različitih podataka. Takođe, dodaci drugih tipova (izvor podataka, panel) i razne kontrolne table se mogu koristiti kao zavisnosti.
Primjer ovisnosti dodataka sa type=app.
Možete koristiti i JavaScript i TypeScript kao programski jezik (mi smo ga izabrali). Pripreme za hello-world dodatke bilo koje vrste
Dio 2: priprema lokalne sredine
Za rad na dodatku, prirodno nam je potreban kubernetes klaster sa svim unaprijed instaliranim alatima: prometheus, node-exporter, kube-state-metrics, grafana. Okruženje treba postaviti brzo, jednostavno i prirodno, a kako bi se osiguralo ponovno učitavanje, Grafana direktorij podataka bi trebao biti montiran direktno sa stroja programera.
Najprikladniji način, po našem mišljenju, za lokalni rad sa kubernetesom je
Naša konačna skripta za lansiranje minikubea izgleda ovako:
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
Dio 3: stvarni razvoj
Objektni model
U pripremi za implementaciju dodatka, odlučili smo da opišemo sve osnovne Kubernetes entitete sa kojima ćemo raditi u obliku TypeScript klasa: pod, deployment, daemonset, statefulset, posao, cronjob, service, node, namespace. Svaka od ovih klasa nasljeđuje uobičajenu klasu BaseModel, koja opisuje konstruktor, destruktor, metode za ažuriranje i promjenu vidljivosti. Svaka od klasa opisuje ugniježđene odnose s drugim entitetima, na primjer, listu podova za entitet implementacije 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 = [];
}
}
Uz pomoć gettera i settera, možemo prikazati ili postaviti metriku entiteta koja nam je potrebna u prikladnom i čitljivom obliku. Na primjer, formatirani izlaz cpu čvorova koji se mogu dodijeliti:
get cpuAllocatableFormatted(){
let cpu = this.data.status.allocatable.cpu;
if(cpu.indexOf('m') > -1){
cpu = parseInt(cpu)/1000;
}
return cpu;
}
Stranice
Lista svih naših dodataka je prvobitno opisana u našem pluing.json u odjeljku ovisnosti:
U bloku za svaku stranicu moramo navesti NAZIV STRANICE (ono će biti konvertovano u puž preko kojeg će ovoj stranici biti pristupačno); naziv komponente odgovorne za rad ove stranice (lista komponenti se izvozi u module.ts); označavajući korisničku ulogu za koju je rad sa ovom stranicom dostupan i postavke navigacije za bočnu traku.
U komponenti odgovornoj za rad stranice, moramo postaviti templateUrl, prosljeđujući tamo putanju do html datoteke s markupom. Unutar kontrolera, kroz injekciju zavisnosti, možemo pristupiti do 2 važna angular servisa:
- backendSrv - servis koji pruža interakciju sa Grafana API serverom;
- datasourceSrv - usluga koja pruža lokalnu interakciju sa svim izvorima podataka instaliranim u vašoj Grafani (na primjer, metoda .getAll() - vraća listu svih instaliranih izvora podataka; .get( ) - vraća objekt instance određenog izvora podataka.
Dio 4: izvor podataka
Sa Grafanine tačke gledišta, datasource je potpuno isti dodatak kao i svi ostali: ima svoju ulaznu tačku module.js, postoji datoteka sa meta informacijama plugin.json. Kada razvijamo dodatak s tipom = app, možemo komunicirati s postojećim izvorima podataka (na primjer, prometheus-datasource) i našim vlastitim, koje možemo pohraniti direktno u direktorij dodataka (dist/datasource/*) ili instalirati kao zavisnost. U našem slučaju, izvor podataka dolazi sa kodom dodatka. Također je potrebno imati config.html šablon i ConfigCtrl kontroler, koji će se koristiti za stranicu konfiguracije instance izvora podataka i Datasource kontroler, koji implementira operativnu logiku vašeg izvora podataka.
U dodatku KubeGraf, sa stanovišta korisničkog interfejsa, izvor podataka je instanca kubernetes klastera koji implementira sledeće mogućnosti (izvorni kod je dostupan
- prikupljanje podataka sa k8s api-servera (dobivanje liste imenskih prostora, implementacija...)
- proxy zahtjeva za prometheus-datasource (koji je odabran u postavkama dodatka za svaki određeni klaster) i formatiranje odgovora za korištenje podataka kako na statičnim stranicama tako i na nadzornim pločama.
- ažuriranje podataka na statičnim stranicama dodataka (sa zadatom brzinom osvježavanja).
- obrada upita za generiranje šablona u grafana-dashboards (metoda metriFindQuery())
- test veze sa konačnim k8s klasterom.
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"};
})
}
Posebna zanimljivost, po našem mišljenju, je implementacija mehanizma autentifikacije i autorizacije za izvor podataka. Obično, izvan kutije, možemo koristiti ugrađenu komponentu Grafana datasourceHttpSettings za konfiguriranje pristupa konačnom izvoru podataka. Koristeći ovu komponentu, možemo konfigurirati pristup izvoru http podataka specificiranjem url-a i osnovnih postavki autentifikacije/autorizacije: login-password ili client-cert/client-key. Da bismo implementirali mogućnost konfigurisanja pristupa pomoću tokena nosioca (de facto standard za k8s), morali smo malo podesiti.
Da biste riješili ovaj problem, možete koristiti ugrađeni Grafana mehanizam “Plugin Routes” (više detalja na
/api/v8/namespaces sa zaglavljem Authorization: Bearer.
Naravno, za rad sa k8s api serverom potreban nam je korisnik sa pristupom samo za čitanje, manifeste za kreiranje koje takođe možete pronaći u
Dio 5: oslobađanje
Nakon što napišete svoj vlastiti Grafana dodatak, prirodno ćete ga željeti učiniti javno dostupnim. U Grafani ovo je biblioteka dodataka dostupna ovdje
Da bi vaš dodatak bio dostupan u službenoj trgovini, potrebno je napraviti PR in
gdje je verzija verzija vašeg dodatka, url je veza do spremišta, a urezivanje je hash urezivanja za koji će određena verzija dodatka biti dostupna.
A na izlazu ćete vidjeti divnu sliku poput:
Podaci za njega će se automatski preuzeti iz vašeg Readme.md, Changelog.md i datoteke plugin.json sa opisom dodatka.
Dio 6: umjesto zaključaka
Nismo prestali razvijati naš dodatak nakon objavljivanja. I sada radimo na ispravnom praćenju korištenja resursa čvorova klastera, uvođenju novih funkcija za poboljšanje UX-a, a također i na prikupljanju velike količine povratnih informacija koje su nakon instaliranja dodatka primili naši klijenti i ljudi na GitHubu (ako odete vaš problem ili zahtjev za povlačenje, bit ću vrlo sretan :)
Nadamo se da će vam ovaj članak pomoći da shvatite tako divan alat kao što je Grafana i, možda, da napišete vlastiti dodatak.
Hvala ti!)
izvor: www.habr.com