Grafana Operator で Grafana を管理する
インスタンス、フォルダー、ダッシュボード、データソース、アラートルールを、Kubernetes のカスタムリソースとして宣言します。
Grafana Operator は、すべての Grafana のリソースを Kubernetes のオブジェクトにします。GrafanaDashboard はマニフェストであり、GrafanaDatasource もマニフェストで、operator が、それらを API を通じて Grafana インスタンスに対して調整します。これは、Flux や Argo CD のような GitOps ツールに自然に適合し、Grafana Cloud を含む、クラスターの内部または外部の Grafana インスタンスで機能します。すべてのリソースは、apiVersion: grafana.integreatly.org/v1beta1 を使います。
operator をインストールする
OCI チャートから Helm でインストールします(現在のチャートの場所とバージョンについては operator のインストールのドキュメントを参照し、固定してください)。
helm upgrade -i grafana-operator \
oci://ghcr.io/grafana/helm-charts/grafana-operator \
--namespace grafana --create-namespace \
--version <operator-version>
operator のドキュメントには、Kustomize によるインストールも記載されています。Flux では、同じチャートを HelmRelease に入れます。
インスタンスを記述する
インスタンスは、管理型(operator が Grafana をデプロイする)または外部(すでに存在するものに接続する)にできます。管理型のインスタンス:
apiVersion: grafana.integreatly.org/v1beta1
kind: Grafana
metadata:
name: grafana
namespace: grafana
labels:
dashboards: "grafana"
spec:
config:
log:
mode: console
security:
admin_user: root
admin_password: secret # 例示のみ。下を参照
Grafana Cloud のスタックなどの外部インスタンスは、URL を指し、Secret からトークンを取得します。
apiVersion: grafana.integreatly.org/v1beta1
kind: Grafana
metadata:
name: my-stack
namespace: grafana
labels:
dashboards: my-stack
spec:
external:
url: https://my-stack.grafana.net/
apiKey:
name: grafana-cloud-credentials
key: GRAFANA_CLOUD_INSTANCE_TOKEN
spec.config ブロックは、grafana.ini と同じセクションとキーを受け付けます。実際のパスワードをマニフェストに書かないでください。operator のドキュメントに、Secret から admin の認証情報を読み取る方法が示されています。
インスタンスのラベルは重要です。他のすべてのリソースは、これらのラベルを使って、instanceSelector.matchLabels で対象のインスタンスを選択します。
フォルダー
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaFolder
metadata:
name: applications
spec:
instanceSelector:
matchLabels:
dashboards: "grafana"
title: Applications
uid: applications # 他のリソースが参照できるよう、安定した UID を設定する
title が省略された場合は、metadata.name がデフォルトになります。他のリソースが folderRef でフォルダーを指す場合は、必ず spec.uid を設定してください。これがないと、reconciler が同じ名前の既存のフォルダーを採用してしまう可能性があります。
データソース
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDatasource
metadata:
name: prometheus
spec:
instanceSelector:
matchLabels:
dashboards: "grafana"
datasource:
name: prometheus
type: prometheus
access: proxy
url: http://prometheus-service:9090
isDefault: true
jsonData:
timeInterval: 5s
認証情報は、valuesFrom を通じて、同じ namespace の Secret から取得されるため、マニフェストに現れることはありません。
apiVersion: v1
kind: Secret
metadata:
name: credentials
type: Opaque
stringData:
PROMETHEUS_USERNAME: grafana
PROMETHEUS_PASSWORD: change-me
---
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDatasource
metadata:
name: prometheus-secured
spec:
instanceSelector:
matchLabels:
dashboards: "grafana"
valuesFrom:
- targetPath: basicAuthUser
valueFrom:
secretKeyRef:
name: credentials
key: PROMETHEUS_USERNAME
- targetPath: secureJsonData.basicAuthPassword
valueFrom:
secretKeyRef:
name: credentials
key: PROMETHEUS_PASSWORD
datasource:
name: prometheus-secured
type: prometheus
access: proxy
basicAuth: true
url: http://prometheus-service:9090
secureJsonData:
basicAuthPassword: ${PROMETHEUS_PASSWORD}
url に認証情報を入れないでください。他の Kubernetes の Secret と同様に、Secret を SOPS や External Secrets で暗号化または同期します。
ダッシュボード
GrafanaDashboard は、複数のソースから JSON を取得でき、これが operator の最大の強みです。
# インラインの JSON
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaDashboard
metadata:
name: simple
spec:
resyncPeriod: 30s
instanceSelector:
matchLabels:
dashboards: "grafana"
folderRef: applications
json: >
{ "uid": "simple", "title": "Simple Dashboard", "panels": [] }
# ConfigMap から
spec:
instanceSelector:
matchLabels:
dashboards: "grafana"
configMapRef:
name: dashboard-definition
key: json
# grafana.com や Git の raw ファイルなどの URL から
spec:
instanceSelector:
matchLabels:
dashboards: "grafana"
url: "https://grafana.com/api/dashboards/1860/revisions/30/download"
# OCI アーティファクトから
spec:
instanceSelector:
matchLabels:
dashboards: "grafana"
oci:
reference: ghcr.io/team-a/dashboards:v1.4.7
path: board.json
pullSecretRef:
name: ghcr-pull
使用するその他のフィールド:
folderRefはGrafanaFolderを名前で指し、folderUIDは既存のフォルダーの UID を指します。gzipJsonは、マニフェストには大きすぎるダッシュボード向けに、ダッシュボードを base64 エンコードされた gzip として保持します(cat dashboard.json | gzip | base64 -w0)。variablesは、テンプレート変数を上書きします。たとえば、環境ごとにnamespaceやデータソースを設定する場合です。resyncPeriodとcontentCacheDurationは、コンテンツがどのくらいの頻度で再適用されるか、取得した URL がどのくらいの間キャッシュされるかを制御します。
アラートルール
apiVersion: grafana.integreatly.org/v1beta1
kind: GrafanaAlertRuleGroup
metadata:
name: webapp-alerts
spec:
folderRef: applications
instanceSelector:
matchLabels:
dashboards: "grafana"
interval: 5m
rules:
- uid: webapp-down
title: Webapp targets down
condition: C
for: 5m
noDataState: NoData
execErrState: Error
data:
- refId: A
# Prometheus へのクエリのステップ。アラートのガイドと同じ
- refId: C
# しきい値の式のステップ
すべてのルールグループには、フォルダーと、少なくとも 1 つのルールが必要です。データのステップは、プロビジョニングのファイルと同じ構造を使うため、アラートのガイドの YAML を再利用できます。operator には、コンタクトポイント用のリソースもあります。現在の一覧は、その例を参照してください。
運用する
kubectl get grafanas,grafanafolders,grafanadatasources,grafanadashboards -A
kubectl describe grafanadashboard simple -n grafana
describe は、リソースのステータス条件を表示し、Grafana への最後の同期が成功したかどうか、失敗した場合はその理由を示します。よくある原因:インスタンスに一致しない instanceSelector、間違ったトークン、間違った namespace の Secret。
Operator か、ファイルによるプロビジョニングか
すでに Kubernetes で GitOps を実行していて、各チームが自分のダッシュボードとアラートを別々のオブジェクトとして所有したい、あるいは Grafana Cloud や複数のインスタンスを管理する場合は、Operator を使います。1 つの Grafana と少数のリソースしかない場合は、追加のコントローラーが不要な、Helm チャートのプロビジョニングの values を使います。両者は共存できますが、各リソースは 1 つのツールに所有させてください。
人気のガイド
-
Grafana をコードとして運用する:全体像 ファイルに置けるもの、API が必要なもの、そしてそれらがどう組み合わさるか。 -
grafana.ini と環境変数で Grafana サーバーを設定する 設定ファイルの場所、上書きの順序、設定を Git に保つ方法を理解します。 -
JSON ファイルからダッシュボードをプロビジョニングする ディスクからダッシュボードを読み込み、ディレクトリからフォルダーを対応付け、変更を失わずに作成します。 -
アラートルール、コンタクトポイント、通知ポリシーをプロビジョニングする アラートのパイプライン全体を YAML で定義し、コードのようにレビューしてバージョン管理します。 -
Helm とプロビジョニングの values で Grafana を Kubernetes にデプロイする データソース、ダッシュボード、設定のすべてが values ファイルから来る、Helm チャートで Grafana を実行します。 -
コマンドラインからプロビジョニングを再読み込み、確認、トラブルシューティングする Grafana が何を読み込んだかを調べ、再起動せずに再読み込みし、よくあるプロビジョニングのエラーを修正します。