Razvoj dodatka za Grafano: zgodovina velikih strelov

Pozdravljeni vsi skupaj! Pred nekaj meseci smo v produkcijo lansirali naš nov odprtokodni projekt - vtičnik Grafana za spremljanje kubernetes, ki smo ga poimenovali DevOpsProdigy KubeGraf. Izvorna koda vtičnika je na voljo na javno skladišče na GitHubu. In v tem članku želimo z vami deliti zgodbo o tem, kako smo ustvarili vtičnik, katera orodja smo uporabili in na katere pasti smo naleteli med razvojnim procesom. Pojdimo!

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.

Razvoj dodatka za Grafano: zgodovina velikih strelov
modul.ts

Razvoj dodatka za Grafano: zgodovina velikih strelov
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.

Razvoj dodatka za Grafano: zgodovina velikih strelov
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 najdi povezavo: to skladišče vsebuje veliko število začetnih paketov (obstaja celo eksperimentalni primer vtičnika v Reactu) z vnaprej nameščenimi in konfiguriranimi graditelji.

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 minikube. Naslednji korak je namestitev kombinacije Prometheus + Grafana z uporabo prometheus-operatorja. IN Ta članek Postopek namestitve prometheus-operatorja na minikube je podrobno opisan. Če želite omogočiti obstojnost, morate nastaviti parameter obstojnost: res v datoteki charts/grafana/values.yaml dodajte svoj PV in PVC ter ju navedite v parametru persistence.existingClaim

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:

Razvoj dodatka za Grafano: zgodovina velikih strelov

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.

Razvoj dodatka za Grafano: zgodovina velikih strelov

Razvoj dodatka za Grafano: zgodovina velikih strelov

Razvoj dodatka za Grafano: zgodovina velikih strelov

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

Razvoj dodatka za Grafano: zgodovina velikih strelov

Razvoj dodatka za Grafano: zgodovina velikih strelov

Razvoj dodatka za Grafano: zgodovina velikih strelov

  • 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 stran uradne dokumentacije). V nastavitvah našega podatkovnega vira lahko navedemo niz pravil usmerjanja, ki jih bo obdelal proxy strežnik grafana. Tako je na primer za vsako posamezno končno točko mogoče nastaviti glave ali url-je z možnostjo šabloniranja, podatke za katere lahko vzamemo iz polj jsonData in secureJsonData (za shranjevanje gesel ali žetonov v šifrirani obliki). V našem primeru so poizvedbe, kot so /__proxy/api/v1/namespaces bo posredovan na url obrazca
/api/v8/namespaces z glavo Authorization: Bearer.

Razvoj dodatka za Grafano: zgodovina velikih strelov

Razvoj dodatka za Grafano: zgodovina velikih strelov

Za delo s strežnikom api k8s seveda potrebujemo uporabnika z dostopom samo za branje, manifeste za ustvarjanje katerih lahko najdete tudi v izvorna koda vtičnika.

5. del: sprostitev

Razvoj dodatka za Grafano: zgodovina velikih strelov

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 grafana.com/grafana/plugins

Da bo vaš vtičnik na voljo v uradni trgovini, morate narediti PR to skladiščez dodajanjem vsebine, kot je ta, v datoteko repo.json:

Razvoj dodatka za Grafano: zgodovina velikih strelov

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:

Razvoj dodatka za Grafano: zgodovina velikih strelov

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

Dodaj komentar