Disvolviĝo de kromaĵo por Grafana: historio de grandaj pafoj

Saluton al ĉiuj! Antaŭ kelkaj monatoj, ni lanĉis nian novan malfermfontan projekton en produktadon - la aldonaĵon Grafana por monitorado de kubernetoj, kiun ni nomis DevOpsProdigy KubeGraf. La aldonaĵa fontkodo haveblas ĉe publika deponejo sur GitHub. Kaj en ĉi tiu artikolo ni volas dividi kun vi la rakonton pri kiel ni kreis la kromprogramon, kiajn ilojn ni uzis kaj kiajn malfacilaĵojn ni renkontis dum la disvolva procezo. Ni iru!

Parto 0 - enkonduka: kiel ni alvenis al ĉi tiu punkto?

La ideo verki nian propran kromprogramon por Grafan venis al ni tute hazarde. Nia kompanio monitoras retajn projektojn de diversaj niveloj de komplekseco dum pli ol 10 jaroj. Dum ĉi tiu tempo, ni amasigis grandan kvanton da kompetenteco, interesaj kazoj kaj sperto en uzado de diversaj monitoraj sistemoj. Kaj iam ni demandis nin: "Ĉu ekzistas magia ilo por monitori Kubernetes, por ke, kiel oni diras, "agordu ĝin kaj forgesu ĝin"?".. La industria normo por monitorado de k8s, kompreneble, delonge estas la Prometheus + Grafana kombinaĵo. Kaj kiel pretaj solvoj por ĉi tiu stako, ekzistas granda aro de diversaj specoj de iloj: prometheus-operator, aro de kubernetes-mixin paneloj, grafana-kubernetes-app.

La kromaĵo grafana-kubernetes-app ŝajnis esti la plej interesa opcio por ni, sed ĝi ne estas subtenata de pli ol unu jaro kaj, krome, ne povas funkcii kun novaj versioj de node-exporter kaj kube-state-metrics. Kaj iam ni decidis: "Ĉu ni ne devus fari nian propran decidon?"

Kiajn ideojn ni decidis efektivigi en nia kromaĵo:

  • bildigo de la "aplikmapo": oportuna prezento de aplikaĵoj en la areto, grupigitaj per nomspacoj, disfaldoj...;
  • bildigo de konektoj kiel "deplojo - servo (+havenoj)".
  • bildigo de la distribuado de cluster-aplikoj trans aretnodoj.
  • kolekto de metrikoj kaj informoj de pluraj fontoj: Prometheus kaj k8s api-servilo.
  • monitorado de kaj la infrastruktura parto (uzo de CPU-tempo, memoro, disksubsistemo, reto) kaj aplikaĵa logiko - sano-stato podoj, nombro da disponeblaj kopioj, informoj pri pasigado de viveco/pretectestoj.

Parto 1: Kio estas "Grafana kromaĵo"?

De teknika vidpunkto, la kromaĵo por Grafana estas angula regilo, kiu estas konservita en la datumdosierujo de Grafana (/var/grafana/kromaĵoj/ /dist/module.js) kaj povas esti ŝarĝita kiel SystemJS-modulo. Ankaŭ en ĉi tiu dosierujo devus esti plugin.json-dosiero enhavanta ĉiujn metainformojn pri via kromaĵo: nomo, versio, kromaĵo-tipo, ligiloj al la deponejo/retejo/licenco, dependecoj, ktp.

Disvolviĝo de kromaĵo por Grafana: historio de grandaj pafoj
modulo.ts

Disvolviĝo de kromaĵo por Grafana: historio de grandaj pafoj
plugin.json

Kiel vi povas vidi en la ekrankopio, ni specifis plugin.type = app. Ĉar kromprogramoj por Grafana povas esti de tri tipoj:

panelo: la plej ofta speco de kromaĵo - ĝi estas panelo por bildigi ajnajn metrikojn, uzata por konstrui diversajn instrumentpanelojn.
datumfonto: kromaĵo-konektilo al iu datumfonto (ekzemple, Prometheus-datumfonto, ClickHouse-datumfonto, ElasticSearch-datumfonto).
app: Kromaĵo, kiu ebligas al vi konstrui vian propran fasan aplikaĵon ene de Grafana, krei viajn proprajn html-paĝojn kaj permane aliri la datumfonton por bildigi diversajn datumojn. Ankaŭ, kromaĵoj de aliaj tipoj (datumfonto, panelo) kaj diversaj paneloj povas esti uzataj kiel dependecoj.

Disvolviĝo de kromaĵo por Grafana: historio de grandaj pafoj
Ekzemplaj kromprogramoj kun tipo=app.

Vi povas uzi kaj JavaScript kaj TypeScript kiel programlingvon (ni elektis ĝin). Preparoj por salutmondaj kromaĵoj de ajna tipo, kiun vi povas trovi la ligilon: ĉi tiu deponejo enhavas grandan nombron da startpakoj (ekzistas eĉ eksperimenta ekzemplo de kromaĵo en React) kun antaŭinstalitaj kaj agorditaj konstruantoj.

Parto 2: prepari la lokan medion

Por labori pri la kromaĵo, ni nature bezonas kubernetes-grupon kun ĉiuj antaŭinstalitaj iloj: prometheus, node-exporter, kube-state-metrics, grafana. La medio devas esti agordita rapide, facile kaj nature, kaj por certigi varman reŝargon, la datumdosierujo Grafana devas esti muntita rekte de la maŝino de la programisto.

La plej oportuna maniero, laŭ nia opinio, labori loke kun kubernetes estas minikube. La sekva paŝo estas instali la kombinaĵon Prometheus + Grafana uzante prometheus-operator. EN ĉi tiu artikolo La procezo de instalado de prometheus-operator sur minikube estas detale priskribita. Por ebligi persiston, vi devas agordi la parametron persisto: vera en la dosiero charts/grafana/values.yaml, aldonu viajn proprajn PV kaj PVC kaj specifu ilin en la parametro persistence.existingClaim

Nia fina lanĉa skripto de minikube aspektas jene:

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

Parto 3: efektiva evoluo

Objekta Modelo

Prepare por efektivigi la kromprogramon, ni decidis priskribi ĉiujn bazajn Kubernetes-entaĵojn kun kiuj ni laboros en la formo de TypeScript-klasoj: pod, deplojo, daemonset, statefulset, laboro, cronjob, servo, nodo, nomspaco. Ĉiu el ĉi tiuj klasoj heredas de la komuna BaseModel-klaso, kiu priskribas la konstruanton, detruanton, metodojn por ĝisdatigi kaj ŝanĝi videblecon. Ĉiu el la klasoj priskribas nestitajn rilatojn kun aliaj estaĵoj, ekzemple, liston de balgoj por ento de tipo deplojo.

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

Kun la helpo de getters kaj setters, ni povas montri aŭ agordi la entajn metrikojn, kiujn ni bezonas en oportuna kaj legebla formo. Ekzemple, formatita eligo de asigneblaj cpu-nodoj:

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

paĝoj

Listo de ĉiuj niaj krompaĝoj estas komence priskribita en nia pluing.json en la sekcio de dependecoj:

Disvolviĝo de kromaĵo por Grafana: historio de grandaj pafoj

En la bloko por ĉiu paĝo ni devas indiki la PAĜNOMON (ĝi tiam estos konvertita en slug per kiu ĉi tiu paĝo estos alirebla); la nomo de la komponanto respondeca por la funkciado de ĉi tiu paĝo (la listo de komponantoj estas eksportita al module.ts); indikante la uzantrolon por kiu laboro kun ĉi tiu paĝo estas disponebla kaj navigadajn agordojn por la flanka kolumno.

En la komponanto respondeca por la funkciado de la paĝo, ni devas agordi templateUrl, pasante tie la vojon al la html-dosiero kun markado. Ene de la regilo, per dependeca injekto, ni povas aliri ĝis 2 gravajn angulajn servojn:

  • backendSrv - servo kiu provizas interagadon kun la Grafana API-servilo;
  • datasourceSrv - servo kiu provizas lokan interagadon kun ĉiuj datumfontoj instalitaj en via Grafana (ekzemple, la .getAll() metodo - liveras liston de ĉiuj instalitaj datumfontoj; .get( ) - resendas ekzemplobjekton de specifa datumfonto.

Disvolviĝo de kromaĵo por Grafana: historio de grandaj pafoj

Disvolviĝo de kromaĵo por Grafana: historio de grandaj pafoj

Disvolviĝo de kromaĵo por Grafana: historio de grandaj pafoj

Parto 4: datumfonto

El la vidpunkto de Grafana, datumfonto estas ĝuste la sama kromaĵo kiel ĉiuj aliaj: ĝi havas sian propran enirpunkton module.js, ekzistas dosiero kun meta-informo plugin.json. Dum evoluado de kromaĵo kun tipo = app, ni povas interagi kun ambaŭ ekzistantaj datumfontoj (ekzemple, prometheus-datasource) kaj niaj propraj, kiujn ni povas konservi rekte en la kromprogramo (dist/datasource/*) aŭ instali kiel dependeco. En nia kazo, la datumfonto venas kun la kromprogramo. Ankaŭ necesas havi config.html ŝablonon kaj ConfigCtrl-regilon, kiu estos uzata por la agorda paĝo de datumfonto kaj la datumfonto-regilo, kiu efektivigas la logikon de via datumfonto.

En la kromaĵo KubeGraf, de la vidpunkto de la uzantinterfaco, la datumfonto estas ekzemplo de kubernetes-areo kiu efektivigas la jenajn kapablojn (fontokodo disponeblas ligilo):

  • kolektado de datumoj de la api-servilo k8s (akiranta liston de nomspacoj, deplojoj...)
  • prokurado de petoj al prometheus-datasource (kiu estas elektita en la aldonaĵagordoj por ĉiu specifa areto) kaj formatado de respondoj por uzi datumojn kaj en senmovaj paĝoj kaj en paneloj.
  • ĝisdatigi datumojn sur senmovaj krompaĝoj (kun fiksita refreŝiga indico).
  • prilaborado de demandoj por generi ŝablonan folion en grafana-paneloj (metodo metriFindQuery())

Disvolviĝo de kromaĵo por Grafana: historio de grandaj pafoj

Disvolviĝo de kromaĵo por Grafana: historio de grandaj pafoj

Disvolviĝo de kromaĵo por Grafana: historio de grandaj pafoj

  • konektotesto kun la fina k8s-areto.
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"};
       })
}

Aparta interesa punkto, laŭ nia opinio, estas la efektivigo de aŭtentikiga kaj rajtiga mekanismo por la datumfonto. Tipe, el la skatolo, ni povas uzi la enkonstruitan Grafana-komponentan datufontonHttpSettings por agordi aliron al la fina datumfonto. Uzante ĉi tiun komponanton, ni povas agordi aliron al la http-datumfonto specifante la url kaj bazajn aŭtentikajn/rajtigajn agordojn: ensalutu-pasvorto aŭ kliento-cert/kliento-ŝlosilo. Por efektivigi la kapablon agordi aliron uzante portantan ĵetonon (la fakta normo por k8s), ni devis iom ĝustigi.

Por solvi ĉi tiun problemon, vi povas uzi la enkonstruitan mekanismon Grafana "Plugin Routes" (pli da detaloj ĉe oficiala dokumenta paĝo). En la agordoj de nia datumfonto, ni povas deklari aron da enrutaj reguloj, kiuj estos prilaboritaj de la prokura servilo grafana. Ekzemple, por ĉiu individua finpunkto eblas agordi kapliniojn aŭ URL-ojn kun la ebleco de ŝablono, por kiuj datumoj povas esti prenitaj el la kampoj jsonData kaj secureJsonData (por konservi pasvortojn aŭ ĵetonojn en ĉifrita formo). En nia ekzemplo, demandoj kiel /__proxy/api/v1/nomspacoj estos proksimita al la url de la formo
/api/v8/namespaces kun la Rajtigo: Portanto-kapo.

Disvolviĝo de kromaĵo por Grafana: historio de grandaj pafoj

Disvolviĝo de kromaĵo por Grafana: historio de grandaj pafoj

Kompreneble, por labori kun la k8s api-servilo ni bezonas uzanton kun nurlegebla aliro, manifestojn por krei, kiujn vi ankaŭ povas trovi en kromaĵo fontkodo.

Parto 5: liberigo

Disvolviĝo de kromaĵo por Grafana: historio de grandaj pafoj

Post kiam vi verkis vian propran aldonaĵon Grafana, vi nature volas disponigi ĝin publike. En Grafana ĉi tio estas biblioteko de kromaĵoj disponeblaj ĉi tie grafana.com/grafana/plugins

Por ke via kromaĵo estu disponebla en la oficiala vendejo, vi devas fari PR en ĉi tiu deponejoaldonante enhavon kiel ĉi tiu al la repo.json dosiero:

Disvolviĝo de kromaĵo por Grafana: historio de grandaj pafoj

kie versio estas la versio de via kromaĵo, url estas ligilo al la deponejo, kaj commit estas la hash de la kommit por kiu specifa versio de la kromaĵo estos disponebla.

Kaj ĉe la eligo vi vidos mirindan bildon kiel:

Disvolviĝo de kromaĵo por Grafana: historio de grandaj pafoj

La datumoj por ĝi estos aŭtomate kaptitaj de via Readme.md, Changelog.md kaj la plugin.json-dosiero kun la kromaĵo-priskribo.

Parto 6: anstataŭ konkludoj

Ni ne ĉesis disvolvi nian kromprogramon post liberigo. Kaj nun ni laboras ĝuste pri monitorado de la uzado de rimedoj de grapolnodoj, enkonduko de novaj funkcioj por plibonigi UX, kaj ankaŭ pritrakti grandan kvanton da sugestoj ricevitaj post instalo de la kromprogramo kaj de niaj klientoj kaj de homoj en GitHub (se vi forlasas). via afero aŭ tira peto, mi mi estos tre feliĉa :)

Ni esperas, ke ĉi tiu artikolo helpos vin kompreni tian mirindan ilon kiel Grafana kaj, eble, skribi vian propran kromprogramon.

Dankon!)

fonto: www.habr.com

Aldoni komenton