Pengembangan plugin untuk Grafana: kisah kerucut penuh

Halo semuanya! Beberapa bulan yang lalu, kami meluncurkan proyek open-source baru kami, plugin Grafana untuk memantau kubernet, yang disebut DevOpsProdigy KubeGraf, ke dalam produksi . Kode sumber plugin tersedia di repositori publik di GitHub . Dan dalam artikel ini kami ingin berbagi dengan Anda sebuah kisah tentang bagaimana kami membuat plug-in, alat apa yang kami gunakan dan perangkap apa yang kami temui selama proses pengembangan. Ayo pergi!

Bagian 0 - pengantar: bagaimana kita mencapai ini?


Gagasan untuk menulis plugin kami sendiri untuk Grafan lahir secara kebetulan. Perusahaan kami telah memantau proyek web dari berbagai tingkat kompleksitas selama lebih dari 10 tahun. Selama waktu ini, kami telah memperoleh banyak keahlian, kasus menarik, dan pengalaman dalam menggunakan berbagai sistem pemantauan. Dan di beberapa titik kami bertanya pada diri sendiri: "Apakah ada alat ajaib untuk memantau Kubernetes sehingga, seperti yang mereka katakan," mengatur dan melupakan "? ... Promstandart untuk memantau k8, tentu saja, telah lama menjadi sekelompok Prometheus + Grafana. Dan sebagai solusi siap pakai untuk tumpukan ini, ada satu set besar berbagai macam alat: prometheus-operator, seperangkat dashboard kubernet-mixin, aplikasi grafana-kubernetes.

Plugin grafana-kubernetes-app tampaknya menjadi pilihan yang paling menarik bagi kami, tetapi belum didukung selama lebih dari satu tahun dan, lebih lanjut, tidak tahu bagaimana bekerja dengan versi baru dari simpul-eksportir dan metrik-negara-kubus. Dan pada titik tertentu, kami memutuskan: "Tapi bukankah kita membuat keputusan sendiri?"

Gagasan apa yang kami putuskan untuk diterapkan dalam plugin kami:

  • visualisasi "peta aplikasi": presentasi aplikasi yang nyaman di cluster, dikelompokkan berdasarkan namespace, penyebaran ...;
  • visualisasi koneksi dari bentuk "penyebaran - layanan (+ port)".
  • visualisasi distribusi aplikasi cluster oleh anggukan cluster.
  • mengumpulkan metrik dan informasi dari beberapa sumber: Prometheus dan server api k8s.
  • pemantauan kedua bagian infrastruktur (penggunaan waktu prosesor, memori, subsistem disk, jaringan), dan logika aplikasi - pod status kesehatan, jumlah replika yang tersedia, informasi tentang bagian sampel sampel liveness / readyness.

Bagian 1: Apa itu Plugin Grafana?


Dari sudut pandang teknis, plugin untuk Grafana adalah pengontrol sudut, yang disimpan di direktori data Grafan ( /var/grafana/plugins/<your_plugin_name>/dist/module.js ) dan dapat dimuat sebagai modul SystemJS. Juga dalam direktori ini harus berupa file plugin.json yang berisi semua meta-informasi tentang plugin Anda: nama, versi, jenis plugin, tautan ke repositori / situs / lisensi, dependensi, dan sebagainya.


module.ts


plugin.json

Seperti yang Anda lihat di tangkapan layar, kami menentukan plugin.type = aplikasi. Untuk plugin untuk Grafana dapat terdiri dari tiga jenis:

panel : jenis plug-in yang paling umum - ini adalah panel untuk memvisualisasikan metrik apa pun, digunakan untuk membuat berbagai dasbor.
sumber data : konektor plug-in ke sumber data apa pun (misalnya, sumber data Prometheus, sumber data ClickHouse, Sumber data ElasticSearch).
app : sebuah plugin yang memungkinkan Anda untuk membangun aplikasi frontend Anda sendiri di dalam Grafana, membuat halaman html Anda sendiri dan secara manual mengakses sumber data untuk memvisualisasikan berbagai data. Juga, plugin jenis lain (sumber data, panel) dan berbagai dasbor dapat digunakan sebagai dependensi.


Contoh dependensi plugin dengan type = app .

Sebagai bahasa pemrograman, Anda dapat menggunakan JavaScript dan TypeScript (kami memilihnya). Anda dapat menemukan blanko untuk plug-in halo-dunia dari jenis apa pun di sini : di repositori ini ada sejumlah besar starter-pack (bahkan ada contoh eksperimental dari plugin on React) dengan pembangun yang sudah diinstal dan dikonfigurasi.

Bagian 2: mempersiapkan lingkungan lokal Anda


Untuk bekerja pada plugin, kita tentu saja memerlukan kubernetes cluster dengan semua alat yang sudah diinstal: prometheus, eksportir-simpul, metrik negara-kubus, grafana. Lingkungan harus diatur dengan cepat, mudah dan alami, dan untuk menyediakan data hot-reload, direktori Grafana harus dipasang langsung dari mesin pengembang.

Menurut pendapat kami, cara yang paling nyaman untuk bekerja secara lokal dengan kubernet adalah minikube . Langkah selanjutnya adalah membuat bundel Prometheus + Grafana menggunakan operator-prometheus. Artikel ini merinci proses pemasangan prometheus-operator di minikube. Untuk mengaktifkan kegigihan, Anda harus mengatur parameter kegigihan: true dalam file grafik / grafana / values.yaml, tambahkan PV dan PVC Anda sendiri dan tentukan dalam parameter persistence.existingClaim

Skrip peluncuran minikube terakhir terlihat seperti ini:

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 

Bagian 3: pengembangan itu sendiri


Model objek

Dalam persiapan untuk implementasi plugin, kami memutuskan untuk menggambarkan semua entitas Kubernetes dasar yang akan kami gunakan sebagai kelas TypeScript: pod, deployment, daemonset, statefulset, job, cronjob, service, node, namespace. Setiap kelas ini mewarisi dari kelas BaseModel umum, yang menjelaskan konstruktor, destruktor, metode untuk memperbarui dan mengalihkan visibilitas. Masing-masing kelas menjelaskan hubungan bertingkat dengan entitas lain, misalnya, daftar pod untuk entitas penyebaran tipe.

 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 = []; } } 

Dengan menggunakan getter dan setter, kita dapat menampilkan atau mengatur metrik entitas yang kita butuhkan dengan cara yang nyaman dan mudah dibaca. Misalnya, output terformat dari cpu yang dapat dialokasikan mengangguk:

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

Halaman

Daftar semua halaman plugin kami pada awalnya dijelaskan di pluing.json kami di bagian dependensi:



Di blok untuk setiap halaman, kita harus menunjukkan JUDUL HALAMAN (itu kemudian akan dikonversi menjadi siput, dimana halaman ini akan tersedia); nama komponen yang bertanggung jawab untuk pengoperasian halaman ini (daftar komponen diekspor ke module.ts); menentukan peran pengguna untuk siapa akses ke halaman ini tersedia dan pengaturan navigasi untuk bilah samping.

Dalam komponen yang bertanggung jawab untuk operasi halaman, kita harus menginstal templateUrl, melewati path ke file html dengan markup. Di dalam controller, melalui injeksi ketergantungan, kita dapat mengakses hingga 2 layanan sudut penting:

  • backendSrv - layanan yang menyediakan interaksi dengan server-api grafana;
  • dataourceSrv - layanan yang menyediakan interaksi lokal dengan semua sumber data yang dipasang di Grafana Anda (misalnya, metode .getAll () - mengembalikan daftar semua dataource'ov yang diinstal; .get (<nama>) - mengembalikan objek contoh dari sumber data tertentu.







Bagian 4: sumber data


Dari sudut pandang Grafana, sumber data persis plug-in yang sama seperti orang lain: ia memiliki entri sendiri module.js, ada file dengan meta-information plugin.json. Ketika mengembangkan sebuah plugin dengan type = app, kita dapat berinteraksi dengan kedua sumber data yang ada (misalnya, prometheus-dataource), dan milik kita sendiri, yang dapat kita simpan langsung di direktori plugin (dist / dataource / *) atau ditetapkan sebagai ketergantungan. Dalam kasus kami, sumber data dilengkapi dengan kode plugin. Anda juga wajib memiliki templat config.html dan pengontrol ConfigCtrl yang akan digunakan untuk halaman konfigurasi instance sumber data dan pengontrol Datasource, yang mengimplementasikan logika sumber data Anda.

Di plugin KubeGraf, dari sudut pandang antarmuka pengguna, sumber data adalah turunan dari kubernetes cluster di mana fitur-fitur berikut diimplementasikan (kode sumber tersedia dengan referensi ):

  • pengumpulan data dari k8s api-server (mendapatkan daftar namespace'ov, deployment'ov ...)
  • proksi permintaan dalam prometheus-dataource (yang dipilih dalam pengaturan plugin untuk setiap cluster tertentu) dan memformat respons untuk menggunakan data di halaman statis dan dashboard.
  • memperbarui data pada halaman statis plugin (dengan kecepatan refresh yang ditetapkan).
  • memproses permintaan untuk membuat daftar templat dalam metode grafana-dashboard (.metriFindQuery ())







  • uji koneksi dengan cluster k8s akhir.


 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"}; }) } 

Poin menarik yang terpisah, menurut pendapat kami, adalah penerapan mekanisme otentikasi dan otorisasi untuk sumber data. Sebagai aturan, di luar kotak untuk mengkonfigurasi akses ke sumber data akhir, kita dapat menggunakan komponen Grafana bawaan - dataourceHttpSettings. Dengan menggunakan komponen ini, kita dapat mengonfigurasi akses ke sumber data http dengan menentukan url dan pengaturan otentikasi / otorisasi dasar: login-password, atau client-cert / client-key. Untuk mewujudkan kemampuan mengkonfigurasi akses menggunakan token pembawa (de facto standar untuk k8s), saya harus melakukan sedikit "bahan kimia".

Untuk mengatasi masalah ini, Anda dapat menggunakan mekanisme “Plugin Plugin” bawaan Grafana (lebih lanjut di halaman dokumentasi resmi ). Dalam pengaturan sumber data kami, kami dapat mendeklarasikan seperangkat aturan perutean yang akan diproses oleh server proxy grafana. Misalnya, untuk setiap titik akhir individu ada kemungkinan membubuhkan tajuk atau url dengan kemampuan untuk templat, data yang dapat diambil dari bidang jsonData dan secureJsonData (untuk menyimpan kata sandi atau token dalam bentuk terenkripsi). Dalam contoh kami, permintaan formulir / __ proxy / api / v1 / namespaces akan diproksi ke url formulir
<your_k8s_api_url> / api / v1 / namespaces dengan header Otorisasi: Bearer.





Secara alami, untuk bekerja dengan api-server k8s, kita memerlukan pengguna dengan akses yang hanya bisa dibaca, manifes untuk membuat yang juga dapat Anda temukan di kode sumber plugin .

Bagian 5: lepaskan




Setelah Anda menulis plugin Anda sendiri untuk Grafana, Anda tentu ingin meletakkannya di domain publik. Grafana adalah perpustakaan plugin yang tersedia di grafana.com/grafana/plugins

Agar plugin Anda tersedia di toko resmi, Anda perlu melakukan PR dalam repositori ini dengan menambahkan konten berikut ke file repo.json:



di mana versi adalah versi plugin Anda, url adalah tautan ke repositori, dan commit adalah hash dari commit, di mana versi plugin tertentu akan tersedia.

Dan di pintu keluar Anda akan melihat gambar indah dari formulir:



Data untuk itu akan secara otomatis diambil dari Readme.md Anda, Changelog.md dan file plugin.json dengan deskripsi plugin.

Bagian 6: bukannya kesimpulan


Kami tidak berhenti mengembangkan plugin kami setelah rilis. Dan sekarang kami bekerja pada pemantauan yang benar dari penggunaan sumber daya node cluster, pengenalan fitur baru untuk meningkatkan UX, serta menyapu dalam jumlah besar umpan balik yang diterima setelah menginstal plugin baik oleh klien kami dan dari ishui pada github (jika Anda meninggalkan masalah Anda atau menarik permintaan, saya Saya akan sangat senang :-)).

Kami berharap artikel ini akan membantu Anda memahami alat hebat seperti Grafana dan, mungkin, menulis plugin Anda sendiri.

Terima kasih!)

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


All Articles