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
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.
modulo.ts
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.
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
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
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:
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.
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
- 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())
- 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
/api/v8/namespaces kun la Rajtigo: Portanto-kapo.
Kompreneble, por labori kun la k8s api-servilo ni bezonas uzanton kun nurlegebla aliro, manifestojn por krei, kiujn vi ankaŭ povas trovi en
Parto 5: liberigo
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
Por ke via kromaĵo estu disponebla en la oficiala vendejo, vi devas fari PR en
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:
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