تطوير البرنامج المساعد لغرافانا: قصة الأقماع الكاملة

مرحبا بالجميع! قبل بضعة أشهر ، أطلقنا مشروعنا الجديد المفتوح المصدر ، البرنامج المساعد Grafana لمراقبة kubernetes ، ودعا DevOpsProdigy KubeGraf ، إلى الإنتاج . شفرة المصدر للمكون الإضافي متاحة في المستودع العام على جيثب . وفي هذه المقالة ، نريد أن نشارككم قصة حول كيفية إنشاء المكون الإضافي ، والأدوات التي استخدمناها والمخاطر التي واجهناها أثناء عملية التطوير. دعنا نذهب!

الجزء 0 - تمهيدي: كيف وصلنا إلى هذا؟


ولدت فكرة كتابة البرنامج المساعد لدينا لغرافان عن طريق الصدفة. تراقب شركتنا مشاريع الويب على مستويات مختلفة من التعقيد لأكثر من 10 سنوات. خلال هذا الوقت ، اكتسبنا خبرة كبيرة وحالات مثيرة للاهتمام وخبرة في استخدام أنظمة المراقبة المختلفة. وفي وقت ما سألنا أنفسنا: "هل هناك أداة سحرية لرصد Kubernetes بحيث ، كما يقولون ،" ضبط وننسى "؟ .. برومستارتارت لرصد K8s ، بالطبع ، كانت مجموعة من بروميثيوس + غرافانا. وكحلول جاهزة لهذه المجموعة ، هناك مجموعة كبيرة من أنواع مختلفة من الأدوات: مشغل بروميثيوس ، ومجموعة من لوحات المعلومات kubernetes-mixin ، grafana-kubernetes-app.

يبدو أن المكوّن الإضافي grafana-kubernetes-app هو الخيار الأكثر إثارة للاهتمام بالنسبة لنا ، لكنه لم يتم دعمه لأكثر من عام ، علاوة على ذلك ، لا يعرف كيفية التعامل مع الإصدارات الجديدة من مقاييس مصدر العقدة و kube-state-metrics. وفي مرحلة ما ، قررنا: "لكن ألا نتخذ قرارنا الخاص؟"

ما الأفكار التي قررنا تنفيذها في البرنامج المساعد لدينا:

  • تصور "خريطة التطبيق": عرض مناسب للتطبيقات في الكتلة ، مجمعة حسب مساحة الاسم ، النشر ... ؛
  • تصور اتصالات النموذج "النشر - الخدمة (+ المنافذ)".
  • تصور لتوزيع تطبيقات الكتلة حسب إيماءات الكتلة.
  • جمع المقاييس والمعلومات من عدة مصادر: خادم بروميثيوس و k8s api.
  • مراقبة كل من جزء البنية التحتية (استخدام وقت المعالج ، والذاكرة ، والنظام الفرعي للقرص ، والشبكة) ، ومنطق التطبيق - قرون الحالة الصحية ، وعدد النسخ المتماثلة المتاحة ، ومعلومات حول مرور عينات الصلاحية / الاستعداد.

الجزء 1: ما هو البرنامج المساعد غرافانا؟


من الناحية الفنية ، فإن المكون الإضافي لـ Grafana هو وحدة تحكم زاوية يتم تخزينها في دليل بيانات Grafana ( /var/grafana/plugins/<your_plugin_name>/dist/module.js ) ويمكن تحميلها كوحدة نمطية SystemJS. أيضًا في هذا الدليل ، يجب أن يكون ملف plugin.json يحتوي على جميع المعلومات الوصفية حول المكون الإضافي الخاص بك: الاسم ، الإصدار ، نوع المكون الإضافي ، ارتباطات إلى المستودع / الموقع / الترخيص ، التبعيات ، وما إلى ذلك.


module.ts


plugin.json

كما ترى في لقطة الشاشة ، حددنا plugin.type = التطبيق. للمكونات الإضافية لـ Grafana يمكن أن تكون من ثلاثة أنواع:

اللوحة : أكثر أنواع المكونات شيوعًا - إنها لوحة لتصور أي مقاييس ، ويتم استخدامها لإنشاء لوحات معلومات مختلفة.
مصدر البيانات : موصل البرنامج المساعد لأي مصدر بيانات (على سبيل المثال ، مصدر بيانات Prometheus ، مصدر بيانات ClickHouse ، مصدر بيانات البحث المرن).
التطبيق : مكون إضافي يسمح لك بإنشاء تطبيق الواجهة الأمامية الخاص بك داخل Grafana ، وإنشاء صفحات html الخاصة بك والوصول يدويًا إلى مصدر البيانات لتصور البيانات المختلفة. أيضًا ، يمكن استخدام المكونات الإضافية من الأنواع الأخرى (مصدر البيانات واللوحة) ولوحات المعلومات المختلفة كتبعية.


مثال على تبعيات البرنامج المساعد مع type = app .

كلغة برمجة ، يمكنك استخدام كل من JavaScript و TypeScript (اخترناها). يمكنك العثور على الفراغات للمكونات الإضافية لـ hello-world من أي نوع هنا : في هذا المستودع يوجد عدد كبير من حزم البداية (يوجد حتى مثال تجريبي للمكوّن الإضافي على React) مع منشئين مُثبتين مسبقًا ومُكّوَّنين.

الجزء 2: إعداد البيئة المحلية الخاصة بك


للعمل على المكوّن الإضافي ، نحتاج بشكل طبيعي إلى مجموعة kubernetes مع جميع الأدوات المثبتة مسبقًا: بروميثيوس ، مصدر العقدة ، مقاييس حالة المكعبات ، grafana. يجب إعداد البيئة بسرعة وسهولة وبطريقة طبيعية ، ولتوفير بيانات إعادة التحميل السريعة ، يجب تثبيت دليل Grafana مباشرة من جهاز المطور.

الطريقة الأكثر ملاءمة ، في رأينا ، للعمل محلياً مع kubernetes هي minikube . الخطوة التالية هي إنشاء حزمة Prometheus + Grafana باستخدام مشغل prometheus. تفاصيل هذه المقالة عملية تثبيت prometheus- المشغل على minikube. لتمكين الثبات ، يجب عليك تعيين الثبات: المعلمة الحقيقية في ملف المخططات / 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 ، والنشر ، daemonset ، statefulset ، job ، cronjob ، service ، node ، space names. يرث كل من هذه الفئات من فئة 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 = []; } } 

باستخدام getters و setters ، يمكننا عرض أو تعيين مقاييس الكيانات التي نحتاجها بطريقة مريحة وسهلة القراءة. على سبيل المثال ، الإخراج المنسق من إيماءات وحدة المعالجة المركزية القابلة للتخصيص:

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

صفحات

يتم وصف قائمة بجميع صفحات المكون الإضافي لدينا في البداية في pluing.json في قسم التبعية:



في كتلة كل صفحة ، يجب الإشارة إلى PAGE TITLE (سيتم تحويلها بعد ذلك إلى سبيكة ، والتي ستتوفر بها هذه الصفحة) ؛ اسم المكون المسؤول عن تشغيل هذه الصفحة (يتم تصدير قائمة المكونات إلى module.ts) ؛ تحديد دور المستخدم الذي يتوفر له الوصول إلى هذه الصفحة وإعدادات التنقل للشريط الجانبي.

في المكون المسؤول عن تشغيل الصفحة ، يجب علينا تثبيت templateUrl ، لتمرير المسار إلى ملف html مع الترميز. داخل وحدة التحكم ، من خلال حقن التبعية ، يمكننا الوصول إلى خدمات الزاوي الهامة اثنين:

  • backendSrv - خدمة توفر التفاعل مع خادم grafana api
  • datasourceSrv - خدمة توفر تفاعلًا محليًا مع كل مصدر البيانات المثبت في Grafana (على سبيل المثال ، طريقة .getAll () - تُرجع قائمة بجميع مصادر البيانات المثبتة ؛ .get (<name>) - تُرجع كائن مثيل لمصدر بيانات معين.







الجزء 4: مصدر البيانات


من وجهة نظر Grafana ، يعد مصدر البيانات هو نفس المكون الإضافي تمامًا مثل أي شخص آخر: فهو يحتوي على الوحدة النمطية لنقطة الدخول الخاصة به ، ويوجد ملف به plugin.json. عند تطوير مكون إضافي باستخدام type = app ، يمكننا التفاعل مع مصدر بيانات موجود (على سبيل المثال ، مصدر البيانات ، prometheus-datasource) ، وكذلك الخاص بنا ، والذي يمكننا تخزينه مباشرة في دليل البرنامج المساعد (dist / datasource / *) أو تعيينه كجهة تبعية. في حالتنا ، يأتي مصدر البيانات برمز البرنامج المساعد. من الضروري أيضًا امتلاك قالب config.html ووحدة التحكم ConfigCtrl التي سيتم استخدامها لصفحة التكوين الخاصة بمثيل مصدر البيانات ووحدة التحكم Datasource ، والتي تنفذ منطق مصدر بياناتك.

في المكوّن الإضافي KubeGraf ، من وجهة نظر واجهة المستخدم ، يعد مصدر البيانات مثالًا على مجموعة kubernetes التي يتم فيها تطبيق الميزات التالية (يتوفر الكود المصدري حسب المرجع ):

  • جمع البيانات من k8s api-server (الحصول على قائمة بمساحات الأسماء ، ونشر'أو ...)
  • طلبات البروكسي في مصدر البيانات (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 وإعدادات المصادقة / التخويل الأساسية: تسجيل الدخول - كلمة المرور ، أو client-cert / client - key. من أجل إدراك القدرة على تكوين الوصول باستخدام الرمز المميز لحامل (في الواقع المعيار ل k8s) ، كان علي أن أفعل قليلاً "الكيميائية".

لحل هذه المشكلة ، يمكنك استخدام آلية "مسارات البرنامج المساعد" المضمنة في Grafana (المزيد في صفحة الوثائق الرسمية ). في إعدادات مصدر البيانات الخاص بنا ، يمكننا الإعلان عن مجموعة من قواعد التوجيه التي سيتم معالجتها بواسطة خادم الوكيل grafana. على سبيل المثال ، لكل نقطة نهاية منفردة ، هناك إمكانية لتضمين الرؤوس أو عناوين url مع القدرة على القالب ، حيث يمكن الحصول على البيانات من حقول jsonData و secureJsonData (لتخزين كلمات المرور أو الرموز المميزة في نموذج مشفر). في المثال الخاص بنا ، سيتم إرسال طلبات النموذج / __ proxy / api / v1 / مساحات الأسماء إلى عنوان url للنموذج
<your_k8s_api_url> / api / v1 / مساحات الأسماء مع التخويل: Bearer header.





بطبيعة الحال ، للعمل مع k8s api-server ، نحتاج إلى مستخدم لديه إمكانية وصول للقراءة فقط ، وهو بيان الإنشاء الذي يمكنك العثور عليه أيضًا في الكود المصدري للمكون الإضافي .

الجزء 5: الافراج




بعد أن تكتب البرنامج المساعد الخاص بك عن Grafana ، ستحتاج بطبيعة الحال إلى وضعه في المجال العام. Grafana هي مكتبة المكونات الإضافية المتاحة في grafana.com/grafana/plugins

من أجل إتاحة المكون الإضافي الخاص بك في المتجر الرسمي ، يلزمك إجراء العلاقات العامة في هذا المستودع عن طريق إضافة المحتويات التالية إلى ملف repo.json:



حيث يكون الإصدار هو إصدار المكون الإضافي الخاص بك ، فإن url هو رابط للمستودع ، والالتزام هو تجزئة للالتزام ، حيث يتوفر إصدار محدد من المكون الإضافي.

وعند الخروج سترى صورة رائعة للنموذج:



سيتم الحصول على البيانات الخاصة بها تلقائيًا من Readme.md و Changelog.md وملف plugin.json مع وصف المكون الإضافي.

الجزء 6: بدلا من الاستنتاجات


لم نتوقف عن تطوير البرنامج المساعد لدينا بعد الإصدار. والآن نحن نعمل على الرصد الصحيح لاستخدام موارد العقد العنقودية ، وإدخال ميزات جديدة لزيادة UX ، بالإضافة إلى جمع قدر كبير من الملاحظات الواردة بعد تثبيت المكون الإضافي من قبل عملائنا ومن ishui على github (إذا تركت مشكلتك أو طلب السحب ، فأنا سأكون سعيدا جدا :-)).

نأمل أن تساعدك هذه المقالة في فهم هذه الأداة الرائعة مثل Grafana ، وربما كتابة البرنامج المساعد الخاص بك.

شكرا لك!)

Source: https://habr.com/ru/post/ar474500/


All Articles