Razvoj dodatka za Grafanu: istorija velikih uspeha

Zdravo svima! Prije nekoliko mjeseci pokrenuli smo u produkciju naš novi open-source projekat - dodatak Grafana za praćenje kubernetesa, koji smo nazvali DevOpsProdigy KubeGraf. Izvorni kod dodatka je dostupan na javno spremište na GitHubu. I u ovom članku želimo s vama podijeliti priču o tome kako smo kreirali dodatak, koje smo alate koristili i na koje smo zamke naišli tokom procesa razvoja. Idemo!

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.

Razvoj dodatka za Grafanu: istorija velikih uspeha
module.ts

Razvoj dodatka za Grafanu: istorija velikih uspeha
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.

Razvoj dodatka za Grafanu: istorija velikih uspeha
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 pronađite link: ovo spremište sadrži veliki broj početnih paketa (postoji čak i eksperimentalni primjer dodatka u Reactu) s unaprijed instaliranim i konfiguriranim programerima.

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 minikube. Sljedeći korak je instaliranje kombinacije Prometheus + Grafana pomoću prometheus-operatora. IN Ovaj članak Detaljno je opisan proces instaliranja prometheus-operatora na minikube. Da biste omogućili postojanost, morate postaviti parametar postojanost: istina u datoteci charts/grafana/values.yaml, dodajte svoj PV i PVC i navedite ih u parametru persistence.existingClaim

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:

Razvoj dodatka za Grafanu: istorija velikih uspeha

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.

Razvoj dodatka za Grafanu: istorija velikih uspeha

Razvoj dodatka za Grafanu: istorija velikih uspeha

Razvoj dodatka za Grafanu: istorija velikih uspeha

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 link):

  • 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())

Razvoj dodatka za Grafanu: istorija velikih uspeha

Razvoj dodatka za Grafanu: istorija velikih uspeha

Razvoj dodatka za Grafanu: istorija velikih uspeha

  • 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 zvanična stranica dokumentacije). U postavkama našeg izvora podataka možemo deklarirati skup pravila rutiranja koja će obraditi grafana proxy server. Na primjer, za svaku pojedinačnu krajnju točku moguće je postaviti zaglavlja ili URL-ove s mogućnošću šabloniranja, za koje se podaci mogu preuzeti iz polja jsonData i secureJsonData (za pohranjivanje lozinki ili tokena u šifriranom obliku). U našem primjeru, upiti poput /__proxy/api/v1/namespaces će biti proksi na url obrasca
/api/v8/namespaces sa zaglavljem Authorization: Bearer.

Razvoj dodatka za Grafanu: istorija velikih uspeha

Razvoj dodatka za Grafanu: istorija velikih uspeha

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 izvorni kod dodatka.

Dio 5: oslobađanje

Razvoj dodatka za Grafanu: istorija velikih uspeha

Nakon što napišete svoj vlastiti Grafana dodatak, prirodno ćete ga željeti učiniti javno dostupnim. U Grafani ovo je biblioteka dodataka dostupna ovdje grafana.com/grafana/plugins

Da bi vaš dodatak bio dostupan u službenoj trgovini, potrebno je napraviti PR in ovo spremištedodavanjem sadržaja poput ovog u datoteku repo.json:

Razvoj dodatka za Grafanu: istorija velikih uspeha

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:

Razvoj dodatka za Grafanu: istorija velikih uspeha

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

Dodajte komentar