Բարև բոլորին! Մի քանի ամիս առաջ մենք արտադրության մեջ մեկնարկեցինք մեր նոր բաց կոդով նախագիծը՝ Grafana հավելվածը kubernetes-ի մոնիթորինգի համար, որը մենք անվանեցինք . Պլագինի սկզբնական կոդը հասանելի է հետևյալ հասցեով՝ . Այս հոդվածում մենք ուզում ենք ձեզ հետ կիսվել այն պատմությամբ, թե ինչպես ենք ստեղծել պլագինը, ինչ գործիքներ ենք օգտագործել և ինչ թերությունների ենք հանդիպել մշակման գործընթացում։ Եկեք գնանք!
Մաս 0 - Ներածություն. Ինչպե՞ս հասանք այստեղ։
Grafana-ի համար մեր սեփական պլագինը գրելու գաղափարը մեզ մոտ ծագեց բոլորովին պատահական։ Մեր ընկերությունը ավելի քան 10 տարի է, ինչ հետևում է տարբեր բարդության մակարդակների վեբ նախագծերին։ Այս ընթացքում մենք կուտակել ենք մեծ քանակությամբ փորձ, հետաքրքիր դեպքեր և փորձ տարբեր մոնիթորինգի համակարգերի օգտագործման ոլորտում։ Եվ մի պահ մենք ինքներս մեզ հարցրինք. «Կա՞ արդյոք Kubernetes-ը մոնիթորինգի կախարդական գործիք, որպեսզի, ինչպես ասում են, կարողանաք «կարգավորել այն և մոռանալ դրա մասին»»։ K8S-ի մոնիթորինգի արդյունաբերության ստանդարտը, բնականաբար, վաղուց Prometheus + Grafana փաթեթն է։ Եվ որպես այս կույտի համար պատրաստի լուծումներ, կա տարբեր տեսակի գործիքների մեծ հավաքածու՝ prometheus-operator, kubernetes-mixin վահանակների հավաքածու, grafana-kubernetes-app։
Մեզ համար ամենահետաքրքիր տարբերակը, կարծես, grafana-kubernetes-app պլագինն էր, բայց այն չի աջակցվում ավելի քան մեկ տարի և, բացի այդ, չի կարող աշխատել node-exporter-ի և kube-state-metrics-ի նոր տարբերակների հետ։ Եվ ինչ-որ պահի մենք որոշեցինք. «Ինչո՞ւ մենք ինքներս չստեղծենք մեր լուծումը»։
Ի՞նչ գաղափարներ որոշեցինք իրականացնել մեր հավելվածում.
- «Ծրագրային քարտեզի» վիզուալիզացիա. կլաստերում ծրագրերի հարմար ներկայացում՝ խմբավորված անվանատարածքներով, տեղակայումներով և այլն։
- «տեղակայման ծառայություն (+պորտեր)» տիպի կապերի վիզուալիզացիա։
- կլաստերային հավելվածների բաշխման վիզուալիզացիա կլաստերային հանգույցների միջև։
- Հավաքագրելով չափանիշներ և տեղեկատվություն բազմաթիվ աղբյուրներից՝ Prometheus և k8s API սերվեր։
- Ինֆրակառուցվածքային մասի (պրոցեսորային ժամանակի, հիշողության, սկավառակի ենթահամակարգի, ցանցի օգտագործում), ինչպես նաև կիրառման տրամաբանության մոնիթորինգ՝ պոդերի առողջական վիճակը, հասանելի կրկնօրինակների քանակը, ակտիվության/պատրաստության թեստերի հաջողության վերաբերյալ տեղեկատվություն։
Մաս 1. Ի՞նչ է «Graftana հավելվածը»։
Տեխնիկապես, Grafana հավելվածը անկյունային կառավարիչ է, որը պահվում է Grafana-ի տվյալների գրացուցակում (/var/grafana/plugins/ /dist/module.js) և կարող է բեռնվել որպես SystemJS մոդուլ։ Այս գրացուցակում պետք է լինի նաև plugin.json ֆայլը, որը պարունակում է ձեր պլագինի մասին բոլոր մետա տեղեկությունները. անունը, տարբերակը, պլագինի տեսակը, հղումները դեպի repository/site/license, կախվածությունները և այլն։

մոդուլ.ts

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

Հավելվածի կախվածության օրինակ՝ type = app-ով.
Դուք կարող եք օգտագործել կամ JavaScript-ը, կամ TypeScript-ը որպես ծրագրավորման լեզու (մենք ընտրեցինք TypeScript-ը): Դատարկ տեղեր ցանկացած տեսակի hello-world պլագինների համար, որոնք կարող եք Այս պահոցը պարունակում է մեծ թվով մեկնարկային փաթեթներ (React-ում նույնիսկ կա միացվող մոդուլի փորձարարական օրինակ)՝ նախապես տեղադրված և կարգավորված փաթեթավորիչներով։
Մաս 2. Տեղական միջավայրի պատրաստում
Պլագինի վրա աշխատելու համար մեզ, բնականաբար, անհրաժեշտ կլինի kubernetes կլաստեր՝ բոլոր նախապես տեղադրված գործիքներով. prometheus, node-exporter, kube-state-metrics, grafana: Միջավայրը պետք է լինի արագ, հեշտ և հեշտ տեղադրվող, իսկ տաք վերաբեռնումն ապահովելու համար Grafana տվյալների գրացուցակը պետք է տեղադրվի անմիջապես մշակողի համակարգչից։
Մեր կարծիքով, kubernetes-ի հետ տեղական աշխատելու ամենահարմար ձևը սա է . Հաջորդ քայլը Prometheus + Grafana փաթեթի տեղադրումն է՝ օգտագործելով prometheus-operator-ը։ ՄԵՋ Minikube-ի վրա prometheus-operator-ը տեղադրելու գործընթացը մանրամասն նկարագրված է։ Համառությունը միացնելու համար անհրաժեշտ է սահմանել պարամետրը համառություն՝ ճշմարիտ 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. Ուղղակի զարգացում
Օբյեկտի մոդել
Պլագինի ներդրմանը նախապատրաստվելիս մենք որոշեցինք նկարագրել բոլոր հիմնական Kubernetes էնթիթները, որոնց հետ աշխատելու ենք որպես TypeScript դասեր՝ pod, deployment, daemonset, statefulset, job, cronjob, service, node, namespace: Այս դասերից յուրաքանչյուրը ժառանգում է ընդհանուր BaseModel դասից, որը սահմանում է կոնստրուկտոր, դեստրուկտոր, տեսանելիությունը թարմացնելու և փոխելու մեթոդներ։ Յուրաքանչյուր դաս նկարագրում է այլ էնթիթների հետ ներդրված հարաբերություններ, օրինակ՝ տեղակայման տիպի էնթիթիի համար պոդերի ցանկ։
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 = [];
}
}Գետտերների և սեթերների օգնությամբ մենք կարող ենք ցուցադրել կամ սահմանել մեզ անհրաժեշտ էնթիթիի չափանիշները հարմար և ընթեռնելի ձևով։ Օրինակ՝ բաշխելի պրոցեսորի հանգույցների ձևաչափված արդյունքը՝
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 կարևոր անկյունային ծառայություններ.
- backendSrv-ը ծառայություն է, որը ապահովում է փոխազդեցություն grafana api սերվերի հետ։
- datasourceSrv — ծառայություն, որը ապահովում է տեղային փոխազդեցություն ձեր Grafana-ում տեղադրված բոլոր տվյալների աղբյուրների հետ (օրինակ՝ .getAll() մեթոդը վերադարձնում է բոլոր տեղադրված տվյալների աղբյուրների ցանկը. .get( ) - վերադարձնում է որոշակի տվյալների աղբյուրի օրինակի օբյեկտը։



Մաս 4. տվյալների աղբյուր
Գրաֆանայի տեսանկյունից, datasource-ը բացարձակապես նույն պլագինն է, ինչ մյուս բոլորը. այն ունի իր սեփական module.js մուտքի կետը, և կա plugin.json մետա տեղեկատվություն պարունակող ֆայլ։ = app տիպի պլագին մշակելիս մենք կարող ենք փոխազդել ինչպես առկա տվյալների աղբյուրների (օրինակ՝ prometheus-datasource), այնպես էլ մեր սեփական տվյալների աղբյուրների հետ, որոնք կարող ենք անմիջապես պահել պլագինի գրացուցակում (dist/datasource/*) կամ տեղադրել որպես կախվածություն։ Մեր դեպքում, տվյալների աղբյուրը մատակարարվում է plugin կոդի հետ միասին։ Անհրաժեշտ է նաև ունենալ config.html ձևանմուշ և ConfigCtrl կառավարիչ, որը կօգտագործվի տվյալների աղբյուրի օրինակի կարգավորման էջի և տվյալների աղբյուրի կառավարիչի համար, որը կիրականացնի ձեր տվյալների աղբյուրի տրամաբանությունը։
KubeGraf հավելվածում, օգտագործողի ինտերֆեյսի տեսանկյունից, տվյալների աղբյուրը kubernetes կլաստերի օրինակ է, որն իրականացնում է հետևյալ հնարավորությունները (ելքային կոդը հասանելի է ):
- k8s api-սերվերից տվյալների ստացում (անվանատարածքների, տեղակայումների ցանկի ստացում...)
- Հարցումների պրոքսիավորում prometheus-datasource-ին (որը ընտրվում է յուրաքանչյուր կոնկրետ կլաստերի համար նախատեսված պլագինի կարգավորումներում) և պատասխանների ձևաչափում՝ տվյալները ստատիկ էջերում և վահանակներում օգտագործելու համար։
- թարմացնելով տվյալները պլագինի ստատիկ էջերում (սահմանված թարմացման հաճախականությամբ):
- grafana-dashboards-ում ձևանմուշի թերթիկ ստեղծելու համար հարցումների մշակում (մեթոդ .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-ը և հիմնական նույնականացման/հավաստագրման կարգավորումները՝ մուտքի գաղտնաբառ կամ հաճախորդի վկայական/հաճախորդի բանալի։ Որպեսզի ներդնենք կրող տոկենի միջոցով մուտքը կարգավորելու հնարավորությունը (k8s-ի փաստացի ստանդարտը), մենք ստիպված էինք մի փոքր փոփոխություններ կատարել։
Այս խնդիրը լուծելու համար կարող եք օգտագործել ներկառուցված Grafana մեխանիզմը՝ «Plugin Routes» (ավելի մանրամասն՝ )։ Մեր տվյալների աղբյուրի կարգավորումներում մենք կարող ենք հայտարարել երթուղայնացման կանոնների մի ամբողջություն, որը կմշակվի grafana պրոքսի սերվերի կողմից։ Օրինակ, յուրաքանչյուր առանձին վերջնակետի համար կա վերնագրեր կամ URL-ներ սահմանելու հնարավորություն՝ ձևանմուշ ստեղծելու հնարավորությամբ, որոնց տվյալները կարելի է վերցնել jsonData և secureJsonData դաշտերից (գաղտնաբառերը կամ տոկենները կոդավորված տեսքով պահելու համար): Մեր օրինակում, ձևի հարցումները /__proxy/api/v1/անվանատարածքներ կուղարկվի ձևի URL-ներին
/api/v8/անվանատարածքներ՝ Authorization: Bearer վերնագրի հավաքածուով։


Բնականաբար, k8s api սերվերի հետ աշխատելու համար մեզ անհրաժեշտ է միայն ընթերցման մուտք ունեցող օգտատեր, որի ստեղծման մանիֆեստները կարող եք գտնել նաև .
Մաս 5. Թողարկում

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

որտեղ version-ը ձեր պլագինի տարբերակն է, url-ը՝ ռեպոզիտորի հղումը, իսկ commit-ը commit-ի հեշն է, որը հասանելի կդարձնի պլագինի կոնկրետ տարբերակը։
Եվ ելքի մոտ դուք կտեսնեք այսպիսի հրաշալի պատկեր.

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