Grafana系列-GaC-1-Grafana即代碼的幾種實(shí)現(xiàn)方式

系列文章

概述

GaC(Grafana as Code, Grafana 即代碼) 很明顯是擴(kuò)展自 IaC(Infrastructure as Code, 基礎(chǔ)設(shè)施即代碼)的概念.

Terraform 系列 - 什么是 IaC?一文中, 我們已經(jīng)詳細(xì)地說(shuō)明了相關(guān)的概念, 我們可以直接套用在 GaC 上:

Grafana 即代碼 (Grafana as Code, GaC) 是指通過(guò) 代碼 而不是手動(dòng)流程 / 控制臺(tái)點(diǎn)擊來(lái)管理和配置 Grafana。

這里有 2 個(gè)關(guān)鍵詞:

  • Grafana
  • Code

Grafana 是被管理對(duì)象,在這里,不僅僅是指 Grafana OSS 這一款產(chǎn)品, 還包括 Grafana Labs 提供的商業(yè)產(chǎn)品和云服務(wù). 包括不限于:

  • Grafana Alerting
  • Grafna Cloud Stack, 包括 Grafana Cloud 的:
    • 認(rèn)證
    • 權(quán)限
    • 策略
    • Service Account
    • 組織
    • ...
  • Grafana Enterprise (企業(yè)版)
  • Grafana OnCall: 事件響應(yīng)和管理平臺(tái)(IRM)
  • Grafana SLO: SLA 和 可用性管理
  • Grafana Synthetic Monitoring: 撥測(cè), 類(lèi)似 BlackBoxProbe

Code 是管理方式,即像管理代碼一樣管理 Grafana 資源。那么管理代碼最重要的部分: 版本管理是繞不開(kāi)的。
...

當(dāng)然, 這一系列文章, 主要還是關(guān)注于通過(guò)代碼的形式來(lái)管理 Grafana 這個(gè)產(chǎn)品.

這篇文章主要跟著Grafana as code: A complete guide to tools, tips, and tricks 這篇官方文章的邏輯來(lái)進(jìn)行, 變穿插筆者的評(píng)價(jià)和最終選擇.

GaC 的幾種官方方案

官方推薦這么幾種方案, 另外我也會(huì)加幾個(gè)我認(rèn)為可行的方案:

是不是有點(diǎn)琳瑯滿(mǎn)目, 是不是有點(diǎn)挑花眼了? ??????

我剛開(kāi)始也是這樣, 不用擔(dān)心, 我們一一過(guò)一下. 很快 GaC 的脈絡(luò)就會(huì)清晰起來(lái).

??Notes:

這里面 Crossplane 大家可能沒(méi)怎么聽(tīng)過(guò), 剛好我 2021 年有一篇介紹其的文章, 感興趣的可以作為擴(kuò)展閱讀.

Jsonnet

根據(jù) Grafana 的一些官方演講視頻和代碼庫(kù)以及博客文章, Grafana 是重度依賴(lài) Jsonnet 這一配置語(yǔ)言的. 后面我們會(huì)詳細(xì)介紹其歷史及使用方法.

無(wú)論我們使用哪一種 GaC 方案, 基于 Jsonnet 的 Dashboard as Code 都是必選的.

  • 在 Terraform 中, 可以通過(guò)Jsonnet Provider 和 Grafana 配合使用
  • 在 Ansible 中, 可以在 task 之前加入對(duì) jsonnet 相關(guān)依賴(lài)的安裝, 以及 jsonnet 生成 Dashboard 的前置 tasks
  • 在 Grizzly 和 Tanka 中, jsonnet 就是一級(jí)公民. 如 Grizzly 可以直接使用 Jsonnet
  • ...

小結(jié), Jsonnet 是目前幾乎唯一的深度 Dashboard as Code 方案, 必選.

??Notes:
如果是淺顯地應(yīng)用 GaC, 那么 Dashboard 直接通過(guò) Dashboard json 文件作為代碼管理也可以.
但是進(jìn)入使用深水區(qū), 在 Dashboard 多起來(lái), 且有大量重復(fù)的配置的情況下, Jsoonet 是唯一選擇.

Grafana Terraform provider

Grafana 管理員可以使用Grafana的Terraform Provider 管理 dashboards 和 alerts,添加 synthetic monitoring probes 和檢查,管理身份和訪(fǎng)問(wèn),等等。

用于創(chuàng)建儀表盤(pán)的Terraform配置示例如下:

resource "grafana_dashboard" "metrics" {
  config_json = jsonencode({
    title   = "as-code dashboard"
    uid     = "ascode"
  })
}

適用用戶(hù)

Grafana Terraform Provider 更適合那些已經(jīng)在非Grafana使用案例中使用Terraform的用戶(hù)。

對(duì)于目前希望在Grafana Cloud 或Grafana的OSS部署上管理整個(gè)Grafana生態(tài)系統(tǒng)資源的用戶(hù),最好使用Grafana Terraform Provider,因?yàn)榕cGrafana的其他作為代碼的解決方案相比,它還支持最多的Grafana資源

筆者的最終選擇, 就是:

  • Grafana Terraform Provider + Jsonnet

其中很大的一個(gè)原因就是上面提到的: 支持最多的Grafana資源.

筆者計(jì)劃在 Aws Managed Grafana 中使用 Grafana, Aws Managed Grafana 相比 Grafana OSS, 功能還是有一點(diǎn)點(diǎn)的細(xì)微差別:

  • AWS Managed Grafana 有 DataSource 的 Permission 管理功能, 而 Grafana OSS 并沒(méi)有這項(xiàng)功能.

但是 Grafana Terraform Provider 是提供這一功能的, 該功能位于 Grafana Enterprise 下面. 但確實(shí)可用.

目前我需要用到的 Grafana 功能有:

  • Grafana 用戶(hù)
  • Grafana Team
  • Grafana 組織
  • Grafana DataSource
  • Grafana DataSource Permission
  • Grafana Folder
  • Grafana Folder Permission
  • Grafana Dashboard
  • Grafana Dashboard Permission
  • Grafana Alerting

只有 Grafana Terraform Provider 提供了完整的功能.

已知的限制

管理儀表盤(pán)并不是一個(gè)最簡(jiǎn)單的過(guò)程--用戶(hù)必須處理長(zhǎng)長(zhǎng)的JSON,這也會(huì)變得難以審查和更新。Grafonnet可以幫助生成可用于Terraform的儀表盤(pán)JSON,但Grafonnet需要了解Jsonnet,所以這對(duì)一些用戶(hù)來(lái)說(shuō)是不可取的。

不管哪種方案, Jsonnet 其實(shí)是對(duì)所有進(jìn)入 GaC 深水區(qū)的用戶(hù)都必須掌握的, 逃不掉的.

Grafana Ansible collection

配置管理的資源可以通過(guò)Ansible Collection for Grafana提供。它可以用來(lái)管理各種資源,包括 folders、cloudstack和dashboards。用戶(hù)可以通過(guò)編寫(xiě)使用HTTP API管理Grafana資源的Ansible playbooks,以編程方式管理Grafana上目前還不屬于Grafana Ansible集合的資源。

創(chuàng)建儀表盤(pán)的Ansible配置示例如下:

- name: dashboard as code
  grafana.grafana.dashboard:
    dashboard: {
      "title": "as-code dashboard",
      "uid": "ascode"
    }
    stack_slug: "{{ stack_slug }}"
    grafana_api_key: "{{ grafana_api_key }}"
    state: present

適用用戶(hù)

和Terraform一樣,Grafana Ansible Collection 更適合已經(jīng)將Ansible用于非Grafana用例的人。此外,該 Collection 目前只適用于Grafana Cloud,所以它對(duì)那些希望使用Ansible聲明式管理資源的Grafana Cloud客戶(hù)最有意義。

已知的限制

截至目前,Grafana Ansible Collection 只適用于Grafana Cloud,并且只支持8種資源

  • API密鑰
  • Cloud Stack
  • plugins
  • dashboards
  • folders
  • data sources
  • alert contact points
  • alert notification policies

對(duì)于希望用Ansible以代碼形式管理整個(gè)Grafana生態(tài)系統(tǒng)的用戶(hù)來(lái)說(shuō),這可能是一個(gè)缺點(diǎn)。與Terraform一樣,儀表盤(pán)的構(gòu)建也不是最簡(jiǎn)單的過(guò)程。

小結(jié), Grafana Ansible Collection 最大的缺點(diǎn)在于: 只適用于Grafana Cloud,并且只支持8種資源.

Grizzly

Grizzly 是一個(gè)命令行工具,允許你用代碼管理你的可觀察性資源。Grizzly支持Kubernetes啟發(fā)的YAML表示的Grafana資源,這使得它更容易熟悉。Grizzly支持在Grafana實(shí)例內(nèi)移動(dòng)儀表盤(pán),也可以檢索已經(jīng)配置的Grafana資源的信息。Grizzly目前支持:

  • Grafana dashboards/dashboard folders
  • Grafana data sources
  • Grafana Cloud 中的 Prometheus recording rules/alerts
  • Grafana Cloud Synthetic Monitoring checks

Grizzly也可以使用 Grafonnet 部署在Jsonnet中構(gòu)建的儀表盤(pán)。(在Grafonnet文檔中了解更多信息)。

用于創(chuàng)建儀表盤(pán)的Kubernetes風(fēng)格的Grizzly配置樣本看起來(lái)是這樣的:

apiVersion: grizzly.grafana.com/v1alpha1
kind: Dashboard
metadata:
    name: as-code-dashboard
spec:
    title: as-code dashboard
    uid: ascode

適用用戶(hù)

Grizzly最適合使用Jsonnet來(lái)管理Grafana資源的用戶(hù),或者喜歡用Kubernetes風(fēng)格的YAML定義他們的Grafana資源。

已知的限制

Grizzly目前不支持Grafana OnCall和Grafana Alerting資源。

也不支持 DataSource/Folder/Dashboard Permission 等資源.

小結(jié), Grizzly最適合使用Jsonnet來(lái)管理Grafana資源的用戶(hù). 但是支持的 Grafana 資源也不夠全.

Grafana Crossplane provider

Grafana Crossplane Provider 使用Terrajet構(gòu)建,為Grafana Terraform Provider 支持的所有資源提供支持。它使用戶(hù)能夠?qū)rafana資源定義為Kubernetes清單,也會(huì)幫助那些使用ArgoCD等工具圍繞Kubernetes清單建立GitOps管道的用戶(hù)。

要開(kāi)始使用Grafana Crossplane Provider,請(qǐng)?jiān)贙ubernetes集群中安裝Crossplane,并使用此命令安裝 provider:

kubectl crossplane install provider grafana/crossplane-provider-grafana:v0.1.0

在安裝 provider 的過(guò)程中,Terraform provider 支持的所有資源的CRD被添加到集群中,因此用戶(hù)可以開(kāi)始將他們的Grafana資源定義為Kubernetes自定義資源。Crossplane provider 確保在 CRD 中所定義的內(nèi)容在Grafana用戶(hù)界面中是可見(jiàn)的。如果在用戶(hù)界面中直接進(jìn)行了任何更改,那么當(dāng)提供者重新同步時(shí),這些更改將被丟棄。這有助于確保集群中的任何聲明性定義都將是Grafana資源的真實(shí)來(lái)源。

要開(kāi)始使用,請(qǐng)參考Grafana Crossplane資源庫(kù)中的示例文件夾。

用于創(chuàng)建 Dashboard 的Kubernetes CRD 樣本看起來(lái)像這樣:

apiVersion: grafana.jet.crossplane.io/v1alpha1
kind: Dashboard
metadata:
  name: as-code-dashboard
spec:
  forProvider:
    configJson: |
      {
        "title": "as-code dashboard",
        "uid": "ascode"
      }
  providerConfigRef:
    name: grafana-crossplane-provider

適用用戶(hù)

Grafana Crossplane provider 適合現(xiàn)有的Crossplane用戶(hù),他們希望從Kubernetes內(nèi)管理Grafana資源,并作為Kubernetes清單用于GitOps管道。

已知限制

Crossplane provider 依賴(lài)于在Kubernetes集群中安裝了Crossplane CLI和Crossplane。這種依賴(lài)性對(duì)于非Crossplane用戶(hù)來(lái)說(shuō)是沒(méi)有吸引力的。它也處于alpha階段,所以還沒(méi)有達(dá)到穩(wěn)定的狀態(tài)。

小結(jié), 適合已經(jīng)用了 CrossPlane 的用戶(hù), 但對(duì)于非Crossplane用戶(hù)來(lái)說(shuō)就沒(méi)啥吸引力了. 另外, 它還不穩(wěn)定.

Kubernetes Grafana Operator

Grafana Operator 是一個(gè) Kubernetes Operator,用于配置和管理Grafana及其使用Kubernetes CR 的資源。它是一個(gè)由Grafana社區(qū)建立的Kubernetes原生解決方案。它還可以把在Grafonnet中構(gòu)建的儀表盤(pán)作為儀表盤(pán)配置的來(lái)源。

請(qǐng)參考grafana-operator倉(cāng)庫(kù)中的文檔部分來(lái)開(kāi)始使用。

一個(gè)使用Grafana操作器創(chuàng)建儀表盤(pán)的Kubernetes配置樣本看起來(lái)是這樣的:

apiVersion: integreatly.org/v1alpha1
kind: GrafanaDashboard
metadata:
  name: simple-dashboard
  labels:
    app: grafana
spec:
  json: >
    {
      "title": "as-code dashboard",
      “uid” : “ascode”
    }

適用用戶(hù)

對(duì)于希望從Kubernetes內(nèi)管理Grafana資源的用戶(hù)來(lái)說(shuō),Grafana-operator非常好用,并作為Kubernetes清單用于GitOps管道。

已知的限制

這只適用于Grafana OSS,所以Grafana Cloud用戶(hù)將無(wú)法使用它。另外,Grafana-operator沒(méi)有Helm Chart,這對(duì)于擁有圍繞Helm構(gòu)建的管道的組織來(lái)說(shuō)可能是個(gè)問(wèn)題。

小結(jié), 筆者個(gè)人認(rèn)為, Kubernetes Grafana Operator 是非常適合這類(lèi)用戶(hù)的:

  • 自托管 Grafana OSS
  • Grafana OSS 部署在 Kubernetes 集群內(nèi)

并且其還有這些優(yōu)勢(shì):

  • 支持 Grafana OSS 各種細(xì)節(jié)配置
  • Grafana Dashboard 可以來(lái)自 Grafana com 的 id(其他工具好像都沒(méi)有)
  • 支持安裝 Grafana Plugin(其他工具好像都沒(méi)有)
  • 完美契合 GitOps

相應(yīng)地, 也有一些劣勢(shì):

  • 社區(qū)開(kāi)發(fā)的, 缺少 Grafana 官方支持
  • 不支持 Grafana Cloud/AWS Managed Grafana 等云服務(wù).

Tanka

為你的Kubernetes集群提供干凈、簡(jiǎn)潔和超級(jí)靈活的YAML替代品

  • ?? 簡(jiǎn)潔:Jsonnet語(yǔ)言比YAML更明顯地表達(dá)了你的應(yīng)用程序。
  • ?? 復(fù)用:構(gòu)建庫(kù),隨時(shí)導(dǎo)入它們,甚至在GitHub上分享它們
  • ?? 簡(jiǎn)潔:使用Kubernetes庫(kù)和抽象,你將永遠(yuǎn)不會(huì)再看到模板!
  • ?? 信心:停止猜測(cè),使用tk diff來(lái)看看到底會(huì)發(fā)生什么
  • ?? Helm:可重現(xiàn)的Helm Chart 中的 vendor、修改和導(dǎo)出。
  • ?? 生產(chǎn)就緒:Tanka部署了Grafana Cloud和更多的生產(chǎn)設(shè)置

一個(gè)使用 tanka 創(chuàng)建 Prometheus + Grafana K8s 資源的配置樣本看起來(lái)是這樣的:

local k = import "github.com/grafana/jsonnet-libs/ksonnet-util/kausal.libsonnet";

{
  _config:: {
    grafana: {
      port: 3000,
      name: "grafana",
    },
    prometheus: {
      port: 9090,
      name: "prometheus"
    }
  },

  local deployment = k.apps.v1.deployment,
  local container = k.core.v1.container,
  local port = k.core.v1.containerPort,
  local service = k.core.v1.service,

  prometheus: {
    deployment: deployment.new(
      name=$._config.prometheus.name, replicas=1,
      containers=[
        container.new($._config.prometheus.name, "prom/prometheus")
        + container.withPorts([port.new("api", $._config.prometheus.port)]),
      ],
    ),
    service: k.util.serviceFor(self.deployment),
  },
  grafana: {
    deployment: deployment.new(
      name=$._config.grafana.name, replicas=1,
      containers=[
        container.new($._config.grafana.name, "grafana/grafana")
        + container.withPorts([port.new("ui", $._config.grafana.port)]),
      ],
    ),
    service:
      k.util.serviceFor(self.deployment)
      + service.mixin.spec.withType("NodePort"),
  },
}

適用用戶(hù)

嚴(yán)格來(lái)說(shuō), Tanka 不應(yīng)該出現(xiàn)在這里. Tanka 本質(zhì)上是一個(gè) Kubernetes 基礎(chǔ)設(shè)施管理工具. 對(duì)標(biāo)的競(jìng)品是:

  • Kustomize
  • Helm
  • Kubernetes Operator

甚至是:

  • Terraform
  • Ansible

如果你是 Jsonnet 配置語(yǔ)言的狂熱粉絲, 并且想要通過(guò) Jsonnet 管理 Kubernetes 基礎(chǔ)設(shè)施和可觀察性的 Grafana Dashboard、Prometheus rule 和 Alert rule。那么 tanka 是適合你的。

已知的限制

拋棄 Kubernetes YAML,完全采用 jsonnet 管理資源,你需要另外掌握以下知識(shí):

  • Jsonnet
  • Tanka 使用
  • Kubernetes 資源的相關(guān) Jsonnet Library
  • Grafana 相關(guān)的 Jsonnet Library

小結(jié),不建議使用 tanka, 除非你是 Jsonnet 配置語(yǔ)言的狂熱粉絲和專(zhuān)家。

基于 API 的定制化開(kāi)發(fā)

Grafana 的 API,我也仔細(xì)找了一圈,官方有這么幾種 API:

  • Grafana API: 最底層的 API 接口。
  • grafana-api-golang-client: 基于 Grafana API 的低級(jí)別的 golang 客戶(hù)端. 也是 Grafana Terraform provider 的底層實(shí)現(xiàn)

如果使用 Grafana API, 創(chuàng)建 Dashboard 的示例如下:

POST /api/dashboards/db HTTP/1.1
Accept: application/json
Content-Type: application/json
Authorization: Bearer eyJrIjoiT0tTcG1pUlY2RnVKZTFVaDFsNFZXdE9ZWmNrMkZYbk

{
  "dashboard": {
    "id": null,
    "uid": null,
    "title": "Production Overview",
    "tags": [ "templated" ],
    "timezone": "browser",
    "schemaVersion": 16,
    "version": 0,
    "refresh": "25s"
  },
  "folderId": 0,
  "folderUid": "l3KqBxCMz",
  "message": "Made changes to xyz",
  "overwrite": false
}

如果使用 grafana-api-golang-client, 創(chuàng)建 Dashboard 的示例可以參考這個(gè)測(cè)試用例:

https://github.com/grafana/grafana-api-golang-client/blob/master/dashboard_test.go

適用用戶(hù)

首先, 基于 API 的定制化開(kāi)發(fā)都適用于開(kāi)發(fā)能力強(qiáng)、有更多自定義需求、上述 GaC 方案都不滿(mǎn)足需求、需要和公司企業(yè)內(nèi)部的自動(dòng)化工具整合的情況.

其次, Grafana 提供了基于 golang 的 grafana-api-golang-client, 如果您的技術(shù)棧是 golang, 建議直接使用 grafana-api-golang-client.

如果您的技術(shù)棧不是 golang, 則建議基于 Grafana API 開(kāi)發(fā).

已知限制

無(wú)

唯一的限制就是您/貴團(tuán)隊(duì)/貴司的技術(shù)能力和資源投入.

總結(jié)

這里有一個(gè)方便的對(duì)比表格,對(duì)比了上面提到的所有屬性和工具。

屬性/工具 Grafana Terraform Provider Grafana Ansible Collection Grizzly Tanka Grafana CrossPlane Provider Grafana Operator Grafana API
支持的Grafana資源 所有資源 Grafana Cloud Stack, plugins, API keys, dashboards, data sources, folders Synthetic Monitoring checks, dashboards, data sources, folders, Prometheus rules Unknown 所有主要資源 Folders, data sources, dashboards, notification channels, Grafana plugin, Grafana oss deploy 所有資源
格式化工具 HCL/JSON/Jsonnet YAML Jsonnet/YAML/JSON Jsonnet YAML/JSON YAML 取決于你
Kubernetes風(fēng)格清單 ?? ?? ?? 取決于你
在K8s中管理定義資源 ?? ?? ?? 取決于你
簡(jiǎn)單的Dashboard構(gòu)建流程 ?? 取決于你
獲取Grafana資源信息 ?? ?? Unknown 取決于你
內(nèi)置資源同步流程 ?? Unknown ?? ?? 取決于你
適用用戶(hù) 已在用Terraform的用戶(hù) 已在用Ansible的用戶(hù) 期望Kubernetes風(fēng)格清單管理Grafana, 內(nèi)置工作流和同步流程的用戶(hù) 部署在K8s上且是Jsonnet粉絲/專(zhuān)家的用戶(hù) 已在用CrossPlane, 或期望用K8s資源管理Grafana的用戶(hù) 全部使用Grafana OSS, 并且部署在K8s中, 期望使用K8s資源管理的用戶(hù). 現(xiàn)有方案都不滿(mǎn)足, 定制需求較多, 需要和內(nèi)部工具集成的用戶(hù)

這里定義的大多數(shù)工具可以相互結(jié)合使用,使用戶(hù)實(shí)現(xiàn) 1 + 1 > 2 的效果.

我的最終選擇是:

  • Grafana Terraform provider
  • Jsonnet

我的 Grafana 主要是以下幾類(lèi):

  • AWS Managed Grafana
  • Grafana OSS
  • Grafana Cloud Free

我需要用到的 Grafana 功能有:

  • Grafana 用戶(hù)
  • Grafana Team
  • Grafana 組織
  • Grafana DataSource
  • Grafana DataSource Permission
  • Grafana Folder
  • Grafana Folder Permission
  • Grafana Dashboard
  • Grafana Dashboard Permission
  • Grafana Alerting

欲了解更多信息或開(kāi)始使用 Grafana ,請(qǐng)查看每個(gè)工具的代碼庫(kù)或和我交流, 敬請(qǐng)期待我的后續(xù)文章。??????

???參考文檔

三人行, 必有我?guī)? 知識(shí)共享, 天下為公. 本文由東風(fēng)微鳴技術(shù)博客 EWhisper.cn 編寫(xiě).

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容