Grafana Grafana

Grafana Operator で Grafana を管理する

インスタンス、フォルダー、ダッシュボード、データソース、アラートルールを、Kubernetes のカスタムリソースとして宣言します。

15 min learn.level.上級

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 つのツールに所有させてください。

人気のガイド