A Grafana bővítményének fejlesztése: nagy sikerek története

Sziasztok! Néhány hónappal ezelőtt elindítottuk az új nyílt forráskódú projektünket a termelésben - a kubernetes figyelésére szolgáló Grafana bővítményt, amelyet elhívtunk. DevOpsProdigy KubeGraf. A beépülő modul forráskódja a következő címen érhető el nyilvános adattár a GitHubon. Ebben a cikkben pedig szeretnénk megosztani veletek a bővítmény létrehozásának történetét, milyen eszközöket használtunk, és milyen buktatókkal találkoztunk a fejlesztési folyamat során. Gyerünk!

0. rész - bevezető: hogyan jutottunk el idáig?

Egészen véletlenül támadt bennünk az ötlet, hogy írjunk saját bővítményt a Grafan számára. Cégünk több mint 10 éve figyeli a különböző bonyolultságú webprojekteket. Ezalatt az idő alatt nagy mennyiségű szakértelmet, érdekes eseteket, tapasztalatokat halmoztunk fel a különböző monitoring rendszerek használatában. És egy ponton feltettük magunknak a kérdést: „Van valami varázseszköz a Kubernetes figyelésére, hogy – ahogy mondani szokás – „állítsd be és felejtsd el”?”. A k8-ak figyelésének iparági szabványa természetesen régóta a Prometheus + Grafana kombináció. És kész megoldásként ehhez a veremhez számos különféle eszköz található: prometheus-operator, kubernetes-mixin irányítópultok, grafana-kubernetes-app.

Számunkra a grafana-kubernetes-app plugin tűnt a legérdekesebb lehetőségnek, de már több mint egy éve nem támogatott, ráadásul nem működik a node-exporter és a kube-state-metrics új verzióival. És valamikor úgy döntöttünk: „Nem kellene magunk döntenünk?”

Milyen ötleteket határoztunk meg a bővítményünkben:

  • az „alkalmazástérkép” megjelenítése: az alkalmazások kényelmes bemutatása a fürtben, névterek, telepítések szerint csoportosítva...;
  • kapcsolatok megjelenítése, mint például a „telepítés - szolgáltatás (+portok)”.
  • a fürt alkalmazások fürtcsomópontok közötti eloszlásának megjelenítése.
  • metrikák és információk gyűjteménye több forrásból: Prometheus és k8s api szerver.
  • mind az infrastrukturális rész (CPU-idő, memória, lemez-alrendszer, hálózat) és alkalmazáslogika monitorozása - állapotjelző pod-ok, elérhető replikák száma, életképességi/készenléti tesztek teljesítésével kapcsolatos információk.

1. rész: Mi az a „Grafana plugin”?

Technikai szempontból a Grafana beépülő modulja egy szögvezérlő, amely a Grafana adatkönyvtárában (/var/grafana/plugins/ /dist/module.js), és SystemJS modulként tölthető be. Szintén ebben a könyvtárban kell lennie egy plugin.json fájlnak, amely tartalmazza a beépülő modul összes metainformációját: név, verzió, beépülő modul típusa, hivatkozások a tárhelyre/webhelyre/licencre, függőségek és így tovább.

A Grafana bővítményének fejlesztése: nagy sikerek története
modul.ts

A Grafana bővítményének fejlesztése: nagy sikerek története
plugin.json

Amint a képernyőképen látható, a plugin.type = app-ot adtuk meg. Mivel a Grafana beépülő moduljai háromféleek lehetnek:

panel: a legelterjedtebb beépülő modul - ez egy panel bármilyen mérőszám megjelenítésére, amelyet különféle irányítópultok készítésére használnak.
adatforrás: plugin csatlakozó valamilyen adatforráshoz (például Prometheus-adatforrás, ClickHouse-adatforrás, ElasticSearch-adatforrás).
app: Beépülő modul, amely lehetővé teszi saját frontend alkalmazás létrehozását a Grafana belsejében, saját html-oldalak létrehozását, valamint az adatforrás kézi elérését különféle adatok megjelenítéséhez. Ezenkívül más típusú bővítmények (adatforrás, panel) és különféle irányítópultok is használhatók függőségekként.

A Grafana bővítményének fejlesztése: nagy sikerek története
Példa beépülő modul-függőségekre a type=app paraméterrel.

Programozási nyelvként használhatja a JavaScriptet és a TypeScriptet is (ezt választottuk). Előkészületek bármilyen típusú hello-world bővítményhez megtalálja a linket: ez a tároló nagyszámú kezdőcsomagot tartalmaz (még a Reactban van egy kísérleti példa is egy bővítményre) előre telepített és konfigurált építőkkel.

2. rész: a helyi környezet előkészítése

A bővítményen való munkához természetesen szükségünk van egy kubernetes-fürtre az összes előre telepített eszközzel: prometheus, node-exporter, kube-state-metrics, grafana. A környezetet gyorsan, egyszerűen és természetesen kell beállítani, és a hot-reload biztosításához a Grafana adatkönyvtárat közvetlenül a fejlesztő gépéről kell felcsatolni.

Véleményünk szerint a legkényelmesebb módja a kubernetes helyi együttműködésének minikube. A következő lépés a Prometheus + Grafana kombináció telepítése a prometheus-operator segítségével. BAN BEN ez a cikk A prometheus-operator minikube-ra történő telepítésének folyamata részletesen le van írva. A perzisztencia engedélyezéséhez be kell állítani a paramétert kitartás: igaz a charts/grafana/values.yaml fájlban adja hozzá saját PV-jét és PVC-jét, és adja meg őket a persistence.existingClaim paraméterben

A végső minikube indító szkriptünk így néz ki:

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. rész: tényleges fejlesztés

Objektummodell

A beépülő modul megvalósításának előkészítéseként úgy döntöttünk, hogy TypeScript osztályok formájában leírjuk az összes alapvető Kubernetes entitást, amellyel dolgozni fogunk: pod, telepítés, démonset, állapotkészlet, feladat, cronjob, szolgáltatás, csomópont, névtér. Ezen osztályok mindegyike a közös BaseModel osztályból örökli, amely leírja a konstruktort, a destruktort, a láthatóság frissítésének és váltásának metódusait. Az egyes osztályok beágyazott kapcsolatokat írnak le más entitásokkal, például egy telepítési típusú entitás pod-listáját.

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

A getterek és setterek segítségével kényelmes és olvasható formában tudjuk megjeleníteni vagy beállítani a számunkra szükséges entitásmérőket. Például az allokálható CPU-csomópontok formázott kimenete:

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

Oldalak

Az összes beépülő modulunk listája először a pluing.json fájlban található a függőségek szakaszban:

A Grafana bővítményének fejlesztése: nagy sikerek története

Az egyes oldalak blokkjában meg kell jelölnünk az OLDAL NEVÉT (ezt ezután egy slug-vá alakítjuk, amely által ez az oldal elérhető lesz); az oldal működéséért felelős komponens neve (az összetevők listája a module.ts-be kerül exportálásra); jelzi a felhasználói szerepkört, amelyhez ez az oldal elérhető, és az oldalsáv navigációs beállításait.

Az oldal működéséért felelős komponensben be kell állítanunk a templateUrl-t, átadva ott a html fájl elérési útját jelöléssel. A vezérlőn belül a függőségi befecskendezéssel akár 2 fontos szögszolgáltatást is elérhetünk:

  • backendSrv - olyan szolgáltatás, amely interakciót biztosít a Grafana API-kiszolgálóval;
  • datasourceSrv – egy szolgáltatás, amely helyi interakciót biztosít a Grafana-ba telepített összes adatforrással (például a .getAll() metódus) – visszaadja az összes telepített adatforrás listáját; .get( ) - egy adott adatforrás példányobjektumát adja vissza.

A Grafana bővítményének fejlesztése: nagy sikerek története

A Grafana bővítményének fejlesztése: nagy sikerek története

A Grafana bővítményének fejlesztése: nagy sikerek története

4. rész: adatforrás

A Grafana szemszögéből az adatforrás pontosan ugyanaz a plugin, mint az összes többi: saját belépési pontja module.js, van egy fájl metainformációkkal plugin.json. A type = app bővítmény fejlesztésekor a meglévő adatforrásokkal (például prometheus-datasource) és a sajátunkkal is interakcióba léphetünk, amit közvetlenül a plugin könyvtárában (dist/datasource/*) tárolhatunk, vagy függőségként telepíthetünk. Esetünkben az adatforrás a beépülő modul kódjával érkezik. Szükséges továbbá egy config.html sablon és egy ConfigCtrl vezérlő, amely az adatforrás-példány konfigurációs oldalához lesz használva, valamint az adatforrás logikáját megvalósító Datasource vezérlő.

A KubeGraf beépülő modulban a felhasználói felület szempontjából az adatforrás egy kubernetes-fürt példánya, amely a következő képességeket valósítja meg (forráskód elérhető по ссылке):

  • adatok gyűjtése a k8s api-szerverről (névterek, telepítések listájának lekérése...)
  • proxy kérések a prometheus-datasource-hoz (amely az egyes fürtök beépülő modul-beállításaiban van kiválasztva), és a válaszok formázása az adatok statikus oldalakon és irányítópultokon történő használatához.
  • adatok frissítése statikus bővítményoldalakon (beállított frissítési gyakorisággal).
  • lekérdezések feldolgozása sablonlap létrehozásához grafana-dashboardokban (metriFindQuery() metódus)

A Grafana bővítményének fejlesztése: nagy sikerek története

A Grafana bővítményének fejlesztése: nagy sikerek története

A Grafana bővítményének fejlesztése: nagy sikerek története

  • kapcsolati teszt a végső k8s klaszterrel.
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"};
       })
}

Külön érdekesség véleményünk szerint az adatforrás hitelesítési és engedélyezési mechanizmusának megvalósítása. Általában a beépített Grafana komponens datasourceHttpSettings segítségével konfigurálhatjuk a végső adatforráshoz való hozzáférést. Ezzel az összetevővel konfigurálhatjuk a hozzáférést a http adatforráshoz az url és az alapvető hitelesítési/engedélyezési beállítások megadásával: login-password vagy client-cert/client-key. Annak érdekében, hogy megvalósíthassuk a hozzáférést egy vivőjogkivonat (a k8s de facto szabványa) használatával konfigurálhatjuk, egy kis módosítást kellett végrehajtanunk.

A probléma megoldásához használhatja a Grafana beépített „Plugin Routes” mechanizmusát (további részletek: hivatalos dokumentációs oldal). Adatforrásunk beállításaiban deklarálhatunk egy útválasztási szabálykészletet, amelyet a grafana proxyszerver dolgoz fel. Például minden egyes végponthoz lehetőség van sablonozási lehetőséggel fejlécek vagy url-ek beállítására, amelyekhez a jsonData és a secureJsonData mezőkből lehet adatokat venni (jelszavak vagy tokenek titkosított formában tárolásához). Példánkban az olyan lekérdezések, mint a /__proxy/api/v1/namespaces az űrlap url-jéhez kerül proxyként
/api/v8/namespaces az Authorization: Bearer fejléccel.

A Grafana bővítményének fejlesztése: nagy sikerek története

A Grafana bővítményének fejlesztése: nagy sikerek története

Természetesen a k8s api szerverrel való együttműködéshez csak olvasási hozzáféréssel rendelkező felhasználóra van szükségünk, amelynek létrehozásához szintén megtalálható a plugin forráskódja.

5. rész: kiadás

A Grafana bővítményének fejlesztése: nagy sikerek története

Miután megírta saját Grafana beépülő modulját, természetesen nyilvánosan elérhetővé kell tennie azt. A Grafanában ez az itt elérhető bővítmények könyvtára grafana.com/grafana/plugins

Ahhoz, hogy a bővítmény elérhető legyen a hivatalos áruházban, PR-t kell készítenie ezt az adattáratehhez hasonló tartalom hozzáadásával a repo.json fájlhoz:

A Grafana bővítményének fejlesztése: nagy sikerek története

ahol a verzió a beépülő modul verziója, az url a tárolóra mutató hivatkozás, a commit pedig annak a véglegesítésnek a hash-je, amelyhez a beépülő modul egy adott verziója elérhető lesz.

És a kimeneten egy csodálatos képet fog látni, például:

A Grafana bővítményének fejlesztése: nagy sikerek története

A hozzá tartozó adatokat a rendszer automatikusan lekéri a Readme.md, Changelog.md és a plugin.json fájlból a beépülő modul leírásával.

6. rész: következtetések helyett

A kiadás után sem hagytuk abba a bővítmény fejlesztését. Most pedig azon dolgozunk, hogy megfelelően figyeljük a fürtcsomópontok erőforrás-felhasználását, új funkciókat vezetünk be az UX javítása érdekében, és nagy mennyiségű visszajelzést is begyűjtünk a bővítmény telepítése után, mind az ügyfeleinktől, mind a GitHubon élőktől (ha kilép kérdésed vagy kérésed, nagyon boldog leszek :)

Reméljük, hogy ez a cikk segít megérteni egy ilyen csodálatos eszközt, mint a Grafana, és talán megírja saját bővítményét.

Kösz!)

Forrás: will.com

Vásároljon megbízható tárhelyet DDoS védelemmel, VPS VDS szerverekkel rendelkező webhelyekhez 🔥 Vásároljon megbízható weboldal tárhelyet DDoS védelemmel, VPS VDS szerverekkel | ProHoster