news 2026/9/6 22:09:53

Istio Grafana 官方仪表盘:Jsonnet 生成流程与 UID 链接规范的工程实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Istio Grafana 官方仪表盘:Jsonnet 生成流程与 UID 链接规范的工程实践

Istio Grafana 官方仪表盘:Jsonnet 生成流程与 UID 链接规范的工程实践

【免费下载链接】istioConnect, secure, control, and observe services.项目地址: https://gitcode.com/GitHub_Trending/is/istio

本文围绕 Istio 仓库中 manifests/addons/dashboards 目录的官方开发指南展开,讲解 Istio 官方 Grafana 仪表盘“Jsonnet 生成 + JSON 手工导出”双轨维护模式、基于 MD5 哈希的 UID 链接规范,以及如何通过gen.sh一键生成并校验全部仪表盘产物。读完后,你可以独立理解 Istio 监控面板的代码化生成流程、新增一个 Jsonnet 仪表盘、并保证跨 Grafana 版本链接稳定。

1. 仪表盘目录的定位与发布链路

manifests/addons/dashboards目录存放 Istio 的官方 Grafana 仪表盘。该目录承担两个角色:

  1. 发布源:在版本发布期间,这些仪表盘会被发布到 Grafana 官方仪表盘库(Istio 组织名下);
  2. 样例捆绑:仪表盘 JSON 会被打进 Istio 的 Grafana 样例部署 samples/addons/grafana.yaml,供用户在本地演示环境(demo profile 等)直接kubectl apply使用。

目录中的产物分为两类,这一“双轨制”是整个开发工作流的基础:

类型文件特征维护方式
新生成的仪表盘*.libsonnet(源码)+*.gen.json(生成物)用 Jsonnet 代码化生成,是新增仪表盘的首选方式
遗留仪表盘*.json直接在 Grafana UI 中手工编辑后导出、提交入库

当前仓库中 Jsonnet 化的仪表盘有三个源码文件,对应三个控制面/环境组件:

  • pilot.libsonnet →pilot-dashboard.gen.json(Istio 控制面 Pilot 仪表盘)
  • ztunnel.libsonnet →ztunnel-dashboard.gen.json(Ambient 模式 ztunnel 节点代理仪表盘)
  • istio-mesh.libsonnet →istio-mesh-dashboard.gen.json(网格整体仪表盘)

遗留的手工 JSON 仪表盘则包括istio-performance-dashboard.jsonistio-workload-dashboard.jsonistio-service-dashboard.jsonistio-extension-dashboard.json

2. Jsonnet + Grafonnet:仪表盘代码化工作流

README 明确指出:较新的仪表盘使用 [Jsonnet] 配合 Grafonnet 库生成,并且“任何新仪表盘都应优先采用这种方式”。

2.1 依赖声明:jsonnetfile.json

jsonnetfile.json 声明了唯一的第三方依赖——Grafonnet:

{ "version": 1, "dependencies": [ { "source": { "git": { "remote": "https://github.com/grafana/grafonnet.git", "subdir": "gen/grafonnet-latest" } }, "version": "main" } ], "legacyImports": true }

要点:

  • 依赖锁定在gen/grafonnet-latest子目录,版本取main分支;
  • 配套存在jsonnetfile.lock.json用于锁定解析结果;
  • "legacyImports": true允许不带包前缀的裸导入(如import 'g.libsonnet');
  • 运行期通过jb install将依赖拉取到本地vendor/目录,jsonnet -J vendor -J lib即可编译。

2.2 Grafonnet 的入口封装:g.libsonnet

lib/g.libsonnet 只有一行,它把 Grafonnet 的最新主库暴露为本地符号g

import 'github.com/grafana/grafonnet/gen/grafonnet-latest/main.libsonnet'

所有.libsonnet源文件的第一行都是local g = import 'g.libsonnet';,之后统一使用g.dashboard.*g.panel.*等 Grafonnet API 构建仪表盘对象。

2.3 公共库(lib/):仪表盘骨架、网格、面板与查询

lib/目录把可复用的构件拆分为独立模块,这是 Jsonnet 方式优于手工 JSON 的核心原因——面板布局、时间范围、数据源变量都不必在每个仪表盘里重复:

  • lib/dashboard.libsonnet:仪表盘骨架工厂,统一注入默认行为——

    { new(name): g.dashboard.new(name) + g.dashboard.graphTooltip.withSharedCrosshair() + g.dashboard.withRefresh('15s') + g.dashboard.time.withFrom('now-30m') + g.dashboard.time.withTo('now') + g.dashboard.withVariables([variables.datasource]), }

    即每个新仪表盘自动获得 15 秒自动刷新、默认时间窗now-30m ~ now、共享十字光标提示以及数据源变量。

  • lib/lib-grid.libsonnet:面板网格布局工具(grid.makeGrid([...], panelHeight=..., startY=...));

  • lib/panels.libsonnet:面板工厂(timeSeriesheatmap等,区分 bytes 格式化、速率格式化等变体);

  • lib/queries.libsonnet:Prometheus 查询构造器,按container/pod/component/app标签参数化生成一组查询;

  • lib/variables.libsonnet:仪表盘变量(如 datasource 变量)。

2.4 一个真实的仪表盘源码:pilot.libsonnet

pilot.libsonnet 展示了完整组装过程:先通过queries模块按 pilot 的标签(pod: 'istiod-.*'app: 'istiod')取回查询集合,再用grid.makeGrid按行(row)拼装面板,最后一行为整个仪表盘写入 UID:

dashboard.new('Istio Control Plane Dashboard') + g.dashboard.withPanels( grid.makeGrid([ row.new('Deployed Versions') + row.withPanels([ panels.timeSeries.simple('Pilot Versions', queries.istioBuild, 'Version number of each running instance'), ]), ], panelHeight=5) + grid.makeGrid([ row.new('Resource Usage') + row.withPanels([ panels.timeSeries.bytes('Memory Usage', queries.goMemoryUsage, 'Memory usage of each running instance'), panels.timeSeries.allocations('Memory Allocations', queries.goAllocations, 'Details about memory allocations'), panels.timeSeries.base('CPU Usage', queries.cpuUsage, 'CPU usage of each running instance'), panels.timeSeries.base('Goroutines', queries.goroutines, 'Goroutine count for each running instance'), ]), ], panelHeight=10, startY=1) + ... // Push Information、Webhooks 等行 ) + g.dashboard.withUid(std.md5('pilot-dashboard.json'))

从源码结构看,pilot 仪表盘覆盖四大分区:Deployed Versions(各运行实例版本)、Resource Usage(内存/分配/CPU/goroutine)、Push Information(xDS 推送速率、事件、连接数、推送错误、推送时延/体积热力图)、Webhooks(验证与注入速率)。ztunnel.libsonnet 遵循完全相同的组装模式,只是查询标签换成pod: "ztunnel-.*"app: "ztunnel",并按 Process / Network / Operations 三行组织面板。

3. 仪表盘链接规范:强制 UID 链接

这是 README 中约束最严格的一节:所有仪表盘必须使用 UID 链接,禁止路径(path-based)链接。原因有三:

  1. 路径链接在新版 Grafana 中已被废弃;
  2. UID 链接在 Grafana 版本升级间更稳定;
  3. UID 链接在自建 Grafana 与 Grafana Cloud 上都能正常工作。

3.1 用文件名 MD5 作为 UID

Istio 的约定是:仪表盘的 UID 取其仪表盘文件名(JSON 文件名)的 MD5 哈希,例如:

g.dashboard.withUid(std.md5('istio-mesh.json'))

仓库中现有三处实例验证了该约定:

源文件UID 表达式
pilot.libsonnet#L86g.dashboard.withUid(std.md5('pilot-dashboard.json'))
ztunnel.libsonnet#L56g.dashboard.withUid(std.md5('ztunnel.json'))
istio-mesh.libsonnet#L60g.dashboard.withUid(std.md5('istio-mesh.json'))

注意一个细节:pilot 与 ztunnel 的 MD5 输入文件名与生成产物名不一致(产物是pilot-dashboard.gen.jsonztunnel-dashboard.gen.json,而哈希输入分别是pilot-dashboard.jsonztunnel.json)。这并非笔误,而是刻意为之的兼容性选择——保证 UID 与历史版本仪表盘在 Grafana 库/集群中已有记录保持一致,避免升级后旧书签失效。

3.2 跨仪表盘链接的两个 helper 库

仪表盘之间互相跳转时,统一使用两个 helper 库,而不是各自硬编码 UID:

  • lib/istio-service.libsonnet:指向 Service 仪表盘;
  • lib/istio-workload.libsonnet:指向 Workload 仪表盘。

两者结构对称,以 Service 为例:

{ // Service 仪表盘的 UID(MD5 of istio-service-dashboard.json) uid:: std.md5('istio-service-dashboard.json'), // 数据链接:面板内数据点跳到 Service 仪表盘并带上当前变量 dataLink(title='View Service'):: g.panel.link.new(title) + g.panel.link.withUrl('/d/' + $.uid + '?${vars}') + g.panel.link.withTargetBlank(true), // 顶部导航链接:跳转到 Service 仪表盘 dashboardLink:: g.dashboard.link.dashboards.new('Service Dashboard', [$.uid]) + g.dashboard.link.dashboards.options.withAsDropdown(false) + g.dashboard.link.dashboards.options.withIncludeVars(true) + g.dashboard.link.dashboards.options.withKeepTime(true) }

三类链接语义清晰:

  • uid:单一真源,所有地方引用这个 UID 而不重复写 MD5 字符串;
  • dataLink:面板数据链接,URL 形如/d/<uid>?${vars}——/d/前缀正是 Grafana 的 UID 路由,${vars}会把当前仪表盘的变量值透传给目标页,并在新标签页打开;
  • dashboardLink:仪表盘顶部导航链接,配置为非下拉(withAsDropdown(false))、携带变量(withIncludeVars(true))、保持时间区间(withKeepTime(true))。

README 给出的使用示例:

local serviceDashboard = import 'istio-service.libsonnet'; dashboard.new('My Dashboard') + g.dashboard.withLinks([ serviceDashboard.dashboardLink ])

即新仪表盘只要导入 helper 库并把dashboardLink挂进withLinks,就自动获得“跳转 Service 仪表盘”导航项,UID 一致性由 helper 库保证。

4. 生成流程:gen.sh 一键产出全部 addon 部署

README 的“Generation”一节指出:无论哪种类型的仪表盘,统一执行./manifests/addons/gen.sh生成全部所需产物。阅读 gen.sh 可以看到完整流水线:

./manifests/addons/gen.sh

脚本(set -eux严格模式)依次完成:

  1. Kiali / Prometheus / Loki:分别用helm template(固定 chart 版本:Kiali 2.31.0、Prometheus 28.13.0、LokiLOKI_VERSION默认 7.2.0)加 values-kiali.yaml、values-prometheus.yaml、values-loki.yaml 渲染出samples/addons/下对应的 YAML;

  2. Jsonnet 仪表盘生成:进入dashboards/目录执行jb install安装 Grafonnet 依赖,然后对每个*.libsonnet执行:

    for file in *.libsonnet; do dashboard="${file%.*}" jsonnet -J vendor -J lib "${file}" > "${dashboard}-dashboard.gen.json" done

    命名规则固定:pilot.libsonnetpilot-dashboard.gen.json,以此类推;-J vendor -J lib指定 import 搜索路径;

  3. Grafana 部署helm template grafanaGRAFANA_VERSION默认 9.2.2)叠加 values-grafana.yaml 渲染;

  4. ConfigMap 拆分与压缩:为避免 Kubernetes 单对象尺寸上限,compressDashboard函数先用jq -c把每个 JSON 压成单行,再分两个 ConfigMap 产出:

    • istio-grafana-dashboards:pilot、ztunnel、performance;
    • istio-services-grafana-dashboards:workload、service、mesh、extension;
  5. 自动校验:若存在test_dashboard_links.sh,脚本末尾自动执行(详见第 5 节)。

values-grafana.yaml 揭示了这些 ConfigMap 如何被 Grafana 消费:两个dashboardProvidersistioistio-services)把上述两个 ConfigMap 分别挂载到/var/lib/grafana/dashboards/istio.../istio-services,并都归入istio文件夹;同时定义了默认 Prometheus 数据源(http://prometheus:9090,15s 采样间隔)与 Loki 数据源(http://loki:3100,5s 采样间隔)。此外该样例做了面向演示的简化(匿名访问、admin/admin、关闭 RBAC),生产环境使用时应按需收紧。

5. 校验脚本:test_dashboard_links.sh 确保没有回退到路径链接

生成后,可用 test_dashboard_links.sh 验证所有仪表盘都采用 UID 链接:

./manifests/addons/dashboards/test_dashboard_links.sh

脚本逻辑对每个*.json/*.gen.json文件做两类 grep 检查:

  • 禁止项/dashboard/db/出现即判定为废弃的路径链接,打印前 5 处命中位置并令整个检查失败(set -eu+error_count计数,最终非零退出);
  • 期望项:存在/d/(UID 路由)或"dashboards"(仪表盘导航链接结构)即认为合格;两者都没有也不报错,仅输出INFO: No dashboard links found in <file>提示——即“无链接”合法,“错误格式”非法。

全部通过时输出:All dashboards use the proper UID-based linking format!。如前所述,gen.sh末尾会自动调用该脚本,因此在正常的生成流水线中该校验是内建的一步,不需要手动补跑;手动运行的场景是只改了 JSON 而跳过完整生成时做快速自检。

6. 实践小结:新增一个仪表盘的操作步骤

综合 README 与仓库现状,在 Istio 中新增一个 Jsonnet 仪表盘的标准做法:

  1. 在 manifests/addons/dashboards 下新建<name>.libsonnet,复用lib/dashboard.libsonnetdashboard.new('<名称>')骨架,配合lib/panels.libsonnetlib/queries.libsonnet组装面板;
  2. 结尾调用g.dashboard.withUid(std.md5('<目标JSON文件名>'))固定 UID(注意与既有产物/历史 UID 保持一致,避免破坏用户已有书签);
  3. 如需从其他面板跳转到 Service/Workload 仪表盘,导入istio-service.libsonnet/istio-workload.libsonnet使用其dataLink/dashboardLink
  4. 运行./manifests/addons/gen.sh,确认<name>-dashboard.gen.json生成、test_dashboard_links.sh通过;
  5. 如需把新仪表盘加入样例部署,还要在gen.shcompressDashboard清单与对应kubectl create configmap --from-file列表中登记(该脚本按文件名显式列举,不是通配收集——从源码结构看,漏登记会导致仪表盘不会出现在samples/addons/grafana.yaml中)。

这套“Jsonnet 源码为真源、MD5 文件名定 UID、helper 库统一跳转、生成脚本内建链接校验”的流水线,使 Istio 官方仪表盘在代码化可维护与跨 Grafana 版本/环境链接稳定性之间取得了平衡;而遗留的手工 JSON 仪表盘则保持原样继续随版本演进,两者通过同一个gen.sh入口统一产出。

【免费下载链接】istioConnect, secure, control, and observe services.项目地址: https://gitcode.com/GitHub_Trending/is/istio

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/6 22:06:09

WaveTerm 自定义小部件快速上手:三步把常用命令变成一键启动

WaveTerm 自定义小部件快速上手&#xff1a;三步把常用命令变成一键启动 【免费下载链接】waveterm An open-source, AI-integrated, cross-platform terminal for seamless workflows 项目地址: https://gitcode.com/GitHub_Trending/wa/waveterm 你有多久没嫌烦地重输…

作者头像 李华
网站建设 2026/9/6 22:04:09

40LL工艺跑出1.3GHz双核A9:从RTL到硅片的工程实践解析

简介&#xff1a;半导体产业前沿动态参考资料&#xff0c;聚焦中芯国际与灿芯半导体推出的40纳米低漏电双核ARM Cortex-A9测试芯片&#xff0c;主频达1.3GHz&#xff0c;是观察国产先进制程与芯片设计协同进展的实用文献。内容还涉及福建首条8英寸IC芯片生产线、两岸企业联手研…

作者头像 李华
网站建设 2026/9/6 22:03:31

升降压斩波电路仿真:MATLAB建模、参数计算与PID闭环调参

简介&#xff1a;升降压斩波电路的MATLAB仿真及分析PDF文档&#xff0c;面向电力电子技术课程学习者与MATLAB仿真入门者&#xff0c;系统梳理Buck-Boost反极性斩波电路的工作原理与仿真分析方法。文档基于50V输入电压、纹波小于0.02%、脉冲周期T1e-4s以及R450Ω、L1.1e-2H、C4.…

作者头像 李华
网站建设 2026/9/6 22:02:54

Wave Terminal:5 分钟上手的完整指南

Wave Terminal&#xff1a;5 分钟上手的完整指南 【免费下载链接】waveterm An open-source, AI-integrated, cross-platform terminal for seamless workflows 项目地址: https://gitcode.com/GitHub_Trending/wa/waveterm Wave Terminal 是一款开源跨平台终端&#xf…

作者头像 李华
网站建设 2026/9/6 22:01:46

OpenPGP邮件数字签名与加密:从密钥管理到实战配置

简介&#xff1a;这是一份关于数字签名与加密邮件发送的完整实验报告&#xff0c;以Windows系统自带的Outlook Express为客户端&#xff0c;面向信息安全课程学生、邮件系统管理员&#xff0c;以及希望为日常通信增加加密与签名能力的办公人员。报告清晰记录了从配置POP3/SMTP账…

作者头像 李华
网站建设 2026/9/6 21:57:16

机器学习辅助锂离子电池材料设计:从数据构建到性能预测的完整实践

简介&#xff1a;机器学习辅助的锂离子电池材料设计及性能预测体系构建专题文档&#xff0c;面向锂电材料研究人员、机器学习方向学生及新能源领域从业者。文档从锂离子电池工作原理与正负极材料、电解质、隔膜等基础出发&#xff0c;系统梳理机器学习算法&#xff08;监督学习…

作者头像 李华