Pengembangan plugin untuk Grafana: sejarah kesuksesan besar

Halo semua! Beberapa bulan yang lalu, kami meluncurkan proyek sumber terbuka baru ke dalam produksi - plugin Grafana untuk memantau kubernetes, yang kami sebut DevOpsProdigy KubeGraf. Kode sumber plugin tersedia di repositori publik di GitHub. Dan dalam artikel ini kami ingin berbagi dengan Anda kisah tentang bagaimana kami membuat plugin, alat apa yang kami gunakan, dan kendala apa yang kami temui selama proses pengembangan. Ayo pergi!

Bagian 0 - pengantar: bagaimana kita bisa sampai ke titik ini?

Ide untuk menulis plugin kami sendiri untuk Grafan datang kepada kami secara tidak sengaja. Perusahaan kami telah memantau proyek web dengan berbagai tingkat kerumitan selama lebih dari 10 tahun. Selama ini, kami telah mengumpulkan banyak keahlian, kasus menarik, dan pengalaman dalam menggunakan berbagai sistem pemantauan. Dan pada titik tertentu kami bertanya pada diri sendiri: “Apakah ada alat ajaib untuk memantau Kubernetes, sehingga, seperti yang mereka katakan, “atur dan lupakan”?”.. Standar industri untuk memantau k8, tentu saja, telah lama menjadi standar Kombinasi Prometheus + Grafana. Dan sebagai solusi siap pakai untuk tumpukan ini, terdapat seperangkat besar berbagai jenis alat: operator prometheus, satu set dasbor kubernetes-mixin, grafana-kubernetes-app.

Plugin grafana-kubernetes-app tampaknya menjadi opsi yang paling menarik bagi kami, tetapi plugin tersebut belum didukung selama lebih dari satu tahun dan, terlebih lagi, tidak dapat bekerja dengan versi baru dari node-exporter dan kube-state-metrics. Dan pada titik tertentu kami memutuskan: “Bukankah sebaiknya kita mengambil keputusan sendiri?”

Ide apa yang kami putuskan untuk diterapkan di plugin kami:

  • visualisasi "peta aplikasi": presentasi aplikasi yang nyaman di cluster, dikelompokkan berdasarkan namespace, penerapan...;
  • visualisasi koneksi seperti "penempatan - layanan (+port)".
  • visualisasi distribusi aplikasi cluster di seluruh node cluster.
  • kumpulan metrik dan informasi dari beberapa sumber: Prometheus dan server api k8s.
  • pemantauan bagian infrastruktur (penggunaan waktu CPU, memori, subsistem disk, jaringan) dan logika aplikasi - pod status kesehatan, jumlah replika yang tersedia, informasi tentang kelulusan uji keaktifan/kesiapan.

Bagian 1: Apa itu “plugin Grafana”?

Dari segi teknis, plugin untuk Grafana adalah pengontrol sudut, yang disimpan di direktori data Grafana (/var/grafana/plugin/ /dist/module.js) dan dapat dimuat sebagai modul SystemJS. Di direktori ini juga harus ada file plugin.json yang berisi semua informasi meta tentang plugin Anda: nama, versi, jenis plugin, tautan ke repositori/situs/lisensi, dependensi, dan sebagainya.

Pengembangan plugin untuk Grafana: sejarah kesuksesan besar
modul.ts

Pengembangan plugin untuk Grafana: sejarah kesuksesan besar
plugin.json

Seperti yang Anda lihat di tangkapan layar, kami menentukan plugin.type = app. Karena plugin untuk Grafana bisa terdiri dari tiga jenis:

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

Pengembangan plugin untuk Grafana: sejarah kesuksesan besar
Contoh dependensi plugin dengan type=app.

Anda dapat menggunakan JavaScript dan TypeScript sebagai bahasa pemrograman (kami memilihnya). Persiapan untuk plugin hello-world jenis apa pun yang Anda bisa temukan tautannya: repositori ini berisi sejumlah besar starter-pack (bahkan ada contoh eksperimental plugin di React) dengan pembuat yang sudah diinstal sebelumnya dan dikonfigurasi.

Bagian 2: mempersiapkan lingkungan setempat

Untuk mengerjakan plugin ini, kita tentu memerlukan cluster kubernetes dengan semua alat yang sudah diinstal sebelumnya: prometheus, node-exporter, kube-state-metrics, grafana. Lingkungan harus diatur dengan cepat, mudah dan alami, dan untuk memastikan hot-reload, direktori data Grafana harus dipasang langsung dari mesin pengembang.

Menurut kami, cara paling nyaman untuk bekerja secara lokal dengan kubernetes adalah minikube. Langkah selanjutnya adalah menginstal kombinasi Prometheus + Grafana menggunakan operator prometheus. DI DALAM artikel ini Proses instalasi operator prometheus di minikube dijelaskan secara rinci. Untuk mengaktifkan persistensi, Anda harus mengatur parameternya ketekunan: benar di file chart/grafana/values.yaml, tambahkan PV dan PVC Anda sendiri dan tentukan di parameter persistence.existenceClaim

Skrip peluncuran minikube terakhir kami 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: perkembangan aktual

Model Objek

Sebagai persiapan untuk mengimplementasikan plugin, kami memutuskan untuk mendeskripsikan semua entitas dasar Kubernetes yang akan kami gunakan dalam bentuk kelas TypeScript: pod, deployment, daemonset, statefulset, job, cronjob, service, node, namespace. Masing-masing kelas ini mewarisi 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 dengan tipe penerapan.

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 bantuan pengambil dan penyetel, kita dapat menampilkan atau mengatur metrik entitas yang kita perlukan dalam bentuk yang nyaman dan mudah dibaca. Misalnya, keluaran yang diformat dari node cpu yang dapat dialokasikan:

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

Pages

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

Pengembangan plugin untuk Grafana: sejarah kesuksesan besar

Di blok untuk setiap halaman kita harus menunjukkan NAMA HALAMAN (kemudian akan diubah menjadi siput sehingga halaman ini dapat diakses); nama komponen yang bertanggung jawab atas pengoperasian halaman ini (daftar komponen diekspor ke module.ts); menunjukkan peran pengguna yang tersedia untuk bekerja dengan halaman ini dan pengaturan navigasi untuk sidebar.

Dalam komponen yang bertanggung jawab atas pengoperasian halaman, kita harus menyetel templateUrl, meneruskan jalur ke file html dengan markup di sana. Di dalam pengontrol, melalui injeksi ketergantungan, kita dapat mengakses hingga 2 layanan sudut penting:

  • backendSrv - layanan yang menyediakan interaksi dengan server API Grafana;
  • datasourceSrv - layanan yang menyediakan interaksi lokal dengan semua sumber data yang terpasang di Grafana Anda (misalnya, metode .getAll() - mengembalikan daftar semua sumber data yang terpasang; .get( ) - mengembalikan objek instan dari sumber data tertentu.

Pengembangan plugin untuk Grafana: sejarah kesuksesan besar

Pengembangan plugin untuk Grafana: sejarah kesuksesan besar

Pengembangan plugin untuk Grafana: sejarah kesuksesan besar

Bagian 4: sumber data

Dari sudut pandang Grafana, sumber data adalah plugin yang persis sama dengan plugin lainnya: ia memiliki titik masuknya sendiri module.js, ada file dengan informasi meta plugin.json. Saat mengembangkan plugin dengan type = app, kita dapat berinteraksi dengan sumber data yang ada (misalnya, prometheus-datasource) dan sumber data kita sendiri, yang dapat kita simpan langsung di direktori plugin (dist/datasource/*) atau dipasang sebagai ketergantungan. Dalam kasus kami, sumber data dilengkapi dengan kode plugin. Anda juga perlu memiliki templat config.html dan pengontrol ConfigCtrl, yang akan digunakan untuk halaman konfigurasi instans sumber data dan pengontrol Sumber Data, yang mengimplementasikan logika sumber data Anda.

Pada plugin KubeGraf, dari sudut pandang antarmuka pengguna, sumber data adalah sebuah instance dari cluster kubernetes yang mengimplementasikan kemampuan berikut (kode sumber tersedia по ссылке):

  • mengumpulkan data dari server api k8s (mendapatkan daftar namespace, penerapan...)
  • memproksi permintaan ke sumber data prometheus (yang dipilih dalam pengaturan plugin untuk setiap cluster tertentu) dan memformat respons untuk menggunakan data baik di halaman statis maupun di dasbor.
  • memperbarui data pada halaman plugin statis (dengan kecepatan refresh yang ditetapkan).
  • memproses kueri untuk menghasilkan lembar templat di dasbor grafana (metode metrikFindQuery())

Pengembangan plugin untuk Grafana: sejarah kesuksesan besar

Pengembangan plugin untuk Grafana: sejarah kesuksesan besar

Pengembangan plugin untuk Grafana: sejarah kesuksesan besar

  • tes koneksi dengan cluster k8s terakhir.
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"};
       })
}

Hal menarik tersendiri, menurut kami, adalah penerapan mekanisme autentikasi dan otorisasi sumber data. Biasanya, secara langsung, kita dapat menggunakan komponen Grafana bawaan datasourceHttpSettings untuk mengonfigurasi akses ke sumber data akhir. Dengan menggunakan komponen ini, kita dapat mengkonfigurasi akses ke sumber data http dengan menentukan url dan pengaturan otentikasi/otorisasi dasar: kata sandi login, atau sertifikat klien/kunci klien. Untuk mengimplementasikan kemampuan mengonfigurasi akses menggunakan token pembawa (standar de facto untuk k8s), kami harus melakukan sedikit penyesuaian.

Untuk mengatasi masalah ini, Anda dapat menggunakan mekanisme “Rute Plugin” Grafana yang ada di dalamnya (detail 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 dimungkinkan untuk mengatur header atau url dengan kemungkinan templating, data yang dapat diambil dari bidang jsonData dan secureJsonData (untuk menyimpan kata sandi atau token dalam bentuk terenkripsi). Dalam contoh kita, pertanyaan seperti /__proxy/api/v1/namespaces akan diproxy ke url formulir
/api/v8/namespaces dengan Otorisasi: Header pembawa.

Pengembangan plugin untuk Grafana: sejarah kesuksesan besar

Pengembangan plugin untuk Grafana: sejarah kesuksesan besar

Secara alami, untuk bekerja dengan server api k8s kita memerlukan pengguna dengan akses hanya baca, manifes untuk pembuatannya juga dapat Anda temukan di kode sumber plugin.

Bagian 5: rilis

Pengembangan plugin untuk Grafana: sejarah kesuksesan besar

Setelah Anda menulis plugin Grafana Anda sendiri, Anda tentu ingin membuatnya tersedia untuk umum. Di Grafana, ini adalah perpustakaan plugin yang tersedia di sini grafana.com/grafana/plugins

Agar plugin Anda tersedia di toko resmi, Anda perlu membuat PR repositori inidengan menambahkan konten seperti ini ke file repo.json:

Pengembangan plugin untuk Grafana: sejarah kesuksesan besar

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

Dan hasilnya Anda akan melihat gambar indah seperti:

Pengembangan plugin untuk Grafana: sejarah kesuksesan besar

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

Bagian 6: bukannya kesimpulan

Kami tidak berhenti mengembangkan plugin kami setelah rilis. Dan sekarang kami sedang berupaya memantau dengan benar penggunaan sumber daya node cluster, memperkenalkan fitur-fitur baru untuk meningkatkan UX, dan juga mengumpulkan banyak masukan yang diterima setelah menginstal plugin baik oleh klien kami maupun dari orang-orang di GitHub (jika Anda keluar masalah atau permintaan tarik Anda, saya akan sangat senang :)

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

Terima kasih!)

Sumber: www.habr.com

Tambah komentar