Razvoj dodatka za Grafana: povijest naučenih lekcija

Pozdrav svima! Prije nekoliko mjeseci pokrenuli smo naš novi open-source projekt u produkciji — Grafana dodatak za praćenje kubernetes-a, koji smo nazvali DevOpsProdigy KubeGraf. Izvorni kod dodatka dostupan je u javnom repozitoriju na GitHubu. U ovom članku želimo podijeliti s vama priču o tome kako smo razvijali dodatak, koje smo alate koristili i s kakvim se izazovima suočili tijekom razvoja. Krenimo!

Dio 0 — uvod: kako smo do ovog došli?

Ideja da napišemo vlastiti dodatak za Grafanu pojavila se sasvim slučajno. Naša tvrtka već više od 10 godina bavi se praćenjem web-projekata različite složenosti. Tijekom tog vremena stekli smo veliko iskustvo, zanimljive slučajeve i iskustvo korištenja raznih sustava za praćenje. U nekom trenutku postavili smo si pitanje: "Postoji li čarobni alat za praćenje Kubernetes-a, koji se može 'postaviti i zaboraviti'?" Prometni standard za praćenje k8s, naravno, odavno je kombinacija Prometheus + Grafana. Za ovaj stakl postoji veliki broj različitih alata: prometheus-operator, set nadzornih ploča kubernetes-mixin, grafana-kubernetes-app.

Najinteresantnija opcija za nas činilo se da je dodatak grafana-kubernetes-app, no on se ne podržava više od godinu dana i, uz to, ne može raditi s novim verzijama node-exportera i kube-state-metrics-a. U nekom trenutku odlučili smo: "Zašto ne bismo napravili vlastito rješenje?"

Koje smo ideje odlučili realizirati u vlastitom dodatku:

  • vizualizacija 'karta aplikacije': prikladno prikazivanje aplikacija u klasteru, grupiranih prema namespace-ima, deployment-ima…;
  • vizualizacija odnosa tipa 'deployment — service (+ports)'.
  • vizualizacija raspodjele aplikacija klastera po nodovima klastera.
  • prikupljanje metrika i informacija iz više izvora: Prometheus i k8s api server.
  • praćenje infrastrukturnog dijela (korištenje procesorskog vremena, memorije, diskovnog sustava, mreže), kao i logike aplikacija — health-status pod-ova, broj dostupnih replika, informacije o prolasku liveness/readyness probiranja.

Dio 1: Što je 'dodatak za Grafana'?

S tehničke točke gledišta, dodatak za Grafanu je angular-kontroler, koji se pohranjuje u data-direktoriju Grafane (/var/grafana/plugins/<your_plugin_name>/dist/module.js) i može biti učitan kao SystemJS modul. Također, u ovoj direktoj mora se nalaziti datoteka plugin.json koja sadrži sve metapodatke o vašem pluginu: naziv, verzija, tip plugina, linkovi na repozitorij/web stranicu/licencu, ovisnosti i tako dalje.

Razvoj dodatka za Grafana: povijest naučenih lekcija
module.ts

Razvoj dodatka za Grafana: povijest naučenih lekcija
plugin.json

Kao što je prikazano na snimci, postavili smo plugin.type = app. Budući da mogu postojati tri vrste plugina za Grafanu:

panel: najčešći tip plugina — predstavlja panel za vizualizaciju raznih metrika, koristi se za izradu različitih nadzornih ploča.
datasource: plugin-konektor za neki izvor podataka (na primjer, Prometheus-datasource, ClickHouse-datasource, ElasticSearch-datasource).
app: plugin koji vam omogućuje da izradite vlastitu frontend aplikaciju unutar Grafane, stvarate vlastite HTML stranice i ručno se obraćate datasource-u za vizualizaciju raznih podataka. Također, kao ovisnosti mogu se koristiti pluginovi drugih tipova (datasource, panel) i različite nadzorne ploče.

Razvoj dodatka za Grafana: povijest naučenih lekcija
Primjer ovisnosti plugina s type = app.

Kao programski jezik možete koristiti i JavaScript i TypeScript (mi smo odabrali njega). Predloške za hello-world pluginove bilo koje vrste možete pronaći na linku: u ovom repozitoriju nalazi se veliki broj starter-packova (čak postoji i eksperimentalni primjer plugina na Reactu) s unaprijed instaliranim i konfiguriranim alatima.

Dio 2: priprema lokalnog okruženja

Za rad na pluginu, naravno, trebat će nam Kubernetes klaster sa svim unaprijed instaliranim alatima: prometheus, node-exporter, kube-state-metrics, grafana. Okruženje bi se trebalo postaviti brzo, lako i neformalno, a za osiguranje hot-reload data-direktorij Grafane trebao bi se montirati direktno s računala programera.

Najprikladniji način lokalnog rada s Kubernetesom je minikube. Sljedeći korak je instalirati vezu Prometheus + Grafana putem prometheus-operatora. U ovom članku detaljno je opisan proces instalacije prometheus-operatora na minikube. Za uključivanje trajnosti potrebno je postaviti parametar persistence: true u datoteci charts/grafana/values.yaml, dodati svoj vlastiti PV i PVC i navesti ih u parametru persistence.existingClaim

Konačni skript za pokretanje 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: razvoj

Objektni model

Kao pripremu za implementaciju dodatka odlučili smo opisati sve osnovne entitete Kubernetes-a s kojima ćemo raditi u obliku TypeScript klasa: pod, deployment, daemonset, statefulset, job, cronjob, service, node, namespace. Svaka od ovih klasa nasljeđuje zajedničku klasu BaseModel, koja opisuje konstruktor, destruktor, metode za ažuriranje i prebacivanje vidljivosti. U svakoj od klasa su opisane ugniježdene veze s drugim entitetima, na primjer, popis podova unutar entiteta tipa deployment.

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

Pomoću getter-a i setter-a možemo prikazivati ili postavljati potrebne nam metrike entiteta na prikladan i čitljiv način. Primjer formatiranog izlaza allocatable cpu nod-e:

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

Stranice

Popis svih stranica našeg dodatka prvotno se opisuje u našem pluing.json u odjeljku sa zavisnostima:

Razvoj dodatka za Grafana: povijest naučenih lekcija

U bloku za svaku stranicu moramo navesti NAZIV STRANICE (koji će potom biti konvertiran u slug pod kojim će stranica biti dostupna); naziv komponente koja je odgovorna za rad s ovom stranicom (popis komponenti izvozi se u module.ts); označavanje uloge korisnika kojoj je dostupno raditi s ovom stranicom i postavke navigacije za bočnu traku.

U komponenti koja je odgovorna za rad sa stranicom moramo postaviti templateUrl, prenoseći tamo putanju do html datoteke s markupom. Unutar kontrolera, putem dependency injection-a, možemo dobiti pristup do 2 važna angular servisa:

  • backendSrv — servis koji omogućava interakciju s api-serverom Grafane;
  • datasourceSrv — servis koji omogućava lokalnu interakciju sa svim izvorima podataka instaliranim u vašoj Grafani (na primjer, metoda .getAll() — vraća popis svih instaliranih izvora podataka; .get() — vraća objekt-instanicu konkretnog izvora podataka.

Razvoj dodatka za Grafana: povijest naučenih lekcija

Razvoj dodatka za Grafana: povijest naučenih lekcija

Razvoj dodatka za Grafana: povijest naučenih lekcija

Dio 4: izvor podataka

Prema Grafana, datasource je plugin poput svih ostalih: ima svoju ulaznu točku module.js i datoteku s metainformacijama plugin.json. Kada razvijamo plugin tipa app, možemo se povezati s postojećim datasourceima (na primjer, prometheus-datasource) ili s vlastitim koji možemo pohraniti izravno u direktorij plugina (dist/datasource/*) ili instalirati kao ovisnost. U našem slučaju, datasource dolazi zajedno s kodom plugina. Također je obavezno imati predložak config.html i kontroler ConfigCtrl, koji će se koristiti za stranicu konfiguracije instance datasourcea i kontrolera Datasource, u kojem se implementira logika rada vašeg datasourcea.

U pluginu KubeGraf, iz perspektive korisničkog sučelja, datasource predstavlja instancu kubernetes-klastera, koja ima sljedeće mogućnosti (izvorni kod je dostupan na linku):

  • prikupljanje podataka iz api-servera k8s (dohvaćanje popisa namespacea, deploymenta…)
  • proksiranje zahtjeva u prometheus-datasource (koji se odabire u postavkama plugina za svaki konkretni klaster) i formatiranje odgovora za upotrebu podataka kako na statičnim stranicama, tako i na nadzornim pločama.
  • ažuriranje podataka na statičnim stranicama plugina (s postavljenim vremenom osvježavanja).
  • obrada zahtjeva za generiranje popisa predložaka u grafana-dashboards (metoda .metriFindQuery())

Razvoj dodatka za Grafana: povijest naučenih lekcija

Razvoj dodatka za Grafana: povijest naučenih lekcija

Razvoj dodatka za Grafana: povijest naučenih lekcija

  • testiranje veze s 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: "Izvor podataka je u redu", title: "Uspjeh"};
           }else{
               return {status: "error", message: "Izvor podataka nije u redu", title: "Greška"};
           }
       }, error => {
           return {status: "error", message: "Izvor podataka nije u redu", title: "Greška"};
       })
}

Jedan zanimljiv aspekt, prema našem mišljenju, je implementacija mehanizma autentifikacije i autorizacije za datasource. Obično, iz kutije za konfiguraciju pristupa krajnjem izvoru podataka možemo koristiti ugrađenu komponentu Grafana — datasourceHttpSettings. Pomoću ove komponente možemo konfigurirati pristup http-izvoru podataka, navodeći URL i osnovne postavke autentifikacije/oznake: korisničko ime lozinka, ili client-cert/client-key. Kako bismo omogućili konfiguraciju pristupa putem bearer-tokena (de facto standard za k8s), trebalo je malo „zakuhati“.

Za rješavanje ovog zadatka može se koristiti ugrađeni mehanizam Grafana „Plugin Routes“ (više na službenoj stranici dokumentacije). U postavkama našeg datasource-a možemo deklarirati skup pravila usmjeravanja koja će obraditi proxy poslužitelj grafana. Na primjer, za svaki pojedini endpoint postoji mogućnost postavljanja zaglavlja ili URL-a s mogućnošću templatinga, a podaci za koje se mogu uzeti iz polja jsonData i secureJsonData (za pohranu lozinki ili tokena u šifriranom obliku). U našem primjeru, zahtjevi poput /__proxy/api/v1/namespaces bit će proksirani na URL poput
/api/v1/namespaces s postavljenim zaglavljem Authorization: Bearer.

Razvoj dodatka za Grafana: povijest naučenih lekcija

Razvoj dodatka za Grafana: povijest naučenih lekcija

Naravno, za rad s api-poslužiteljem k8s potreban nam je korisnik s readonly pristupima, a manifesti za njegovo kreiranje također se mogu pronaći u izvornom kodu plugina.

Dio 5: izdanje

Razvoj dodatka za Grafana: povijest naučenih lekcija

Nakon što napišete vlastiti plugin za Grafanu, naravno, poželjet ćete ga objaviti kao otvoreni izvor. U Grafani postoji biblioteka pluginova koja je dostupna na linku grafana.com/grafana/plugins

Kako bi vaš plugin bio dostupan u službenoj trgovini, potrebno je napraviti PR u ovaj repozitorij, dodajući u datoteku repo.json sadržaj oblika:

Razvoj dodatka za Grafana: povijest naučenih lekcija

gdje je version — verzija vašeg plugina, url — link na repozitorij, a commit — hash commit-a koji će omogućiti specifičnu verziju plugina.

I na izlazu ćete vidjeti prekrasnu sliku oblika:

Razvoj dodatka za Grafana: povijest naučenih lekcija

Podaci za nju će se automatski izvući iz vašeg Readme.md, Changelog.md i datoteke plugin.json s opisom plugina.

Dio 6: umjesto zaključaka

Nismo prekinuli razvoj našeg dodatka nakon objave. Trenutno radimo na pravilnom praćenju upotrebe resursa nodova klastera, implementaciji novih funkcionalnosti za poboljšanje korisničkog iskustva, kao i na rješavanju velikog broja povratnih informacija koje smo dobili nakon instalacije dodatka od naših klijenata, kao i iz prijava na GitHubu (ako ostavite svoj issue ili pull request, bit ću vrlo sretan 🙂 ).

Nadamo se da će vam ovaj članak pomoći da se upoznate s ovim prekrasnim alatom kao što je Grafana i možda napisati vlastiti dodatak.

Hvala!)

Izvor: habr.com

Kupite pouzdan hosting za web stranice s DDoS zaštitom, VPS VDS servere 🔥 Kupite pouzdan hosting za web stranice s DDoS zaštitom, VPS VDS servere | ProHoster