Grafana-ի համար հավելվածի մշակում. մեծ կրակոցների պատմություն

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

Մաս 0 - ներածական. ինչպե՞ս հասանք այս կետին:

Grafan-ի համար մեր սեփական փլագինը գրելու գաղափարը մեզ մոտ առաջացավ միանգամայն պատահաբար: Մեր ընկերությունն ավելի քան 10 տարի վերահսկում է տարբեր մակարդակների բարդության վեբ նախագծերը: Այս ընթացքում մենք կուտակել ենք մեծ փորձաքննություն, հետաքրքիր դեպքեր, տարբեր մոնիտորինգային համակարգեր օգտագործելու փորձ։ Եվ ինչ-որ պահի մենք հարցրինք ինքներս մեզ. «Կա՞ արդյոք կախարդական գործիք Kubernetes-ի մոնիտորինգի համար, որպեսզի, ինչպես ասում են, «տեղադրեք այն և մոռանաք այն»: K8-ների մոնիտորինգի արդյունաբերության ստանդարտը, իհարկե, վաղուց է եղել: Պրոմեթևս + Գրաֆանա համադրություն. Եվ որպես պատրաստի լուծումներ այս կույտի համար, կա տարբեր տեսակի գործիքների մեծ հավաքածու՝ պրոմեթևս-օպերատոր, kubernetes-mixin վահանակների հավաքածու, grafana-kubernetes-app:

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

Ինչ գաղափարներ մենք որոշեցինք իրականացնել մեր plugin-ում.

  • «Հավելվածի քարտեզի» վիզուալացում. հավելվածների հարմար ներկայացում կլաստերում՝ խմբավորված ըստ անվանատարածքների, տեղակայումների...;
  • կապերի վիզուալացում, ինչպիսին է «տեղակայում - ծառայություն (+պորտ)»:
  • կլաստերային հավելվածների բաշխման պատկերացում կլաստերի հանգույցներում:
  • չափումների և տեղեկատվության հավաքածու մի քանի աղբյուրներից՝ Պրոմեթևս և k8s api սերվեր:
  • և՛ ենթակառուցվածքի մասի մոնիտորինգ (պրոցեսորի ժամանակի օգտագործում, հիշողություն, սկավառակի ենթահամակարգ, ցանց), և՛ կիրառական տրամաբանություն՝ առողջական կարգավիճակի պատյաններ, հասանելի կրկնօրինակների քանակը, աշխուժության/պատրաստության թեստեր անցնելու մասին տեղեկատվություն:

Մաս 1. Ի՞նչ է «Grafana plugin»-ը:

Տեխնիկական տեսանկյունից Grafana-ի հավելումը անկյունային վերահսկիչ է, որը պահվում է Grafana տվյալների գրացուցակում (/var/grafana/plugins/ /dist/module.js) և կարող է բեռնվել որպես SystemJS մոդուլ: Նաև այս գրացուցակում պետք է լինի plugin.json ֆայլ, որը պարունակի ձեր plugin-ի մասին բոլոր մետա տեղեկատվությունը. անունը, տարբերակը, plugin-ի տեսակը, հղումներ դեպի պահեստ/կայք/լիցենզիա, կախվածություններ և այլն:

Grafana-ի համար հավելվածի մշակում. մեծ կրակոցների պատմություն
մոդուլ.ց

Grafana-ի համար հավելվածի մշակում. մեծ կրակոցների պատմություն
plugin.json

Ինչպես տեսնում եք սքրինշոթում, մենք նշել ենք plugin.type = app: Քանի որ Grafana-ի հավելումները կարող են լինել երեք տեսակի.

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

Grafana-ի համար հավելվածի մշակում. մեծ կրակոցների պատմություն
Փլագինների կախվածության օրինակ՝ type=app.

Որպես ծրագրավորման լեզու կարող եք օգտագործել ինչպես JavaScript-ը, այնպես էլ TypeScript-ը (մենք ընտրել ենք այն): Նախապատրաստություններ hello-world պլագինների համար՝ ցանկացած տեսակի, որը կարող եք գտնել հղումըԱյս պահոցը պարունակում է մեծ թվով մեկնարկային փաթեթներ (նույնիսկ React-ում կա plugin-ի փորձնական օրինակ)՝ նախապես տեղադրված և կազմաձևված շինարարներով:

Մաս 2. տեղական միջավայրի նախապատրաստում

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

Կուբերնետների հետ տեղական աշխատելու ամենահարմար տարբերակը, մեր կարծիքով, դա է minikube. Հաջորդ քայլը Prometheus + Grafana համադրությունը տեղադրելն է՝ օգտագործելով prometheus-operator: IN այս հոդվածը Մանրամասն նկարագրված է minikube-ի վրա Prometheus-operator-ի տեղադրման գործընթացը։ Համառությունը միացնելու համար դուք պետք է սահմանեք պարամետրը համառություն: ճշմարիտ գծապատկերներում/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-ում՝ կախվածությունների բաժնում.

Grafana-ի համար հավելվածի մշակում. մեծ կրակոցների պատմություն

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

Էջի աշխատանքի համար պատասխանատու բաղադրիչում մենք պետք է սահմանենք templateUrl-ը՝ այնտեղ փոխանցելով html ֆայլի ուղին՝ նշագրումով։ Կարգավորիչի ներսում, կախվածության ներարկման միջոցով, մենք կարող ենք մուտք գործել մինչև 2 կարևոր անկյունային ծառայություններ.

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

Grafana-ի համար հավելվածի մշակում. մեծ կրակոցների պատմություն

Grafana-ի համար հավելվածի մշակում. մեծ կրակոցների պատմություն

Grafana-ի համար հավելվածի մշակում. մեծ կրակոցների պատմություն

Մաս 4. տվյալների աղբյուր

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

KubeGraf հավելվածում, օգտագործողի միջերեսի տեսանկյունից, տվյալների աղբյուրը kubernetes կլաստերի օրինակ է, որն իրականացնում է հետևյալ հնարավորությունները (աղբյուրային կոդը հասանելի է по ссылке):

  • k8s api-սերվերից տվյալների հավաքագրում (անվանատարածքների ցանկ, տեղակայում...)
  • proxying հարցումներ prometheus-datasource-ին (որն ընտրվում է plugin-ի կարգավորումներում յուրաքանչյուր կոնկրետ կլաստերի համար) և պատասխանների ձևաչափում՝ տվյալների օգտագործման համար ինչպես ստատիկ էջերում, այնպես էլ վահանակներում:
  • տվյալների թարմացում ստատիկ հավելումների էջերի վրա (սահմանված թարմացման արագությամբ):
  • հարցումների մշակում grafana-dashboards-ում ձևանմուշային թերթ ստեղծելու համար (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-ը և նույնականացման/լիազորման հիմնական կարգավորումները՝ login-password կամ client-cert/client-key: Որպեսզի գործադրենք մուտքը կարգավորելու հնարավորություն՝ օգտագործելով կրող նշան (k8s-ի դե ֆակտո ստանդարտ), մենք պետք է մի փոքր շտկումներ կատարեինք:

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

Grafana-ի համար հավելվածի մշակում. մեծ կրակոցների պատմություն

Grafana-ի համար հավելվածի մշակում. մեծ կրակոցների պատմություն

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

Մաս 5. ազատում

Grafana-ի համար հավելվածի մշակում. մեծ կրակոցների պատմություն

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

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

Grafana-ի համար հավելվածի մշակում. մեծ կրակոցների պատմություն

որտեղ տարբերակը ձեր plugin-ի տարբերակն է, url-ը հղում է դեպի պահեստ, իսկ commit-ը commit-ի հեշն է, որի համար հասանելի կլինի plugin-ի հատուկ տարբերակը:

Եվ ելքի վրա դուք կտեսնեք մի հրաշալի նկար, ինչպիսին է.

Grafana-ի համար հավելվածի մշակում. մեծ կրակոցների պատմություն

Դրա համար տվյալները ավտոմատ կերպով կվերցվեն ձեր Readme.md, Changelog.md և plugin.json ֆայլից՝ plugin-ի նկարագրությամբ:

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

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

Հուսով ենք, որ այս հոդվածը կօգնի ձեզ հասկանալ այնպիսի հիանալի գործիք, ինչպիսին է Grafana-ն և, հավանաբար, գրել ձեր սեփական հավելվածը:

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

Source: www.habr.com

Добавить комментарий