مرحبا بالجميع! قبل بضعة أشهر ، أطلقنا مشروعنا الجديد المفتوح المصدر ، البرنامج المساعد 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 ، وربما كتابة البرنامج المساعد الخاص بك.
شكرا لك!)