系列文章
概述
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)為可行的方案:
- 基于 Terraform 的 Grafana Terraform provider
- 基于 Ansible 的 Grafana Ansible collection
- Grizzly: Grafana 官方開(kāi)源的一個(gè)部署和配置Grafana 一體化 cli 工具.
- Tanka: Grafana 官方開(kāi)源的一個(gè)基于 jsonnet 的 Kubernetes 集群管理工具
- 基于 Crossplane 的Grafana Crossplane provider
- 基于 Kubernetes CRD 的 Kubernetes Grafana Operator
- 基于 API 的定制化開(kāi)發(fā):
- 基于 Jsonnet 的 Dashboard as Code
- grafana/jsonnet-libs: Grafana Labs' Jsonnet libraries (github.com)
- grafana/grafonnet: Jsonnet library for generating Grafana dashboards. (github.com)
- grafana/grafonnet-lib: Jsonnet library for generating Grafana dashboard files. (github.com) (??已棄用, 但是仍有很多 Dashboard 資源依賴(lài)它)
- Prometheus Monitoring Mixins | Monitoring Mixins
- kubernetes-monitoring/kubernetes-mixin: A set of Grafana dashboards and Prometheus alerts for Kubernetes. (github.com)
是不是有點(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ě).