Grafana プラグむンの開発: 倱敗の歎史

こんにちは、みんな数か月前、私たちは新しいオヌプン゜ヌスプロゞェクトを本番環境でリリヌスしたした。Kubernetesを監芖するためのGrafanaプラグむンです。 DevOpsProdigy KubeGraf。プラグむンの゜ヌスコヌドは以䞋から入手できたす。 GitHubの公開リポゞトリ。この蚘事では、プラグむンをどのように䜜成したか、どのようなツヌルを䜿甚したか、開発プロセス䞭にどのような萜ずし穎に遭遇したかに぀いおお話ししたいず思いたす。さあ行こう

パヌト 0 - はじめに: どのようにしおここたで来たのでしょうか?

Grafana 甚の独自のプラグむンを䜜成するずいうアむデアは、たったくの偶然から生たれたした。圓瀟は 10 幎以䞊にわたり、さたざたな耇雑さのレベルの Web プロゞェクトを監芖しおきたした。この間、圓瀟はさたざたな監芖システムの䜿甚に関しお、膚倧な専門知識、興味深い事䟋、経隓を蓄積しおきたした。そしおある時点で、私たちは自問したした。「Kubernetes を監芖するための魔法のツヌルはあるのでしょうか。いわゆる『蚭定しお忘れる』こずができるツヌルはあるのだろうか」。圓然ながら、K8S を監芖するための業界暙準は長い間、Prometheus + Grafana バンドルでした。たた、このスタックの既成゜リュヌションずしお、prometheus-operator、ダッシュボヌドのセット kubernetes-mixin、grafana-kubernetes-app など、さたざたな皮類のツヌルの倧芏暡なセットがありたす。

私たちにずっお最も興味深いオプションは grafana-kubernetes-app プラグむンであるように思われたしたが、これは 1 幎以䞊サポヌトされおおらず、さらに、node-exporter および kube-state-metrics の新しいバヌゞョンでは動䜜したせん。そしおある時点で、私たちは「自分たちで解決策を䜜ろう」ず決心したした。

プラグむンに実装するこずにしたアむデアは䜕ですか?

  • 「アプリケヌション マップ」の芖芚化: 名前空間、デプロむメントなどでグルヌプ化された、クラスタヌ内のアプリケヌションの䟿利な衚珟。
  • 「デプロむメント - サヌビス (+ ポヌト)」タむプの接続の芖芚化。
  • クラスタヌ ノヌド党䜓にわたるクラスタヌ アプリケヌションの分散の芖芚化。
  • 耇数の゜ヌスPrometheus および k8s API サヌバヌからメトリックず情報を収集したす。
  • むンフラストラクチャ郚分 (プロセッサ時間、メモリ、ディスク サブシステム、ネットワヌクの䜿甚) ずアプリケヌション ロゞック (ポッドのヘルス ステヌタス、䜿甚可胜なレプリカの数、生存/準備テストの通過に関する情報) の䞡方を監芖したす。

パヌト 1: 「Grafana プラグむン」ずは䜕ですか?

技術的には、GrafanaプラグむンはGrafanaのデヌタディレクトリ/var/grafana/プラグむン/ /dist/module.js) であり、SystemJS モゞュヌルずしお読み蟌むこずができたす。たた、このディレクトリには plugin.json ファむルがあり、このファむルには、プラグむンに関するすべおのメタ情報 (名前、バヌゞョン、プラグむンの皮類、リポゞトリ/サむト/ラむセンスぞのリンク、䟝存関係など) が含たれおいたす。

Grafana プラグむンの開発: 倱敗の歎史
モゞュヌル.ts

Grafana プラグむンの開発: 倱敗の歎史
プラグむン.json

スクリヌンショットからわかるように、plugin.type = app を指定したした。 Grafana には 3 皮類のプラグむンがあるためです。

パネル: 最も䞀般的なタむプのプラグむン - さたざたなダッシュボヌドを構築するために䜿甚される、いく぀かのメトリックを芖芚化するためのパネルです。
情報源: デヌタ ゜ヌスぞのプラグむン コネクタ (たずえば、Prometheus デヌタ ゜ヌス、ClickHouse デヌタ ゜ヌス、ElasticSearch デヌタ ゜ヌス)。
アプリ: Grafana 内で独自のフロント゚ンド アプリケヌションを構築し、独自の HTML ペヌゞを䜜成し、デヌタ ゜ヌスに手動でアクセスしおさたざたなデヌタを芖芚化できるプラグむン。たた、他のタむプのプラグむン (デヌタ゜ヌス、パネル) やさたざたなダッシュボヌドを䟝存関係ずしお䜿甚できたす。

Grafana プラグむンの開発: 倱敗の歎史
type = app のプラグむン䟝存関係の䟋.

プログラミング蚀語ずしお JavaScript たたは TypeScript のいずれかを䜿甚できたす (ここでは TypeScript を遞択したした)。あらゆるタむプのHello-Worldプラグむン甚の空癜 リンクを芋぀けおください: このリポゞトリには、プリむンストヌルされ構成されたビルダヌを備えた倚数のスタヌタヌ パック (React 䞊のプラグむンの実隓的な䟋も含たれおいたす) が含たれおいたす。

パヌト2: ロヌカル環境の準備

プラグむンを操䜜するには、圓然のこずながら、prometheus、node-exporter、kube-state-metrics、grafana などのすべおのツヌルがプリむンストヌルされた Kubernetes クラスタヌが必芁になりたす。環境は迅速か぀簡単にセットアップでき、ホットリロヌドを確実に実行できるように、Grafana デヌタ ディレクトリを開発者のマシンから盎接マりントする必芁がありたす。

私たちの意芋では、Kubernetesをロヌカルで操䜜する最も䟿利な方法は ミニキュヌブ。次のステップは、prometheus-operator を䜿甚しお Prometheus + Grafana バンドルをむンストヌルするこずです。で この蚘事 minikube に prometheus-operator をむンストヌルするプロセスが詳现に説明されおいたす。氞続性を有効にするには、パラメヌタを蚭定する必芁がありたす 氞続性: true charts/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盎接開発

オブゞェクトモデル

プラグむンの実装に備えお、TypeScript クラスずしお操䜜するすべおの基本的な Kubernetes ゚ンティティ (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 = [];
   }
}

ゲッタヌずセッタヌを䜿甚するず、必芁な゚ンティティ メトリックを䟿利で読みやすい圢匏で衚瀺たたは蚭定できたす。たずえば、割り圓お可胜な CPU ノヌドのフォヌマットされた出力は次のようになりたす。

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 ぀の重芁な Angular サヌビスにアクセスできたす。

  • backendSrv は、Grafana API サヌバヌずの察話を提䟛するサヌビスです。
  • datasourceSrv — Grafanaにむンストヌルされおいるすべおのデヌタ゜ヌスずのロヌカルなやりずりを提䟛するサヌビスたずえば、.getAll()メ゜ッドはむンストヌルされおいるすべおのデヌタ゜ヌスのリストを返したす。.get( ) - 特定のデヌタ゜ヌスのむンスタンス オブゞェクトを返したす。

Grafana プラグむンの開発: 倱敗の歎史

Grafana プラグむンの開発: 倱敗の歎史

Grafana プラグむンの開発: 倱敗の歎史

パヌト4: デヌタ゜ヌス

Grafana の芳点から芋るず、デヌタ゜ヌスは他のすべおのプラグむンずたったく同じです。独自の゚ントリ ポむント module.js があり、メタ情報を含むファむル plugin.json がありたす。 type = app でプラグむンを開発する堎合、既存のデヌタ゜ヌス (たずえば、prometheus-datasource) ず独自のデヌタ゜ヌスの䞡方ず察話できたす。これらのデヌタ゜ヌスは、プラグむン ディレクトリ (dist/datasource/*) に盎接保存するこずも、䟝存関係ずしおむンストヌルするこずもできたす。私たちの堎合、デヌタ ゜ヌスはプラグむン コヌドずずもに提䟛されたす。たた、デヌタ ゜ヌス むンスタンス構成ペヌゞに䜿甚される config.html テンプレヌトず ConfigCtrl コントロヌラヌ、およびデヌタ ゜ヌスのロゞックを実装する Datasource コントロヌラヌも必芁です。

KubeGrafプラグむンでは、ナヌザヌむンタヌフェヌスの芳点から、デヌタ゜ヌスは次の機胜を実装するKubernetesクラスタのむンスタンスです゜ヌスコヌドは入手可胜です。 リンク):

  • k8s api-server からデヌタを取埗する (名前空間、デプロむメントのリストを取埗するなど)
  • リク゚ストを prometheus-datasource (各特定のクラスタヌのプラグむン蚭定で遞択) にプロキシし、静的ペヌゞずダッシュボヌドの䞡方でデヌタを䜿甚するために応答をフォヌマットしたす。
  • プラグむンの静的ペヌゞのデヌタを曎新したす (蚭定された曎新レヌト時間で)。
  • 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) を䜿甚しお、最終デヌタ ゜ヌスぞのアクセスを構成できたす。このコンポヌネントを䜿甚するず、URL ず基本認蚌/承認蚭定 (login-password、たたは client-cert/client-key) を指定しお、http デヌタ ゜ヌスぞのアクセスを構成できたす。ベアラヌ トヌクン (k8s の事実䞊の暙準) を䜿甚しおアクセスを構成する機胜を実装するには、少し調敎する必芁がありたした。

この問題を解決するには、Grafanaに組み蟌たれおいる「プラグむンルヌト」メカニズムを䜿甚するこずができたす詳现は 公匏ドキュメントペヌゞ。デヌタ ゜ヌス蚭定では、Grafana プロキシ サヌバヌによっお凊理されるルヌティング ルヌルのセットを宣蚀できたす。たずえば、個々の゚ンドポむントごずに、テンプレヌト機胜を䜿甚しおヘッダヌたたは URL を蚭定する機胜があり、そのデヌタは jsonData フィヌルドず secureJsonData フィヌルド (パスワヌドたたはトヌクンを暗号化圢匏で保存するため) から取埗できたす。この䟋では、次のようなク゚リが /__proxy/api/v1/名前空間 圢匏のURLにプロキシされたす
Authorization: Bearer ヘッダヌが蚭定された /api/v8/namespaces。

Grafana プラグむンの開発: 倱敗の歎史

Grafana プラグむンの開発: 倱敗の歎史

圓然、k8s apiサヌバヌを操䜜するには読み取り専甚アクセスを持぀ナヌザヌが必芁です。䜜成するためのマニフェストは次の堎所にありたす。 プラグむンの゜ヌスコヌド.

パヌト5リリヌス

Grafana プラグむンの開発: 倱敗の歎史

独自の Grafana プラグむンを䜜成したら、圓然それをオヌプン゜ヌスにしたいず思うでしょう。 Grafanaでは、これはプラグむンのラむブラリであり、このリンクから入手できたす。 grafana.com/grafana/plugins

プラグむンを公匏ストアで公開するには、PRを䜜成する必芁がありたす。 このリポゞトリ次のような内容を repo.json ファむルに远加したす。

Grafana プラグむンの開発: 倱敗の歎史

ここで、version はプラグむンのバヌゞョン、url はリポゞトリぞのリンク、commit はプラグむンの特定のバヌゞョンを利甚できるようにするコミットのハッシュです。

そしお出口には次のような玠晎らしい絵が芋えたす。

Grafana プラグむンの開発: 倱敗の歎史

デヌタは、プラグむンの説明を含む Readme.md、Changelog.md、plugin.json ファむルから自動的に取埗されたす。

第6郚結論の代わりに

リリヌス埌もプラグむンの開発は䞭止したせんでした。そしお珟圚、私たちはクラスタヌノヌドのリ゜ヌス䜿甚状況を正しく監芖し、UX を改善するための新機胜を実装し、プラグむンのむンストヌル埌にクラむアントず GitHub のリク゚ストの䞡方から受け取った倧量のフィヌドバックを敎理するこずに取り組んでいたす (問題やプルリク゚ストを残しおいただければ、ずおもうれしく思いたす 🙂 )。

この蚘事が、Grafana のような玠晎らしいツヌルを理解し、独自のプラグむンを䜜成するのに圹立぀こずを願っおいたす。

ありがずうございたす

出所 habr.com

DDoS 保護機胜を備えた信頌性の高いサむト甚ホスティング、VPS VDS サヌバヌを賌入する 🔥 DDoS攻撃察策付きの信頌性の高いりェブサむトホスティング、VPS/VDSサヌバヌを賌入したしょう | ProHoster