Բարև բոլորին! մի քանի ամիս առաջ մենք թողարկեցինք մեր նոր open-source նախագիծը՝ Grafana-պլագինը Kubernetes մոնիտորինգի համար, որը կոչեցինք . Պլագինի աղբյուրի կոդը հասանելի է . Այս հոդվածում ցանկանում ենք կիսվել ձեզ հետ մեր պլագինի ստեղծման պատմությամբ, ինչ գործիքներ օգտագործեցինք և որոնց հետ բախվեցինք զարգացման գործընթացում: Արի սկսենք:
Մաս 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 ֆայլ, որը պարունակում է ձեր պլագինի բոլոր մետաընթեցումները՝ անվանում, տարբերակ, պլագինի տեսակ, հղումներ ռեպոզիտոր/ сайт/ լիցենզիա, կախվածությունները և այլն:

module.ts

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

Պլագինի կախվածությունների օրինակ type = app:.
Ծրագրավորման լեզու կարող եք օգտագործել ինչպես JavaScript-ը, այնպես էլ TypeScript-ը (մենք ընտրեցինք վերջինը): hello-world պլագինի ցանկացած տեսակի նախատեքստեր կարող եք : այս ռեպոզիտորայում ներկայացված է բազմաթիվ starter-pack-ներ (կան նույնիսկ փորձնական պլագին React-ի վրա) ներկայացված նախնական և կարգավորված հավաքույթներով:
Հրավը 2: տեղական միջավայրի պատրաստում:
Պլագինի վրա աշխատելու համար մեզ, բնականաբար, անհրաժեշտ կլինի kubernetes-խմբավորում բոլոր նախորդ գործիքներով. prometheus, node-exporter, kube-state-metrics, grafana: Շրջապատը պետք է արագ, հեշտ և անվերապահ սահմանվի, իսկ տվյալների hot-reload ապահովելու համար Grafana-ի data-դիրքերն անհրաժեշտ է անմիջապես սարքին միացնել:
Մեր կարծիքով, kubernetes-ի հետ տեղական աշխատելու ամենահարմար ճանապարհը է: Հաջորդ քայլը գցել Prometheus + Grafana թողնելով prometheus-operator: Այս գործընթացում մանրամասն նկարագրված է 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-ում կախվածությունների բաժնում:

Յուրաքանչյուր էջի բլոկում մենք պետք է նշենք ԷՋԻ ԱՅՑԸ (այնուհետև կհամագործակցվի slug-ի հետ, որով այս էջը կլինի հասանելի); գործող էջի համար պատասխանատու կոմպոնנטի անունը (կոմպոնենտների ցանկը արտահանվում է module.ts); օգտվողի դերը, որի համար հասանելի է այս էջով աշխատանքը և կողմնային պտտման վերանայման կարգը:
Էջի համար պատասխանատու կոմպոնենտում մենք պետք է սահմանենք templateUrl, որտեղ փոխանցում ենք html-ֆայլի ճանապարհը կանոնակարգելու համար: Շտրիխի միջոցով, կախյալության ներարկման միջոցով, մենք կարող ենք հասնել 2 կարևոր angular-ծառայությունների:
- backendSrv — ծառայություն, որը ապահովում է փոխադարձ կապ api-սերվերի հետ grafana;
- datasourceSrv — ծառայություն, որը ապահովում է տեղական փոխադարձ կապ բոլոր datasource-ների հետ, որոնք տեղադրված են ձեր Grafana-ում (օրինակ, .getAll() — վերադարձնում է բոլոր տեղադրված datasource-ների ցանկը; .get() — վերադարձնում է կոնկրետ datasource-ի օբյեկտ-ինքնաթիռը:



Մաս 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())



- 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 վերնագրերին:


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

Երբ դուք ձեր սեփական պլագինը գրել եք Grafana-ի համար, բնականաբար, ուզենալու եք այն հրապարակել: Grafana-ում համակցված պլագինների գրադարան է, հասանելի՝
Որ ձեր պլագինը հասանելի լինի պաշտոնական խանութում, հարկավոր է PR անել , ավելացնելով repo.json ֆայլում հետևյալ ձևաթուղթը:

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

Տվյալները դրա համար ավտոմատ կերպով կտրված կլինեն ձեր Readme.md, Changelog.md և plugin.json ֆայլից, որում նշված է պլագինի նկարագիրը:
Մաս 6: փոխարեն եզրակացությունները
Մեր պլագինի մշակումը չենք կանգնեցրել թողարկումից հետո: Այս պահին մենք աշխատում ենք վերանայելու նաև ռեսուրսների օգտագործման վերահսկումը կլաստերյան հանգույցներում, նոր ֆունկցիաների ներդրումը UX-ի բարելավման համար, ինչպես նաև մշակվում է մեծ քանակությամբ հետադարձ կապ, որը ստացել ենք ինչպես մեր հաճախորդներից, այնպես էլ GitHub-ում բաց խնդիրների վերացումները: (եթե թողնենք ձեր խնդիրը կամ pull request-ը, ես շատ ուրախ կլինեմ 🙂 )
Հուսով ենք, որ այս հոդվածը կօգնի ձեզ հասկանալ Grafana նման հրաշալի գործիքն ու, հնարավոր է, գրել ձեր սեփական պլագինը։
Շնորհակալություն!)
Ընտանիք: habr.com
