Żvilupp ta' plugin għal Grafana: storja ta' tiri kbar

Hi kollha! Ftit xhur ilu, nedejna l-proġett ta’ sors miftuħ il-ġdid tagħna fil-produzzjoni - il-plugin Grafana għall-monitoraġġ tal-kubernetes, li sejjaħna DevOpsProdigy KubeGraf. Il-kodiċi tas-sors tal-plugin huwa disponibbli fuq repożitorju pubbliku fuq GitHub. U f'dan l-artikolu rridu naqsmu miegħek l-istorja ta 'kif ħloqna l-plugin, liema għodod użajna u x'iżvantaġġi ltqajna magħhom matul il-proċess ta' żvilupp. Tlaqna!

Parti 0 - introduzzjoni: kif wasalna sa dan il-punt?

L-idea li niktbu l-plugin tagħna stess għal Grafan waslet lilna pjuttost b'inċident. Il-kumpanija tagħna ilha tissorvelja proġetti tal-web ta’ diversi livelli ta’ kumplessità għal aktar minn 10 snin. Matul dan iż-żmien, akkumulajna ammont kbir ta 'għarfien espert, każijiet interessanti, u esperjenza fl-użu ta' diversi sistemi ta 'monitoraġġ. U f'xi punt staqsejna lilna nfusna: "Hemm għodda maġika għall-monitoraġġ ta 'Kubernetes, sabiex, kif jgħidu, "issettjaha u tinsaha"?".. L-istandard tal-industrija għall-monitoraġġ tal-k8s, ovvjament, ilu żmien twil il- Prometheus + kombinazzjoni Grafana. U bħala soluzzjonijiet lesti għal dan il-munzell, hemm sett kbir ta 'diversi tipi ta' għodod: prometheus-operator, sett ta 'kubernetes-mixin dashboards, grafana-kubernetes-app.

Il-plugin grafana-kubernetes-app deher li kien l-aktar għażla interessanti għalina, iżda ma ġiex appoġġjat għal aktar minn sena u, barra minn hekk, ma jistax jaħdem ma 'verżjonijiet ġodda ta' node-exporter u kube-state-metrics. U f’xi punt iddeċidejna: “M’għandniex nieħdu d-deċiżjoni tagħna stess?”

Liema ideat iddeċidejna li nimplimentaw fil-plugin tagħna:

  • viżwalizzazzjoni tal-"mappa tal-applikazzjoni": preżentazzjoni konvenjenti tal-applikazzjonijiet fil-cluster, miġbura minn namespaces, skjeramenti...;
  • viżwalizzazzjoni ta' konnessjonijiet bħal "skjerament - servizz (+portijiet)".
  • viżwalizzazzjoni tad-distribuzzjoni ta 'applikazzjonijiet cluster madwar cluster nodes.
  • ġbir ta 'metriċi u informazzjoni minn diversi sorsi: Prometheus u k8s api server.
  • monitoraġġ kemm tal-parti tal-infrastruttura (użu tal-ħin tas-CPU, memorja, subsistema tad-disk, netwerk) kif ukoll loġika tal-applikazzjoni - pods tal-istat tas-saħħa, numru ta 'repliki disponibbli, informazzjoni dwar il-passaġġ tat-testijiet tal-ħajja/prontezza.

Parti 1: X'inhu "Grafana plugin"?

Mil-lat tekniku, il-plugin għal Grafana huwa kontrollur angolari, li huwa maħżun fid-direttorju tad-dejta Grafana (/var/grafana/plugins/ /dist/module.js) u jista' jitgħabba bħala modulu SystemJS. F'dan id-direttorju wkoll għandu jkun hemm fajl plugin.json li jkun fih l-informazzjoni meta kollha dwar il-plugin tiegħek: isem, verżjoni, tip ta 'plugin, links għar-repożitorju/sit/liċenzja, dipendenzi, eċċ.

Żvilupp ta' plugin għal Grafana: storja ta' tiri kbar
modulu.ts

Żvilupp ta' plugin għal Grafana: storja ta' tiri kbar
plugin.json

Kif tistgħu taraw fil-screenshot, speċifikajna plugin.type = app. Minħabba li l-plugins għal Grafana jistgħu jkunu ta 'tliet tipi:

bord: l-aktar tip komuni ta 'plugin - huwa panel għall-viżwalizzazzjoni ta' kwalunkwe metrika, użata biex tibni diversi dashboards.
sors tad-data: konnettur tal-plugin għal xi sors tad-dejta (pereżempju, Prometheus-datasource, ClickHouse-datasource, ElasticSearch-datasource).
app: Plugin li jippermettilek tibni l-applikazzjoni frontend tiegħek stess ġewwa Grafana, toħloq il-paġni html tiegħek stess u taċċessa manwalment is-sors tad-dejta biex tara dejta varji. Ukoll, plugins ta 'tipi oħra (datasource, panel) u diversi dashboards jistgħu jintużaw bħala dipendenzi.

Żvilupp ta' plugin għal Grafana: storja ta' tiri kbar
Eżempju tad-dipendenzi tal-plugin b'tip=app.

Tista 'tuża kemm JavaScript kif ukoll TypeScript bħala lingwa ta' programmar (għażilna). Tħejjijiet għal plugins hello-world ta 'kull tip li tista' sib il-link: dan ir-repożitorju fih numru kbir ta 'starter-packs (saħansitra hemm eżempju sperimentali ta' plugin f'React) b'bennejja installati minn qabel u kkonfigurati.

Parti 2: it-tħejjija tal-ambjent lokali

Biex naħdmu fuq il-plugin, naturalment għandna bżonn kubernetes cluster bl-għodod kollha installati minn qabel: prometheus, node-exporter, kube-state-metrics, grafana. L-ambjent għandu jiġi stabbilit malajr, faċilment u b'mod naturali, u biex jiġi żgurat hot-reload, id-direttorju tad-dejta Grafana għandu jiġi mmuntat direttament mill-magna tal-iżviluppatur.

L-aktar mod konvenjenti, fl-opinjoni tagħna, biex taħdem lokalment ma 'kubernetes huwa minikube. Il-pass li jmiss huwa li tinstalla l-kombinazzjoni Prometheus + Grafana billi tuża prometheus-operator. IN Dan l-artiklu Il-proċess ta 'installazzjoni ta' prometheus-operator fuq minikube huwa deskritt fid-dettall. Biex tippermetti l-persistenza, trid issettja l-parametru persistenza: vera fil-fajl charts/grafana/values.yaml, żid il-PV u l-PVC tiegħek stess u speċifikahom fil-parametru persistentence.existingClaim

L-iskript tat-tnedija tal-minikube finali tagħna jidher bħal dan:

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

Parti 3: żvilupp attwali

Mudell ta' Għan

Bi tħejjija għall-implimentazzjoni tal-plugin, iddeċidejna li niddeskrivu l-entitajiet bażiċi kollha ta 'Kubernetes li se naħdmu magħhom fil-forma ta' klassijiet TypeScript: pod, deployment, daemonset, statefulset, job, cronjob, service, node, namespace. Kull waħda minn dawn il-klassijiet tirret mill-klassi BaseModel komuni, li tiddeskrivi l-kostruttur, id-distruttur, il-metodi għall-aġġornament u l-bidla tal-viżibilità. Kull waħda mill-klassijiet tiddeskrivi relazzjonijiet nested ma' entitajiet oħra, pereżempju, lista ta 'miżwed għal entità ta' tip skjerament.

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

Bl-għajnuna ta 'getters u setters, nistgħu nuru jew nissettjaw il-metriċi tal-entità li għandna bżonn f'forma konvenjenti u li tinqara. Pereżempju, output ifformattjat ta' nodi CPU allokabbli:

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

paġni

Lista tal-paġni kollha tal-plugins tagħna hija inizjalment deskritta fil-pluing.json tagħna fit-taqsima tad-dipendenzi:

Żvilupp ta' plugin għal Grafana: storja ta' tiri kbar

Fil-blokk għal kull paġna rridu nindikaw l-ISEM TAL-PAĠNA (imbagħad tiġi kkonvertita fi slug li biha din il-paġna tkun aċċessibbli); l-isem tal-komponent responsabbli għat-tħaddim ta 'din il-paġna (il-lista tal-komponenti hija esportata lejn module.ts); li jindika r-rwol tal-utent li għalih ix-xogħol ma 'din il-paġna huwa disponibbli u s-settings tan-navigazzjoni għall-sidebar.

Fil-komponent responsabbli għall-operat tal-paġna, irridu nissettjaw templateUrl, u ngħaddu hemm it-triq għall-fajl html b'markup. Ġewwa l-kontrollur, permezz ta 'injezzjoni ta' dipendenza, nistgħu naċċessaw sa 2 servizzi angolari importanti:

  • backendSrv - servizz li jipprovdi interazzjoni mas-server tal-API Grafana;
  • datasourceSrv - servizz li jipprovdi interazzjoni lokali mas-sorsi tad-data kollha installati fil-Grafana tiegħek (per eżempju, il-metodu .getAll() - jirritorna lista tas-sorsi tad-data kollha installati; .get() ) - jirritorna oġġett ta 'istanza ta' datasource speċifika.

Żvilupp ta' plugin għal Grafana: storja ta' tiri kbar

Żvilupp ta' plugin għal Grafana: storja ta' tiri kbar

Żvilupp ta' plugin għal Grafana: storja ta' tiri kbar

Parti 4: sors tad-dejta

Mill-perspettiva ta' Grafana, id-datasource huwa eżattament l-istess plugin bħall-oħrajn kollha: għandu l-punt tad-dħul tiegħu module.js, hemm fajl b'meta informazzjoni plugin.json. Meta niżviluppaw plugin b'tip = app, nistgħu jinteraġixxu kemm ma 'sorsi tad-data eżistenti (per eżempju, prometheus-datasource) kif ukoll tagħna stess, li nistgħu naħżnu direttament fid-direttorju tal-plugin (dist/datasource/*) jew ninstallaw bħala dipendenza. Fil-każ tagħna, is-sors tad-data jiġi mal-kodiċi tal-plugin. Huwa wkoll meħtieġ li jkollok mudell config.html u kontrollur ConfigCtrl, li se jintużaw għall-paġna tal-konfigurazzjoni tal-istanza tad-datasource u l-kontrollur tad-Datasource, li jimplimenta l-loġika tad-datasource tiegħek.

Fil-plugin KubeGraf, mil-lat tal-interface tal-utent, is-sors tad-dejta huwa eżempju ta’ cluster kubernetes li jimplimenta l-kapaċitajiet li ġejjin (il-kodiċi tas-sors huwa disponibbli по ссылке):

  • ġbir ta' data mis-server api k8s (kiseb lista ta' namespaces, skjeramenti...)
  • proxy talbiet lil prometheus-datasource (li jintgħażel fis-settings tal-plugin għal kull cluster speċifiku) u tweġibiet ifformattjar biex tuża d-dejta kemm f'paġni statiċi kif ukoll f'dashboards.
  • aġġornament tad-dejta fuq paġni tal-plugin statiċi (b'rata ta' aġġornament stabbilita).
  • l-ipproċessar ta' mistoqsijiet biex jiġġenera folja mudell f'grafana-dashboards (metodu metriFindQuery())

Żvilupp ta' plugin għal Grafana: storja ta' tiri kbar

Żvilupp ta' plugin għal Grafana: storja ta' tiri kbar

Żvilupp ta' plugin għal Grafana: storja ta' tiri kbar

  • test ta 'konnessjoni mal-cluster finali 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"};
       })
}

Punt interessanti separat, fl-opinjoni tagħna, huwa l-implimentazzjoni ta 'mekkaniżmu ta' awtentikazzjoni u awtorizzazzjoni għas-sors tad-data. Tipikament, barra mill-kaxxa, nistgħu nużaw il-komponent Grafana integrat datasourceHttpSettings biex jiġi kkonfigurat l-aċċess għas-sors finali tad-dejta. Billi nużaw dan il-komponent, nistgħu kkonfiguraw l-aċċess għas-sors tad-dejta http billi nispeċifikaw l-url u s-settings bażiċi ta 'awtentikazzjoni/awtorizzazzjoni: login-password, jew client-cert/client-key. Sabiex timplimenta l-abbiltà li tikkonfigura l-aċċess bl-użu ta 'bearer token (l-istandard de facto għal k8s), kellna nagħmlu ftit tweaking.

Biex issolvi din il-problema, tista’ tuża l-mekkaniżmu integrat ta’ Grafana “Rotot tal-Plugin” (aktar dettalji fuq paġna tad-dokumentazzjoni uffiċjali). Fis-settings tas-sors tad-data tagħna, nistgħu niddikjaraw sett ta 'regoli ta' routing li se jiġu pproċessati mis-server proxy grafana. Pereżempju, għal kull endpoint individwali huwa possibbli li jiġu stabbiliti headers jew urls bil-possibbiltà ta 'templating, li d-dejta tagħhom tista' tittieħed mill-oqsma jsonData u secureJsonData (għall-ħażna ta' passwords jew tokens f'forma kriptata). Fl-eżempju tagħna, mistoqsijiet bħal /__proxy/api/v1/namespaces se jiġi prokurat għall-url tal-formola
/api/v8/namespaces bl-Awtorizzazzjoni: Header Bearer.

Żvilupp ta' plugin għal Grafana: storja ta' tiri kbar

Żvilupp ta' plugin għal Grafana: storja ta' tiri kbar

Naturalment, biex naħdmu mas-server k8s api għandna bżonn utent b'aċċess għall-qari biss, manifesti għall-ħolqien li tista' ssib ukoll f' kodiċi tas-sors tal-plugin.

Parti 5: rilaxx

Żvilupp ta' plugin għal Grafana: storja ta' tiri kbar

Ladarba tkun ktibt il-plugin Grafana tiegħek, naturalment tkun trid tagħmilha disponibbli pubblikament. Fi Grafana din hija librerija ta' plugins disponibbli hawn grafana.com/grafana/plugins

Sabiex il-plugin tiegħek ikun disponibbli fuq il-maħżen uffiċjali, trid tagħmel PR in dan ir-repożitorjubilli żżid kontenut bħal dan fil-fajl repo.json:

Żvilupp ta' plugin għal Grafana: storja ta' tiri kbar

fejn il-verżjoni hija l-verżjoni tal-plugin tiegħek, l-url hija link għar-repożitorju, u l-commit hija l-hash tal-commit li għalih tkun disponibbli verżjoni speċifika tal-plugin.

U fl-output se tara stampa mill-isbaħ bħal:

Żvilupp ta' plugin għal Grafana: storja ta' tiri kbar

Id-dejta għaliha tinqabad awtomatikament minn Readme.md, Changelog.md u l-fajl plugin.json tiegħek bid-deskrizzjoni tal-plugin.

Parti 6: minflok konklużjonijiet

Aħna ma waqfitx niżviluppaw il-plugin tagħna wara r-rilaxx. U issa qed naħdmu biex nissorveljaw b'mod korrett l-użu tar-riżorsi tan-nodi tal-clusters, nintroduċu karatteristiċi ġodda biex intejbu l-UX, u wkoll nirbħu ammont kbir ta' feedback li waslu wara l-installazzjoni tal-plugin kemm mill-klijenti tagħna kif ukoll minn nies fuq GitHub (jekk titlaq il-kwistjoni tiegħek jew it-talba tal-ġibda, inkun kuntent ħafna :)

Nittamaw li dan l-artikolu jgħinek tifhem għodda mill-isbaħ bħal Grafana u, forsi, tikteb il-plugin tiegħek.

Grazzi!)

Sors: www.habr.com

Ixtri hosting affidabbli għal siti bi protezzjoni DDoS, servers VPS VDS 🔥 Ixtri hosting ta' websajts affidabbli bi protezzjoni DDoS, servers VPS VDS | ProHoster