系列文章

概述

GaC(Grafana as Code, Grafana 即代码) 很明显是扩展自 IaC(Infrastructure as Code, 基础设施即代码)的概念.

Terraform 系列 - 什么是 IaC?一文中, 我们已经详细地说明了相关的概念, 我们可以直接套用在 GaC 上:

Grafana 即代码 (Grafana as Code, GaC) 是指通过 代码 而不是手动流程 / 控制台点击来管理和配置 Grafana。

这里有 2 个关键词:

  • Grafana
  • Code

Grafana 是被管理对象,在这里,不仅仅是指 Grafana OSS 这一款产品, 还包括 Grafana Labs 提供的商业产品和云服务. 包括不限于:

  • Grafana Alerting
  • Grafna Cloud Stack, 包括 Grafana Cloud 的:
    • 认证
    • 权限
    • 策略
    • Service Account
    • 组织
    • ...
  • Grafana Enterprise (企业版)
  • Grafana OnCall: 事件响应和管理平台(IRM)
  • Grafana SLO: SLA 和 可用性管理
  • Grafana Synthetic Monitoring: 拨测, 类似 BlackBoxProbe

Code 是管理方式,即像管理代码一样管理 Grafana 资源。那么管理代码最重要的部分: 版本管理是绕不开的。

...

当然, 这一系列文章, 主要还是关注于通过代码的形式来管理 Grafana 这个产品.

这篇文章主要跟着Grafana as code: A complete guide to tools, tips, and tricks 这篇官方文章的逻辑来进行, 变穿插笔者的评价和最终选择.

GaC 的几种官方方案

官方推荐这么几种方案, 另外我也会加几个我认为可行的方案:

是不是有点琳琅满目, 是不是有点挑花眼了?

我刚开始也是这样, 不用担心, 我们一一过一下. 很快 GaC 的脉络就会清晰起来.

Notes:

这里面 Crossplane 大家可能没怎么听过, 刚好我 2021 年有一篇介绍其的文章, 感兴趣的可以作为扩展阅读.

Jsonnet

根据 Grafana 的一些官方演讲视频和代码库以及博客文章, Grafana 是重度依赖 Jsonnet 这一配置语言的. 后面我们会详细介绍其历史及使用方法.

无论我们使用哪一种 GaC 方案, 基于 Jsonnet 的 Dashboard as Code 都是必选的.

  • 在 Terraform 中, 可以通过Jsonnet Provider 和 Grafana 配合使用
  • 在 Ansible 中, 可以在 task 之前加入对 jsonnet 相关依赖的安装, 以及 jsonnet 生成 Dashboard 的前置 tasks
  • 在 Grizzly 和 Tanka 中, jsonnet 就是一级公民. 如 Grizzly 可以直接使用 Jsonnet
  • ...

小结, Jsonnet 是目前几乎唯一的深度 Dashboard as Code 方案, 必选.

Notes:

如果是浅显地应用 GaC, 那么 Dashboard 直接通过 Dashboard json 文件作为代码管理也可以.

但是进入使用深水区, 在 Dashboard 多起来, 且有大量重复的配置的情况下, Jsoonet 是唯一选择.

Grafana Terraform provider

Grafana 管理员可以使用Grafana的Terraform Provider 管理 dashboards 和 alerts,添加 synthetic monitoring probes 和检查,管理身份和访问,等等。

用于创建仪表盘的Terraform配置示例如下:

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

适用用户

Grafana Terraform Provider 更适合那些已经在非Grafana使用案例中使用Terraform的用户。

对于目前希望在Grafana Cloud 或Grafana的OSS部署上管理整个Grafana生态系统资源的用户,最好使用Grafana Terraform Provider,因为与Grafana的其他作为代码的解决方案相比,它还支持最多的Grafana资源

笔者的最终选择, 就是:

  • Grafana Terraform Provider + Jsonnet

其中很大的一个原因就是上面提到的: 支持最多的Grafana资源.

笔者计划在 Aws Managed Grafana 中使用 Grafana, Aws Managed Grafana 相比 Grafana OSS, 功能还是有一点点的细微差别:

  • AWS Managed Grafana 有 DataSource 的 Permission 管理功能, 而 Grafana OSS 并没有这项功能.

但是 Grafana Terraform Provider 是提供这一功能的, 该功能位于 Grafana Enterprise 下面. 但确实可用.

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

  • Grafana 用户
  • Grafana Team
  • Grafana 组织
  • Grafana DataSource
  • Grafana DataSource Permission
  • Grafana Folder
  • Grafana Folder Permission
  • Grafana Dashboard
  • Grafana Dashboard Permission
  • Grafana Alerting

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

已知的限制

管理仪表盘并不是一个最简单的过程--用户必须处理长长的JSON,这也会变得难以审查和更新。Grafonnet可以帮助生成可用于Terraform的仪表盘JSON,但Grafonnet需要了解Jsonnet,所以这对一些用户来说是不可取的。

不管哪种方案, Jsonnet 其实是对所有进入 GaC 深水区的用户都必须掌握的, 逃不掉的.

Grafana Ansible collection

配置管理的资源可以通过Ansible Collection for Grafana提供。它可以用来管理各种资源,包括 folders、cloudstack和dashboards。用户可以通过编写使用HTTP API管理Grafana资源的Ansible playbooks,以编程方式管理Grafana上目前还不属于Grafana Ansible集合的资源。

创建仪表盘的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

适用用户

和Terraform一样,Grafana Ansible Collection 更适合已经将Ansible用于非Grafana用例的人。此外,该 Collection 目前只适用于Grafana Cloud,所以它对那些希望使用Ansible声明式管理资源的Grafana Cloud客户最有意义。

已知的限制

截至目前,Grafana Ansible Collection 只适用于Grafana Cloud,并且只支持8种资源

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

对于希望用Ansible以代码形式管理整个Grafana生态系统的用户来说,这可能是一个缺点。与Terraform一样,仪表盘的构建也不是最简单的过程。

小结, Grafana Ansible Collection 最大的缺点在于: 只适用于Grafana Cloud,并且只支持8种资源.

Grizzly

Grizzly 是一个命令行工具,允许你用代码管理你的可观察性资源。Grizzly支持Kubernetes启发的YAML表示的Grafana资源,这使得它更容易熟悉。Grizzly支持在Grafana实例内移动仪表盘,也可以检索已经配置的Grafana资源的信息。Grizzly目前支持:

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

Grizzly也可以使用 Grafonnet 部署在Jsonnet中构建的仪表盘。(在Grafonnet文档中了解更多信息)。

用于创建仪表盘的Kubernetes风格的Grizzly配置样本看起来是这样的:

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

适用用户

Grizzly最适合使用Jsonnet来管理Grafana资源的用户,或者喜欢用Kubernetes风格的YAML定义他们的Grafana资源。

已知的限制

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

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

小结, Grizzly最适合使用Jsonnet来管理Grafana资源的用户. 但是支持的 Grafana 资源也不够全.

Grafana Crossplane provider

Grafana Crossplane Provider 使用Terrajet构建,为Grafana Terraform Provider 支持的所有资源提供支持。它使用户能够将Grafana资源定义为Kubernetes清单,也会帮助那些使用ArgoCD等工具围绕Kubernetes清单建立GitOps管道的用户。

要开始使用Grafana Crossplane Provider,请在Kubernetes集群中安装Crossplane,并使用此命令安装 provider:

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

在安装 provider 的过程中,Terraform provider 支持的所有资源的CRD被添加到集群中,因此用户可以开始将他们的Grafana资源定义为Kubernetes自定义资源。Crossplane provider 确保在 CRD 中所定义的内容在Grafana用户界面中是可见的。如果在用户界面中直接进行了任何更改,那么当提供者重新同步时,这些更改将被丢弃。这有助于确保集群中的任何声明性定义都将是Grafana资源的真实来源。

要开始使用,请参考Grafana Crossplane资源库中的示例文件夹

用于创建 Dashboard 的Kubernetes CRD 样本看起来像这样:

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

适用用户

Grafana Crossplane provider 适合现有的Crossplane用户,他们希望从Kubernetes内管理Grafana资源,并作为Kubernetes清单用于GitOps管道。

已知限制

Crossplane provider 依赖于在Kubernetes集群中安装了Crossplane CLI和Crossplane。这种依赖性对于非Crossplane用户来说是没有吸引力的。它也处于alpha阶段,所以还没有达到稳定的状态。

小结, 适合已经用了 CrossPlane 的用户, 但对于非Crossplane用户来说就没啥吸引力了. 另外, 它还不稳定.

Kubernetes Grafana Operator

Grafana Operator 是一个 Kubernetes Operator,用于配置和管理Grafana及其使用Kubernetes CR 的资源。它是一个由Grafana社区建立的Kubernetes原生解决方案。它还可以把在Grafonnet中构建的仪表盘作为仪表盘配置的来源。

请参考grafana-operator仓库中的文档部分来开始使用。

一个使用Grafana操作器创建仪表盘的Kubernetes配置样本看起来是这样的:

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

适用用户

对于希望从Kubernetes内管理Grafana资源的用户来说,Grafana-operator非常好用,并作为Kubernetes清单用于GitOps管道。

已知的限制

这只适用于Grafana OSS,所以Grafana Cloud用户将无法使用它。另外,Grafana-operator没有Helm Chart,这对于拥有围绕Helm构建的管道的组织来说可能是个问题。

小结, 笔者个人认为, Kubernetes Grafana Operator 是非常适合这类用户的:

  • 自托管 Grafana OSS
  • Grafana OSS 部署在 Kubernetes 集群内

并且其还有这些优势:

  • 支持 Grafana OSS 各种细节配置
  • Grafana Dashboard 可以来自 Grafana com 的 id(其他工具好像都没有)
  • 支持安装 Grafana Plugin(其他工具好像都没有)
  • 完美契合 GitOps

相应地, 也有一些劣势:

  • 社区开发的, 缺少 Grafana 官方支持
  • 不支持 Grafana Cloud/AWS Managed Grafana 等云服务.

Tanka

为你的Kubernetes集群提供干净、简洁和超级灵活的YAML替代品

  • 简洁:Jsonnet语言比YAML更明显地表达了你的应用程序。
  • 复用:构建库,随时导入它们,甚至在GitHub上分享它们
  • 简洁:使用Kubernetes库和抽象,你将永远不会再看到模板!
  • 信心:停止猜测,使用tk diff来看看到底会发生什么
  • Helm:可重现的Helm Chart 中的 vendor、修改和导出。
  • 生产就绪:Tanka部署了Grafana Cloud和更多的生产设置

一个使用 tanka 创建 Prometheus + Grafana K8s 资源的配置样本看起来是这样的:

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"),
},
}

适用用户

严格来说, Tanka 不应该出现在这里. Tanka 本质上是一个 Kubernetes 基础设施管理工具. 对标的竞品是:

  • Kustomize
  • Helm
  • Kubernetes Operator

甚至是:

  • Terraform
  • Ansible

如果你是 Jsonnet 配置语言的狂热粉丝, 并且想要通过 Jsonnet 管理 Kubernetes 基础设施和可观察性的 Grafana Dashboard、Prometheus rule 和 Alert rule。那么 tanka 是适合你的。

已知的限制

抛弃 Kubernetes YAML,完全采用 jsonnet 管理资源,你需要另外掌握以下知识:

  • Jsonnet
  • Tanka 使用
  • Kubernetes 资源的相关 Jsonnet Library
  • Grafana 相关的 Jsonnet Library

小结,不建议使用 tanka, 除非你是 Jsonnet 配置语言的狂热粉丝和专家。

基于 API 的定制化开发

Grafana 的 API,我也仔细找了一圈,官方有这么几种 API:

如果使用 Grafana API, 创建 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, 创建 Dashboard 的示例可以参考这个测试用例:

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

适用用户

首先, 基于 API 的定制化开发都适用于开发能力强、有更多自定义需求、上述 GaC 方案都不满足需求、需要和公司企业内部的自动化工具整合的情况.

其次, Grafana 提供了基于 golang 的 grafana-api-golang-client, 如果您的技术栈是 golang, 建议直接使用 grafana-api-golang-client.

如果您的技术栈不是 golang, 则建议基于 Grafana API 开发.

已知限制

唯一的限制就是您/贵团队/贵司的技术能力和资源投入.

总结

这里有一个方便的对比表格,对比了上面提到的所有属性和工具。

属性/工具 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风格清单 取决于你
在K8s中管理定义资源 取决于你
简单的Dashboard构建流程 取决于你
获取Grafana资源信息 Unknown 取决于你
内置资源同步流程 Unknown 取决于你
适用用户 已在用Terraform的用户 已在用Ansible的用户 期望Kubernetes风格清单管理Grafana, 内置工作流和同步流程的用户 部署在K8s上且是Jsonnet粉丝/专家的用户 已在用CrossPlane, 或期望用K8s资源管理Grafana的用户 全部使用Grafana OSS, 并且部署在K8s中, 期望使用K8s资源管理的用户. 现有方案都不满足, 定制需求较多, 需要和内部工具集成的用户

这里定义的大多数工具可以相互结合使用,使用户实现 1 + 1 > 2 的效果.

我的最终选择是:

  • Grafana Terraform provider
  • Jsonnet

我的 Grafana 主要是以下几类:

  • AWS Managed Grafana
  • Grafana OSS
  • Grafana Cloud Free

我需要用到的 Grafana 功能有:

  • Grafana 用户
  • Grafana Team
  • Grafana 组织
  • Grafana DataSource
  • Grafana DataSource Permission
  • Grafana Folder
  • Grafana Folder Permission
  • Grafana Dashboard
  • Grafana Dashboard Permission
  • Grafana Alerting

欲了解更多信息或开始使用 Grafana ,请查看每个工具的代码库或和我交流, 敬请期待我的后续文章。

️参考文档

三人行, 必有我师; 知识共享, 天下为公. 本文由东风微鸣技术博客 EWhisper.cn 编写.

Grafana系列-GaC-1-Grafana即代码的几种实现方式的更多相关文章

  1. SQL Server调优系列基础篇(常用运算符总结——三种物理连接方式剖析)

    前言 上一篇我们介绍了如何查看查询计划,本篇将介绍在我们查看的查询计划时的分析技巧,以及几种我们常用的运算符优化技巧,同样侧重基础知识的掌握. 通过本篇可以了解我们平常所写的T-SQL语句,在SQL ...

  2. STM32 HAL库学习系列第3篇 常使用的几种延时方式

    1   自带的hal_delay 函数    毫秒级延迟 void HAL_Delay(__IO uint32_t Delay) { uint32_t tickstart = HAL_GetTick( ...

  3. 前端测试框架Jest系列教程 -- Asynchronous(测试异步代码)

    写在前面: 在JavaScript代码中,异步运行是很常见的.当你有异步运行的代码时,Jest需要知道它测试的代码何时完成,然后才能继续进行另一个测试.Jest提供了几种方法来处理这个问题. 测试异步 ...

  4. java代码中init method和destroy method的三种使用方式

    在java的实际开发过程中,我们可能常常需要使用到init method和destroy method,比如初始化一个对象(bean)后立即初始化(加载)一些数据,在销毁一个对象之前进行垃圾回收等等. ...

  5. Grafana 系列文章(一):基于 Grafana 的全栈可观察性 Demo

    ️Reference: https://github.com/grafana/intro-to-mlt 这是关于 Grafana 中可观察性的三个支柱的一系列演讲的配套资源库. 它以一个自我封闭的 D ...

  6. Grafana 系列文章(二):使用 Grafana Agent 和 Grafana Tempo 进行 Tracing

    ️URL: https://grafana.com/blog/2020/11/17/tracing-with-the-grafana-cloud-agent-and-grafana-tempo/ ✍A ...

  7. Grafana 系列文章(九):开源云原生日志解决方案 Loki 简介

    简介 Grafana Labs 简介 Grafana 是用于时序数据的事实上的仪表盘解决方案.它支持近百个数据源. Grafana Labs 想从一个仪表盘解决方案转变成一个可观察性 (observa ...

  8. Grafana 系列文章(十一):Loki 中的标签如何使日志查询更快更方便

    ️URL: https://grafana.com/blog/2020/04/21/how-labels-in-loki-can-make-log-queries-faster-and-easier/ ...

  9. ldap配置系列三:grafana集成ldap

    ldap配置系列三:grafana集成ldap grafana的简介 grafana是一个类似kibana的东西,是对来自各种数据源的数据进行实时展示的平台,拥有这牛逼的外观.给一个官方的demo体验 ...

  10. Grafana 系列文章(三):Tempo-使用 HTTP 推送 Spans

    ️URL: https://grafana.com/docs/tempo/latest/api_docs/pushing-spans-with-http/ Description: 有时,使用追踪系统 ...

随机推荐

  1. odoo 开发入门教程系列-计算的字段和变更(Computed Fields And Onchanges)

    计算的字段和变更(Computed Fields And Onchanges) 模型之间的关系是任何Odoo模块的关键组成部分.它们对于任何业务案例的建模都是必要的.然而,我们可能需要给定模型中字段之 ...

  2. Nginx主要功能

    Nginx主要功能: 1.反向代理2.负载均衡3.HTTP服务器(包含动静分离)4.正向代理 一.反向代理 反向代理应该是 Nginx 做的最多的一件事了,什么是反向代理呢,以下是百度百科的说法:反向 ...

  3. python之re详解

    import re# .匹配任何一个字符,除了换行#[]匹配里面任意一个字符# \d匹配一个数字0-9# \D匹配不是一个数字# \s 匹配一个空格和tab# \S 匹配非空格和tab一个字符# \w ...

  4. Semantic Kernel 入门系列:🥑Memory内存

    了解的运作原理之后,就可以开始使用Semantic Kernel来制作应用了. Semantic Kernel将embedding的功能封装到了Memory中,用来存储上下文信息,就好像电脑的内存一样 ...

  5. Java SpringBoot 中,动态执行 bean 对象中的方法

    根据不同的条件,调用不同的 bean 对象,执行对象中的方法 SpringUtils 工具类 package com.vipsoft.web.utils; import cn.hutool.core. ...

  6. Sql批量替换字段字符,Sql批量替换多字段字符,Sql替换字符

    update phome_ecms_news_check set filename= replace(filename,'Under4-',''); update phome_ecms_news_ch ...

  7. CSS笔记(待完善)

    CSS笔记 css权重 ID(100)> class(10)> element(1) css最高权重 !important 块元素(block) 可以设置宽度和高度,独立成行. h1~h6 ...

  8. 开心档之MySQL ALTER命令

    MySQL ALTER命令 当我们需要修改数据表名或者修改数据表字段时,就需要使用到MySQL ALTER命令. 开始本章教程前让我们先创建一张表,表名为:testalter_tbl. root@ho ...

  9. SpringCloud导入spring boot项目当作子模块微服务IDEA不识别子module问题

    1.在父工程下面引入module. <modules> <module>study-design-mode</module> </modules> 2. ...

  10. Claude:除ChatGPT外的另一种选择

    前言 Claude 是 Anthropic 开发的人工智能产品.Anthropic 是由 11 名前 OpenAI 员工于 2022 年创立的人工智能公司,旨在构建安全.可解释和有益于人类的人工智能系 ...