Entwécklung vun engem Plugin fir Grafana: eng Geschicht vu grousse Schëss

Moien alleguer! Virun e puer MĂ©int hu mir eisen neien Open-Source Projet an d'Produktioun lancĂ©iert - de Grafana Plugin fir d'Iwwerwaachung vu Kuberneten, dee mir genannt hunn DevOpsProdigy KubeGraf. De Plugin Quellcode ass verfĂŒgbar op Ă«ffentleche Repository op GitHub. An an dĂ«sem Artikel wĂ«lle mir mat Iech d'Geschicht deelen wĂ©i mir de Plugin erstallt hunn, wĂ©i eng Tools mir benotzt hunn a wĂ©i eng Falen mir am EntwĂ©cklungsprozess begĂ©int hunn. A lass!

Deel 0 - Aféierung: Wéi si mir op dëse Punkt komm?

D'Iddi fir eisen eegene Plugin fir Grafan ze schreiwen ass bei eis zimmlech zoufÀlleg komm. Eis Firma iwwerwaacht Webprojete vu verschiddene Komplexitéitsniveauen fir méi wéi 10 Joer. WÀrend dëser ZÀit hu mir eng grouss Quantitéit un Expertise gesammelt, interessant FÀll an Erfarung beim Gebrauch vu verschiddene Iwwerwaachungssystemer. An iergendwann hu mir eis gefrot: "Gëtt et e magescht Instrument fir d'Iwwerwaachung vu Kubernetes, sou datt, wéi se soen, "set et a vergiess et"? Prometheus + Grafana Kombinatioun. A wéi fÀerdeg Léisunge fir dëse Stack gëtt et e grousse Set vu verschiddenen Tools: Prometheus-Operateur, eng Rei vu kubernetes-mixin Dashboards, Grafana-kubernetes-App.

De Grafana-kubernetes-App Plugin schéngt déi interessantst Optioun fir eis ze sinn, awer et ass net méi wéi engem Joer ënnerstëtzt ginn an och kann net mat neie Versioune vun Node-Exporter a Kube-State-Metriken funktionnéieren. An iergendwann hu mir décidéiert: "Sollte mir net eis eegen Entscheedung treffen?"

Wéi eng Iddien hu mir decidéiert an eisem Plugin ëmzesetzen:

  • VisualisĂ©ierung vun der "Applikatiounskaart": praktesch Presentatioun vun Uwendungen am Cluster, gruppĂ©iert no Nummraim, Deployment ...;
  • VisualisĂ©ierung vu Verbindunge wĂ©i "Deployment - Service (+Ports)".
  • VisualisĂ©ierung vun der Verdeelung vu Clusterapplikatiounen iwwer Clusternoden.
  • Sammlung vu Metriken an Informatioun aus verschiddene Quellen: Prometheus an k8s API Server.
  • Iwwerwaachung vu bĂ©iden Infrastrukturen Deel (Notzung vun der CPU ZĂ€it, ErĂ«nnerung, Disk Subsystem, Netzwierk) an Uwendungslogik - Gesondheetsstatus Pods, Zuel vun verfĂŒgbare Repliken, Informatioun iwwer d'Liewer / Bereetschaftstester.

Deel 1: Wat ass e "Grafana Plugin"?

Aus technescher Siicht ass de Plugin fir Grafana e WĂ©nkelkontroller, deen am Grafana Datenverzeichnis (/var/grafana/plugins/ /dist/module.js) a kann als SystemJS Modul geluede ginn. Och an dĂ«sem Verzeechnes sollt et eng plugin.json Datei sinn, dĂ©i all Meta-Informatioun iwwer Äre Plugin enthĂ€lt: Numm, Versioun, Plugin-Typ, Linken op de Repository/Site/Lizenz, OfhĂ€ngegkeeten, a sou weider.

Entwécklung vun engem Plugin fir Grafana: eng Geschicht vu grousse Schëss
module.ts

Entwécklung vun engem Plugin fir Grafana: eng Geschicht vu grousse Schëss
plugin.json

Wéi Dir am Screenshot gesitt, hu mir plugin.type = app spezifizéiert. Well Plugins fir Grafana kënnen vun drÀi Aarte sinn:

Kompletéiert: déi allgemeng Aart vu Plugin - et ass e Panel fir all Metrik ze visualiséieren, benotzt fir verschidde Dashboards ze bauen.
Datenquell: Plugin Connector op eng Datenquell (zum Beispill Prometheus-Datenquelle, ClickHouse-Datenquelle, ElasticSearch-Datenquelle).
App: E Plugin deen Iech erlaabt Är eege Frontend-Applikatioun bannent Grafana ze bauen, Är eege HTML SĂ€iten ze kreĂ©ieren an manuell op d'Datequelle ze kommen fir verschidden DonnĂ©eĂ«n ze visualisĂ©ieren. Och Plugins vun aneren Typen (Datenquelle, Panel) a verschidde Dashboards kĂ«nnen als OfhĂ€ngegkeet benotzt ginn.

Entwécklung vun engem Plugin fir Grafana: eng Geschicht vu grousse Schëss
Beispill Plugin OfhÀngegkeeten mat Typ = App.

Dir kënnt souwuel JavaScript wéi och TypeScript als Programméierungssprooch benotzen (mir hunn et gewielt). Virbereedunge fir Hallo-Welt Plugins vun all Typ Dir kënnt fannen de Link: Dëse Repository enthÀlt eng grouss Zuel vu Starter-PÀck (et gëtt souguer en experimentellt Beispill vun engem Plugin am React) mat virinstalléierten a konfiguréierte Builder.

Deel 2: Virbereedung vun der lokaler Ëmwelt

Fir um Plugin ze schaffen, brauche mir natierlech e Kubernetes-Cluster mat all de virinstallĂ©ierten Tools: Prometheus, Node-Exporter, Kube-State-Metrics, Grafana. D'Ëmfeld soll sĂ©ier, einfach an natierlech ageriicht ginn, a fir Hot-Reload ze garantĂ©ieren, sollt de Grafana Dateverzeichnis direkt vun der Maschinn vum EntwĂ©ckler montĂ©iert ginn.

DĂ©i bequemste ManĂ©ier, eiser Meenung no, fir lokal mat kubernetes ze schaffen ass minikube. De nĂ€chste SchrĂ«tt ass d'Prometheus + Grafana Kombinatioun mat Prometheus-Operator z'installĂ©ieren. IN dĂ«sen Artikel De Prozess vun der Installatioun vum Prometheus-Bedreiwer op Minikube gĂ«tt am Detail beschriwwen. Fir Persistenz z'aktivĂ©ieren, musst Dir de Parameter setzen Persistenz: wouer an den Charts/grafana/values.yaml Datei, fĂŒĂŒgt Ären eegene PV a PVC derbĂ€i a spezifizĂ©iert se am Persistence.existingClaim Parameter

Eis lescht Minikube Startskript gesÀit esou aus:

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

Deel 3: tatsÀchlech Entwécklung

Objektmodell

Als Virbereedung fir d'Ëmsetzung vum Plugin hu mir beschloss all Basis Kubernetes EntitĂ©iten ze beschreiwen, mat deenen mir a Form vun TypeScript Klassen schaffen: Pod, Deployment, Daemonset, Statefulset, Job, Cronjob, Service, Node, Nummraum. All eenzel vun dĂ«se Klassen ierft aus der gemeinsamer BaseModel Klass, dĂ©i beschreift de constructor, destructor, Methode fir AktualisĂ©ierung opgetrueden an Wiessel VisibilitĂ©it. Jiddereng vun de Klassen beschreift nested Relatiounen mat aneren EntitĂ©ite, Zum Beispill, eng LĂ«scht vun pods fir eng EntitĂ©it vun Typ Deployment.

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

Mat der Hëllef vu Getters a Setzer kënne mir d'Entitéitsmetriken weisen oder setzen déi mir brauchen an enger praktescher a liesbarer Form. Zum Beispill, formatéiert Ausgang vun allocatable CPU Noden:

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

SĂ€iten

Eng Lëscht vun all eise Plugin SÀiten gëtt ufanks an eisem pluing.json an der OfhÀngegkeetssektioun beschriwwen:

Entwécklung vun engem Plugin fir Grafana: eng Geschicht vu grousse Schëss

Am Block fir all SĂ€it musse mir de PAGE NAME uginn (en gĂ«tt dann an e Slug Ă«mgewandelt, duerch deen dĂ«s SĂ€it zougĂ€nglech ass); den Numm vun der Komponent verantwortlech fir d'Operatioun vun dĂ«ser SĂ€it (d'LĂ«scht vun de Komponenten gĂ«tt op module.ts exportĂ©iert); dĂ©i d'Benotzerroll uginn fir dĂ©i d'Aarbecht mat dĂ«ser SĂ€it verfĂŒgbar ass an d'Navigatiounsastellunge fir d'Sidebar.

An der Komponent verantwortlech fir d'Operatioun vun der SÀit, musse mir TemplateUrl setzen, de Wee an d'HTML-Datei mat Markup laanschtgoen. Bannen am Controller, duerch OfhÀngegkeetsinjektioun, kënne mir bis zu 2 wichteg Wénkelservicer zougrÀifen:

  • backendSrv - e Service deen Interaktioun mam Grafana API Server ubitt;
  • datasourceSrv - e Service deen lokal Interaktioun mat all Datenquellen ubitt, dĂ©i an Ärem Grafana installĂ©iert sinn (zum Beispill d'.getAll() Method - gĂ«tt eng LĂ«scht vun all installĂ©ierten Datequellen zrĂ©ck; .get( ) - gĂ«tt en Instanzobjekt vun enger spezifescher Datenquell zrĂ©ck.

Entwécklung vun engem Plugin fir Grafana: eng Geschicht vu grousse Schëss

Entwécklung vun engem Plugin fir Grafana: eng Geschicht vu grousse Schëss

Entwécklung vun engem Plugin fir Grafana: eng Geschicht vu grousse Schëss

Deel 4: Daten Quell

Vun Grafana Siicht, Datasource genee dĂ©i selwecht Plugin wĂ©i all dĂ©i aner: et huet seng eege EntrĂ©en Punkt module.js, et gĂ«tt e Fichier mat Meta Informatiounen plugin.json. Wann Dir e Plugin mat Typ = App entwĂ©ckelen, kĂ«nne mir souwuel mat existĂ©ierende Datequellen interagĂ©ieren (zum Beispill, prometheus-datasource) an eis eegen, dĂ©i mir direkt am Plugin-Verzeichnis spĂ€icheren (dist/datasource/*) oder als OfhĂ€ngegkeet installĂ©ieren. An eisem Fall kĂ«nnt d'Datenquelle mam Plugin Code. Et ass och noutwendeg eng config.html Schabloun an e ConfigCtrl Controller ze hunn, dĂ©i fir d'Datenquell Instanz KonfiguratiounssĂ€it an den Datasource Controller benotzt gĂ«tt, deen d'Logik vun Ärer Datequell implementĂ©iert.

Am KubeGraf Plugin, aus der User-Interface Siicht, ass d'Datenquell eng Instanz vun engem kubernetes-Cluster deen dĂ©i folgend FĂ€egkeeten implementĂ©iert (Quellcode ass verfĂŒgbar Link):

  • sammelen Daten vum k8s api-Server (krĂ©ien eng LĂ«scht vun Nummraim, Deployment ...)
  • Proxying Ufroe fir prometheus-Datenquelle (dĂ©i an de Plugin-Astellunge fir all spezifesche Cluster ausgewielt gĂ«tt) an d'FormatĂ©ierung vun Äntwerte fir Daten souwuel op statesche SĂ€iten an an Dashboards ze benotzen.
  • d'AktualisĂ©ierung vun Daten op statesche Plugin SĂ€iten (mat engem festgeluegten ErfrĂ«schungsrate).
  • Veraarbechtung vun Ufroen fir e Schablounblat a Grafana-Dashboards ze generĂ©ieren (metriFindQuery () Method)

Entwécklung vun engem Plugin fir Grafana: eng Geschicht vu grousse Schëss

Entwécklung vun engem Plugin fir Grafana: eng Geschicht vu grousse Schëss

Entwécklung vun engem Plugin fir Grafana: eng Geschicht vu grousse Schëss

  • Verbindung Test mat der Finale k8s StĂ€rekoup.
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"};
       })
}

En separaten interessante Punkt, eiser Meenung no, ass d'Ëmsetzung vun engem Authentifikatiouns- an Autorisatiounsmechanismus fir d'Datequelle. Typesch, aus der KĂ«scht, kĂ«nne mir dĂ©i agebaute Grafana Komponent DatasourceHttpSettings benotzen fir den Zougang zu der definitiver Datequell ze konfigurĂ©ieren. Mat dĂ«ser Komponente kĂ«nne mir den Zougang zu der http Datenquell konfigurĂ©ieren andeems Dir d'URL an d'Basis Authentifikatioun / Autorisatioun Astellunge spezifizĂ©iert: Login-Passwuert oder Client-cert/client-key. Fir d'FĂ€egkeet ze realisĂ©ieren den Zougang mat engem Bearer Token ze konfigurĂ©ieren (de de facto Standard fir k8s), hu mir e bĂ«ssen Tweaking misse maachen.

Fir dëse Problem ze léisen, kënnt Dir den agebaute Grafana "Plugin Routes" Mechanismus benotzen (méi Detailer op offiziell Dokumentatioun SÀit). An den Astellunge vun eiser Datessource kënne mir eng Rei vu Routingregelen deklaréieren, déi vum Grafana Proxy Server veraarbecht ginn. Zum Beispill, fir all eenzel Endpunkt ass et méiglech Header oder URLen mat der Méiglechkeet vun Template ze setzen, Daten fir déi aus de jsonData a secureJsonData Felder geholl kënne ginn (fir Passwierder oder Tokens a verschlësselte Form ze spÀicheren). An eisem Beispill, Ufroen wéi /__proxy/api/v1/namespaces gëtt op d'URL vum Formulaire proxéiert
/api/v8/namespaces mat der Autorisatioun: Bearer Header.

Entwécklung vun engem Plugin fir Grafana: eng Geschicht vu grousse Schëss

Entwécklung vun engem Plugin fir Grafana: eng Geschicht vu grousse Schëss

Natierlech, fir mam k8s API Server ze schaffen, brauche mir e Benotzer mat nëmmen liesen Zougang, Manifestatiounen fir ze kreéieren déi Dir och fannt Plugin Quellcode.

Deel 5: FrÀisetzung

Entwécklung vun engem Plugin fir Grafana: eng Geschicht vu grousse Schëss

Wann Dir Ären eegene Grafana Plugin geschriwwen hutt, wĂ«llt Dir se natierlech Ă«ffentlech verfĂŒgbar maachen. Zu Grafana ass dĂ«st eng BibliothĂ©ik vu Plugins dĂ©i hei verfĂŒgbar sinn grafana.com/grafana/plugins

Fir datt Äre Plugin am offiziellen GeschĂ€ft verfĂŒgbar ass, musst Dir e PR maachen dĂ«se Repositoryandeems Dir Inhalt wĂ©i dĂ«sen an d'repo.json Datei addĂ©iert:

Entwécklung vun engem Plugin fir Grafana: eng Geschicht vu grousse Schëss

wou Versioun d'Versioun vun Ärem Plugin ass, URL ass e Link op de Repository, an commit ass den Hash vum Engagement fir deen eng spezifesch Versioun vum Plugin verfĂŒgbar ass.

An op der Ausgab gesitt Dir eng wonnerbar Bild wéi:

Entwécklung vun engem Plugin fir Grafana: eng Geschicht vu grousse Schëss

D'DonnĂ©eĂ«n dofir ginn automatesch vun Ärem Readme.md, Changelog.md an der plugin.json Datei mat der Plugin Beschreiwung gegraff.

Deel 6: amplaz Conclusiounen

Mir hunn net opgehalen eise Plugin no der VerĂ«ffentlechung z'entwĂ©ckelen. An elo schaffe mir un der korrekter Iwwerwaachung vun der Notzung vu Ressourcen vu Clusternoden, nei Fonctiounen afĂ©ieren fir d'UX ze verbesseren, an och eng grouss QuantitĂ©it vu Feedback erakommen, dĂ©i no der Installatioun vum Plugin souwuel vun eise Clienten wĂ©i och vu Leit op GitHub (wann Dir verloosst) Är Fro oder Pull Ufro, ech wĂ€ert ganz frou sinn :)

Mir hoffen, datt dĂ«sen Artikel Iech hĂ«lleft esou e wonnerbare Tool wĂ©i Grafana ze verstoen an, vlĂ€icht, Ären eegene Plugin ze schreiwen.

Merci!)

Source: will.com

Kaaft zouverlĂ€sseg Hosting fir Site mat DDoS Schutz, VPS VDS Server đŸ”„ Kaaft zouverlĂ©issegt WebsĂ€ithosting mat DDoS-Schutz, VPS VDS Server | ProHoster