Grafana-ի համար պլագինի մշակում․ անցած փորձառությունների պատմություն

Բարև բոլորին! մի քանի ամիս առաջ մենք թողարկեցինք մեր նոր open-source նախագիծը՝ Grafana-պլագինը Kubernetes մոնիտորինգի համար, որը կոչեցինք DevOpsProdigy KubeGraf. Պլագինի աղբյուրի կոդը հասանելի է հանրային ռեպոզիտորիայում GitHub-ում. Այս հոդվածում ցանկանում ենք կիսվել ձեզ հետ մեր պլագինի ստեղծման պատմությամբ, ինչ գործիքներ օգտագործեցինք և որոնց հետ բախվեցինք զարգացման գործընթացում: Արի սկսենք:

Մաս 0 — ծանոթացում՝ ինչպես ենք մենք այստեղ եկել:

Գրաֆանա համար մեր սեփական պլագինը գրելն ի սկզբանե պատահաբար առաջացավ: Մեր ընկերությունը ավելի քան 10 տարի զբաղվում է տարբեր բարդության web-պроектների մոնիտորինգով: Այս ընթացքում մենք ձեռք ենք բերել մեծ փորձ, հետաքրքիր դեպքեր և տարբեր մոնիտորինգի համակարգերի օգտագործման փորձ: Եվ մի պահ մենք տրվեցինք հարցի՝ «Հիմա արդյո՞ք կա կախարդական գործիք Kubernetes մոնիտորինգի համար, որը, ինչպես ասում են, «դնում ես և մոռանում»:.. Կ natürlich մոնիտորինգի ստանդարտը վաղուց արդեն Prometheus + Grafana համադրությունն է: Եվ այս տեխնոլոգիական ստեքի համար ստեղծված լուրջ արձանագրությունների մեծ բազմություն կա՝ prometheus-operator, kubernetes-mixin խմբաքանակի դաշբորդներ, grafana-kubernetes-app:

Մեզ համար ամենահետաքրքիր տարբերակներն էին grafana-kubernetes-app պլագինը, բայց այն արդեն ավելի քան մեկ տարի չի ենթարկվում աջակցությունի, ուստի չի կարող աշխատել node-exporter և kube-state-metrics նոր տարբերակների հետ: Եվ մի որոշ ժամանակ անց մենք որոշեցինք. «Հապաղում ենք անել մեր սեփական լուծումը»

Որոնք էին մեր պլագինի իրականացման գաղափարները:

  • առ application's map visualization: удобное представление приложения в кластере, сгруппированного по namespace, deployment...;
  • визуализация связей формы «deployment — service (+ports)»:
  • визуализация распределения приложений кластера по nod'ам кластера:
  • ավելի քան մեկ աղբյուրներից մետրիքի և տեղեկատվության հավաքում՝ Prometheus և kubernetes API սերվեր:
  • նշանակալումներ ինչպես ենթակառուցվածքի մասի (փոփոխության ժամանակ, հիշողության, սկավառակի ենթակառուցվածքի, ցանցի) այնպես էլ application's логики — pod-ների health-status, հատկությունների հասանելիության քանակը, liveness/readyness-փորձերի մասին տեղեկատվություն:

Մաս 1: Ի՞նչ է «Grafana պլագինը»:

Տեխնիկական տեսանկյունից, Grafana պլագինը Angular-կանոն, որը գտնվում է Grafana'nın data-թղթապանակում (/var/grafana/plugins/<your_plugin_name>/dist/module.js) և կարող է բեռնվել որպես SystemJS մոդուլ: Այս ֆայլի կողքին պետք է լինի plugin.json ֆայլ, որը պարունակում է ձեր պլագինի բոլոր մետաընթեցումները՝ անվանում, տարբերակ, պլագինի տեսակ, հղումներ ռեպոզիտոր/ сайт/ լիցենզիա, կախվածությունները և այլն:

Grafana-ի համար պլագինի մշակում․ անցած փորձառությունների պատմություն
module.ts

Grafana-ի համար պլագինի մշակում․ անցած փորձառությունների պատմություն
plugin.json

Ինչպես երևում է էկրանի վրա, մենք plugin.type = app սահմանեցինք: Որովհետև Grafana պլագինները կարող են լինել երեք տեսակի:

panel: ամենատարածված պլագինի տեսակն է՝ ներկայացնում է տարբեր մետրիքի համար վիզուալացնող վանդակ, օգտագործվում է տարբեր դաշբորդներ կառուցելու համար:
datasource: տվյալ տվյալներ աղբյուրի համար կոնեկտոր պլագին (օրինակ, Prometheus-datasource, ClickHouse-datasource, ElasticSearch-datasource):
app: պլագին, որը թույլ է տալիս ստեղծել ձեր սեփական ֆրոնտենդ կիրառումը Grafana-ի ներսում, ստեղծել ձեր սեփական html էջերը և ձեռքով դիմել datasource տարբեր տվյալների визуալիզացիայի համար: Որպես կախվածություններ կարող են օգտագործվել այլ տեսակների պլագիններ (datasource, panel) և տարբեր դաշբորդներ:

Grafana-ի համար պլագինի մշակում․ անցած փորձառությունների պատմություն
Պլագինի կախվածությունների օրինակ type = app:.

Ծրագրավորման լեզու կարող եք օգտագործել ինչպես JavaScript-ը, այնպես էլ TypeScript-ը (մենք ընտրեցինք վերջինը): hello-world պլագինի ցանկացած տեսակի նախատեքստեր կարող եք գտնել հղումով:: այս ռեպոզիտորայում ներկայացված է բազմաթիվ starter-pack-ներ (կան նույնիսկ փորձնական պլագին React-ի վրա) ներկայացված նախնական և կարգավորված հավաքույթներով:

Հրավը 2: տեղական միջավայրի պատրաստում:

Պլագինի վրա աշխատելու համար մեզ, բնականաբար, անհրաժեշտ կլինի kubernetes-խմբավորում բոլոր նախորդ գործիքներով. prometheus, node-exporter, kube-state-metrics, grafana: Շրջապատը պետք է արագ, հեշտ և անվերապահ սահմանվի, իսկ տվյալների hot-reload ապահովելու համար Grafana-ի data-դիրքերն անհրաժեշտ է անմիջապես սարքին միացնել:

Մեր կարծիքով, kubernetes-ի հետ տեղական աշխատելու ամենահարմար ճանապարհը minikubeէ: Հաջորդ քայլը գցել Prometheus + Grafana թողնելով prometheus-operator: Այս գործընթացում this article մանրամասն նկարագրված է prometheus-operator-ի տեղադրման գործընթացը minikube-ում: Կայունությունը շարունակելու համար անհրաժեշտ է սահմանել պարամետրը persistence: true charts/grafana/values.yaml ֆայլում, ավելացնել ձեր սեփական PV և PVC և նշել դրանք persistence.existingClaim պարամետրի մեջ:

Մեր վերջնական minikube գործարկման սցենարը выглядит так:

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: անմիջականորեն մշակումը:

Obiectual Modéna:

Պլագինի իրագործման նախապատրաստման համար մենք որոշեցինք նկարագրել բոլոր Kubernetes-ի հիմնական ռեժիմները, որոնց հետ մենք կզբաղվենք TypeScript դասերի տեսքով: pod, deployment, daemonset, statefulset, job, cronjob, service, node, namespace: Յուրաքանչյուր այս դասերից ժառանգում է BaseModel ընդհանուր դասից, որտեղ նկարագրված են կոնստրուկտորը, դեստրուկտորը, թարմացման և տեսանելիության փոփոխության մեթոդները: Յուրաքանչյուր դասում նկարագրված են ներքին հարաբերությունները այլ ռեժիմների հետ, օրինակ, pod-ների ցանկը deployment տեսակի ռեժիմի համար:

import {Pod} from "./pod";
import {Service} from "./service";
import {BaseModel} from './traits/baseModel';

export class Deployment extends BaseModel{
   pods: Array;
   services: Array;

   constructor(data: any){
       super(data);
       this.pods = [];
       this.services = [];
   }
}

Getter-ների և setter-ների միջոցով մենք կարող ենք դուրս բերել կամ տեղադրել մեզ անհրաժեշտ ռեժիմների մետրիկաները հարմար և ընթերյան տեսքով: Օրինակ, ձևաչափված դուրս բերել allocatable cpu nod’ի:

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

Զգուշացումներ

Մեր պլագինի բոլոր էջերի ցանկը սկզբում նկարագրված է մեր pluing.json-ում կախվածությունների բաժնում:

Grafana-ի համար պլագինի մշակում․ անցած փորձառությունների պատմություն

Յուրաքանչյուր էջի բլոկում մենք պետք է նշենք ԷՋԻ ԱՅՑԸ (այնուհետև կհամագործակցվի slug-ի հետ, որով այս էջը կլինի հասանելի); գործող էջի համար պատասխանատու կոմպոնנטի անունը (կոմպոնենտների ցանկը արտահանվում է module.ts); օգտվողի դերը, որի համար հասանելի է այս էջով աշխատանքը և կողմնային պտտման վերանայման կարգը:

Էջի համար պատասխանատու կոմպոնենտում մենք պետք է սահմանենք templateUrl, որտեղ փոխանցում ենք html-ֆայլի ճանապարհը կանոնակարգելու համար: Շտրիխի միջոցով, կախյալության ներարկման միջոցով, մենք կարող ենք հասնել 2 կարևոր angular-ծառայությունների:

  • backendSrv — ծառայություն, որը ապահովում է փոխադարձ կապ api-սերվերի հետ grafana;
  • datasourceSrv — ծառայություն, որը ապահովում է տեղական փոխադարձ կապ բոլոր datasource-ների հետ, որոնք տեղադրված են ձեր Grafana-ում (օրինակ, .getAll() — վերադարձնում է բոլոր տեղադրված datasource-ների ցանկը; .get() — վերադարձնում է կոնկրետ datasource-ի օբյեկտ-ինքնաթիռը:

Grafana-ի համար պլագինի մշակում․ անցած փորձառությունների պատմություն

Grafana-ի համար պլագինի մշակում․ անցած փորձառությունների պատմություն

Grafana-ի համար պլագինի մշակում․ անցած փորձառությունների պատմություն

Մաս 4: datasource

Grafana-ի տեսանկյունից datasource-ն նույնպիսի պլագին է, ինչպես մյուսները: այն ունի իր մուտքի կետը module.js, ունի meta տվյալների ֆայլ plugin.json: type = app պլագինի մշակման ընթացքում մենք կարող ենք փոխզիջել գոյություն ունեցող datasource-ների (օրինակ, prometheus-datasource) և մեր սեփականների հետ, որոնք կարող ենք պահել անմիջապես պլագինի ուղղության մեջ (dist/datasource/*) կամ տեղադրել որպես կախվածություն: մեր դեպքում datasource-ը գալիս է պլագինի կոդի հետ: Ամբողջովին անհրաժեշտ է config.html շաբլոնի առկայությունը և ConfigCtrl վերահսկիչը, որոնք օգտագործվելու են datasource-ի ինստանսի խմբագրման էջի համար և datasource-ի վերահսկիչը, որտեղ գտնվում է ձեր datasource-ի գործառնական տրամաբանությունը:

KubeGraf պլագինի տեսանկյունից, օգտվողի ինտերֆեյսի առումով, datasource-ն kubernetes-կլաստերի ինքնաթիռ է, որտեղ իրականացված են հետևյալ հնարավորությունները (որոշակի աղբյուրի կոդը մատչելի է հղումով):

  • տվյալների հավաքում k8s api-server-ից (namespace-ների, deployment-ների ցանկի ստացում…)
  • prometheus-datasource-ի վրա հարցումների պրոքսավորում (որը ընտրվում է պլագինի կարգավորումներում յուրաքանչյուր կոնկրետ կլաստերի համար) և պատասխանի ձևավորում տվյալների օգտագործման համար թե կայտնի էջերում, թե դաշբորդերում:
  • պլագինի կայտնի էջերում տվյալների թարմացում (նշված թարմացման հաճախականությամբ):
  • grafana-dashboards-ում template-ցանկի ձևավորման համար հարցումների մշակման (метод .metriFindQuery())

Grafana-ի համար պլագինի մշակում․ անցած փորձառությունների պատմություն

Grafana-ի համար պլագինի մշակում․ անցած փորձառությունների պատմություն

Grafana-ի համար պլագինի մշակում․ անցած փորձառությունների պատմություն

  • 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"};
       })
}

Մեր կարծիքով, առանձնահատուկ հետաքրքիր կողմը տվյալների աղբյուրի համար ավտորիզացիայի և վավերացման մեխանիզմի իրականացումն է: Ընդհանրապես, սովորաբար կարող ենք օգտագործել Grafana-ի ինտեգրված բաղադրիչը՝ datasourceHttpSettings, թիրախային տվյալների աղբյուրին հասանելիության կարգավորումը կատարելու համար: Այս բաղադրիչի միջոցով կարող ենք կարգավորել HTTP տվյալների աղբյուրին մուտք, նշելով URL և վավերացման/autorizacia-ի հիմնական պարամետրեր՝ մուտքի անուն-գաղտնաբառ կամ client-cert/client-key: Ցանկալի bearer-token-ի միջոցով մուտք կազմելու հնարավորության իրականացնելու համար (de facto սպառողական ստանդարտ k8s), հարկ էր մի փոքր «փոխել»:

Այս խնդիրն լուծելու համար կարելի է օգտագործել Grafana-ի ինտեգրված «Plugin Routes» մեխանիզմը (ավելին՝ պաշտոնական փաստաթղթավորման էջում). Մեր datasource-ի կարգավորումների մեջ կարող ենք հայտարարել երթևեկության կանոնների հավաքածու, որոնք կներկայացնեն grafana-ի proxy սերվերը: Օրինակ, յուրաքանչյուր առանձին endpoint-ի համար կարելի է սահմանել վերնագրեր կամ URL-ներ՝ հնարավորությամբ նախաբառի, որոնց տվյալները կարող են վերցվել jsonData և secureJsonData (գաղտնաբառերի կամ tokens-երի խճողված տեսքով պահելու համար) դաշտերից: Մեր օրինակներում, նման ձևով, հարցումներն ավելորդ լինելու համար /__proxy/api/v1/namespaces կփոխանցվեն URL տեսքով
/api/v1/namespaces և կհետևեն Authorization: Bearer վերնագրերին:

Grafana-ի համար պլագինի մշակում․ անցած փորձառությունների պատմություն

Grafana-ի համար պլագինի մշակում․ անցած փորձառությունների պատմություն

Ենթադրվող k8s API սերվերով աշխատելու համար մի օգտատեր պետք է ունենա readonly հասանելիություն, որի ստեղծման մանիֆեստները կարող եք գտնել նաև ապրանքային կոդում.

Մաս 5: թողարկում

Grafana-ի համար պլագինի մշակում․ անցած փորձառությունների պատմություն

Երբ դուք ձեր սեփական պլագինը գրել եք Grafana-ի համար, բնականաբար, ուզենալու եք այն հրապարակել: Grafana-ում համակցված պլագինների գրադարան է, հասանելի՝ grafana.com/grafana/plugins

Որ ձեր պլագինը հասանելի լինի պաշտոնական խանութում, հարկավոր է PR անել այս ռեպոզիտորիան, ավելացնելով repo.json ֆայլում հետևյալ ձևաթուղթը:

Grafana-ի համար պլագինի մշակում․ անցած փորձառությունների պատմություն

որտեղ version — ձեր պլագինի տարբերակն է, url — ռեպոզիտորիայի հղումը, իսկ commit — այն կոմիտայի hash-ը, որի միջոցով հասանելի կլինի կոնկրետ պլագինի տարբերակը:

Եվ արդյունքում կտեսնեք գեղեցիկ պատկեր, որը նման է:

Grafana-ի համար պլագինի մշակում․ անցած փորձառությունների պատմություն

Տվյալները դրա համար ավտոմատ կերպով կտրված կլինեն ձեր Readme.md, Changelog.md և plugin.json ֆայլից, որում նշված է պլագինի նկարագիրը:

Մաս 6: փոխարեն եզրակացությունները

Մեր պլագինի մշակումը չենք կանգնեցրել թողարկումից հետո: Այս պահին մենք աշխատում ենք վերանայելու նաև ռեսուրսների օգտագործման վերահսկումը կլաստերյան հանգույցներում, նոր ֆունկցիաների ներդրումը UX-ի բարելավման համար, ինչպես նաև մշակվում է մեծ քանակությամբ հետադարձ կապ, որը ստացել ենք ինչպես մեր հաճախորդներից, այնպես էլ GitHub-ում բաց խնդիրների վերացումները: (եթե թողնենք ձեր խնդիրը կամ pull request-ը, ես շատ ուրախ կլինեմ 🙂 )

Հուսով ենք, որ այս հոդվածը կօգնի ձեզ հասկանալ Grafana նման հրաշալի գործիքն ու, հնարավոր է, գրել ձեր սեփական պլագինը։

Շնորհակալություն!)

Ընտանիք: habr.com

Գնել հուսալի հյուրընկալում DDoS պաշտպանությամբ, VPS VDS սերվերներով 🔥 Գնել հուսալի հյուրընկալում DDoS պաշտպանությամբ, VPS VDS սերվերներով | ProHoster