Grafana 数据源、看板与告警治理工具手册
Grafana 面板显示“No data”时,至少有四种完全不同的原因:后端没有数据,数据源连错地址,查询被变量或时间范围改坏,面板 transform 又过滤了结果。直接改 PromQL,往往只是把故障从一层推到另一层。可靠的排查顺序是先验证后端原始查询,再验证 Grafana 数据源代理,接着看 Explore,最后才检查 dashboard 的变量、时间范围、step、transform 和 panel 配置。
下面使用 Grafana 13.0.2 作为固定实验基线。官方容器仓库使用 grafana/grafana;grafana/grafana-oss 从 12.4.0 起不再更新。版本号只约束实验和升级回放,部署新环境时仍应核对 Grafana releases 与 Docker 安装文档。
先区分浏览器地址和数据源地址
浏览器访问 http://127.0.0.1:3000,Grafana 容器访问 Prometheus 时却不能使用宿主机语义下的 localhost:9090。容器内的 localhost 指向 Grafana 自己。这个地址错误会呈现为 Grafana 健康、Prometheus 健康、数据源仍然失败。
# compose.yaml
services:
prometheus:
image: prom/prometheus:v3.12.0
ports: ["127.0.0.1:9090:9090"]
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml:ro
grafana:
image: grafana/grafana:13.0.2
ports: ["127.0.0.1:3000:3000"]
environment:
GF_SECURITY_ADMIN_USER: admin
GF_SECURITY_ADMIN_PASSWORD: ${GRAFANA_ADMIN_PASSWORD:?set a local password}
GF_USERS_ALLOW_SIGN_UP: "false"
volumes:
- ./grafana/provisioning:/etc/grafana/provisioning:ro
- ./grafana/dashboards:/var/lib/grafana/dashboards:ro
- grafana-data:/var/lib/grafana
depends_on: [prometheus]
volumes:
grafana-data: {}管理员密码由部署环境注入,不能把真实值写进 Compose、截图或文章仓库。启动后同时检查 HTTP 健康和数据库状态,再从 Grafana 容器验证后端名称解析。
export GRAFANA_ADMIN_PASSWORD='replace-with-a-local-test-password'
docker compose up -d
curl -fsS http://127.0.0.1:3000/api/health
docker compose exec grafana wget -qO- http://prometheus:9090/-/ready/api/health 返回数据库 ok 只证明 Grafana 自身能读写状态库,不证明数据源可查询。后面的请求则证明容器网络里的 Prometheus 名称与端口可达。TLS、代理认证或租户头存在时,还要单独验证握手、身份和租户路由。
Provisioning 把隐式状态变成可评审文件
数据源通过 UI 创建很快,却会把 URL、默认选择、最小 step、认证方式和敏感配置留在数据库里。多人环境更适合用 provisioning 建立权威来源,让新实例能从仓库和 Secret 恢复同一状态。
# grafana/provisioning/datasources/prometheus.yml
apiVersion: 1
prune: true
datasources:
- name: Prometheus
uid: prometheus-main
type: prometheus
access: proxy
url: http://prometheus:9090
isDefault: true
editable: false
version: 1
jsonData:
timeInterval: 15s
httpMethod: POST稳定 uid 比展示名称重要。Dashboard JSON、告警规则和 API 自动化都可以引用 UID;如果每套环境让 Grafana 随机生成标识,同一份看板会在迁移后找不到数据源。access: proxy 表示浏览器把查询交给 Grafana server,再由 Grafana 访问后端,因此后端网络凭证和可达性发生在服务端。
密码、token 和客户端密钥应进入 secureJsonData,普通配置进入 jsonData。Provisioning 文件仍可能通过环境变量引用 Secret,但要注意 $ 展开与转义;更稳妥的做法是让部署系统把敏感文件挂载到受限路径,或者使用有审计能力的 Secret 集成。Grafana 数据库会加密 secure 字段,不代表导出的环境变量、容器检查结果和部署日志自动安全。
官方 provisioning 文档 说明了 datasource version 在多实例更新时的作用。多个 Grafana 实例若加载不同版本的配置,较旧配置不应覆盖较新配置。prune: true 也具有删除语义:文件中移除数据源后,启动或同步过程可能把对象从 Grafana 删除,变更评审不能只检查新增内容。
Dashboard 需要稳定身份和明确所有权
文件 provider 可以把 dashboard JSON 放进 Git,并持续同步到指定 folder。
# grafana/provisioning/dashboards/default.yml
apiVersion: 1
providers:
- name: platform-metrics
orgId: 1
folder: Platform Metrics
type: file
disableDeletion: false
allowUiUpdates: false
updateIntervalSeconds: 30
options:
path: /var/lib/grafana/dashboards{
"uid": "platform-node-health",
"title": "Platform / Node health",
"schemaVersion": 42,
"version": 1,
"refresh": "30s",
"panels": [
{
"id": 1,
"type": "timeseries",
"title": "Target up",
"datasource": {"type": "prometheus", "uid": "prometheus-main"},
"targets": [{"refId": "A", "expr": "up{job=\"node\"}"}],
"gridPos": {"h": 8, "w": 24, "x": 0, "y": 0}
}
]
}allowUiUpdates: false 明确文件是权威来源。设为 true 时,用户可以在 UI 保存修改,但文件下一次更新仍可能覆盖数据库中的同 UID dashboard;UI 也不会自动把改动写回 Git。团队必须选定一种真实工作流:文件所有权、Terraform/API 所有权,或者受控的 UI 编辑与导出。三种方式同时写同一对象,只会制造漂移。
Dashboard 变量不是无害的下拉框。一个展开到数千 label value 的变量,会先请求元数据,再让每个 panel 生成更宽的查询;重复 panel、长时间范围和过快 refresh 又会放大并发。排查慢看板时应从 Query inspector 保存实际请求、响应大小和耗时,再到后端查看并发、扫描量与超时。仅压缩前端 JSON,不会降低数据源计算成本。
Panel transform 在浏览器或 Grafana 侧对查询结果继续加工。它适合轻量重命名和拼接,但如果 transform 已承担核心业务计算,Explore 中的原始查询与看板结论就会分叉。关键 SLI 应在后端查询或 recording rule 中形成可测试语义,dashboard 负责展示,不应成为唯一计算实现。
Explore 是诊断入口,不是权限沙箱
Explore 能绕开 dashboard 变量和 transform,直接验证数据源查询。排障时先在 Prometheus、Loki 或 SQL 后端执行最小查询,随后在 Explore 使用同一表达式和时间窗口;两边结果一致后再回到 panel。这样可以把源端、数据源代理、查询编辑器和展示层分别归因。
Grafana OSS 的 folder 权限主要保护 dashboard、alert rule、silence、annotation 与 library panel 等 Grafana 资源。Viewer 默认仍能查询组织中的数据源;一个用户看不到某个 dashboard,不等于他无法在 Explore 或直接查询入口读取同一数据。更细的数据源权限与 RBAC 能力取决于版本和发行版,源端租户隔离、数据库授权和网关策略仍然必须成立。
因此 Grafana 不能被当作数据安全边界的唯一一层。对不同租户复用一个拥有全局权限的数据源,再希望用 dashboard 变量限制租户,只是界面约束。变量可以被修改,请求也能被重新构造。可靠方案要让 Grafana 使用与用户、团队或租户相匹配的后端身份,或由受控查询网关执行强制授权。
匿名访问、public dashboard、snapshot、分享链接和导出 JSON 都可能暴露内部主机名、租户 label、查询表达式和业务数据。启用前要用真实低权限账号验证,而不是用管理员会话观察“页面看起来没问题”。
Grafana Alerting 有自己的状态链
Grafana Alerting 可以跨多个数据源计算规则,并持有 rule、evaluation state、alert instance、contact point、notification policy、mute timing 与 state history。它不是 Prometheus rule 和 Alertmanager 的同义 UI。团队需要明确一条告警由 Prometheus 计算,还是由 Grafana 计算;同一条件在两边各维护一份,通常会产生不同窗口、不同标签和重复通知。
文件 provisioning 可以把 Grafana-managed alert rules 与通知资源放进 provisioning/alerting。API 也可以导出适合 provisioning 的格式,但导出格式与某些写入 API 的 JSON 并不相同,不能把一次 GET 的响应原样 POST 回去。变更前应在隔离实例导入,验证表达式、No Data、Error、pending period、标签模板、contact point 和 resolved 通知。
告警实验不能停在规则显示 Normal。应主动制造数据源超时、空结果和阈值越界,观察 Grafana 如何区分 Error、No Data、Pending 与 Alerting,再恢复数据并确认通知关闭。通知策略的 grouping 和 mute timing 也要使用实际标签验证,否则一处模板变化就可能让同一事故拆成大量通知。
Grafana 多实例默认会在每个节点执行规则,这会把数据源查询负载按节点数放大。Alerting HA 通过实例间通信协调 silence 和通知,目标是减少重复通知,但网络分区时仍优先避免漏报,重复或乱序通知不能被视为绝不发生。官方 Alerting HA 文档 给出了 memberlist 或 Redis 等配置与验证指标;只有负载均衡和共享数据库,尚未完成告警 HA。
多实例共享的是数据库,不是一个 SQLite 文件
Grafana 默认 SQLite 适合本地开发和小型评估。生产高可用需要两个以上 Grafana server、负载均衡入口,以及共享 PostgreSQL 或 MySQL。把同一个 SQLite 文件挂给多个容器不会得到可靠集群,反而会引入并发写入和文件系统故障。
共享数据库保存用户、组织、dashboard、数据源元数据和其他持久状态,但插件文件、provisioning 文件、Secret、镜像版本和外部资源仍需在所有节点保持一致。root_url、反向代理头和 OAuth callback 必须与集群公共地址一致,否则登录成功后可能重定向到错误节点或错误协议。
负载均衡健康检查不能只判断 TCP 端口打开。实例能返回页面但数据库连接池已耗尽、插件初始化失败或依赖数据源不可用时,仍然可能接收请求。健康证据至少包含 Grafana API、共享数据库、关键登录链和一条低成本数据源查询;是否把数据源失败纳入摘流,则要考虑避免后端故障同时摘掉全部 Grafana 节点。
插件是运行代码,也是升级依赖
数据源、panel 和 app plugin 会在 Grafana 进程或浏览器环境中执行,并拥有相应数据访问能力。安装前要固定插件 ID 与版本,核对签名、发行来源、许可证、所需网络和维护状态。让容器每次启动都下载“latest”插件,会让同一镜像在不同时间产生不同运行结果,也会在外网故障时阻塞启动。
升级 Grafana 时要把核心版本、dashboard schemaVersion、插件兼容性、浏览器行为和数据库 migration 一起测试。先克隆生产数据库到隔离环境,启动候选版本,检查 migration 日志、登录、数据源、代表性 dashboard、告警和插件。完成数据库 migration 后直接把镜像降回旧版,未必是安全回滚;必须以官方兼容说明和真实备份恢复演练为准。
备份必须覆盖状态的全部落点
官方 备份文档 把配置、插件数据和 Grafana 数据库分开处理。使用 SQLite 时应在停止 Grafana 后复制数据库文件,避免得到不一致快照;使用 PostgreSQL 或 MySQL 时采用数据库自身的一致性备份。Provisioning 仓库不能替代数据库备份,因为 UI 创建的用户、团队、会话、注释和未代码化对象仍在数据库里。
恢复演练要在空环境中执行。先恢复数据库和 Secret,再部署同版本 Grafana 与固定插件,挂载 provisioning 文件,最后验证登录、组织、权限、数据源、dashboard 和告警。只证明备份文件存在,没有证明它能被当前镜像和插件组合读回。
退出 Grafana 或迁移到新实例时,先盘点 dashboard UID、folder、data source UID、alert rule、contact point、service account、插件和外部认证配置。新旧实例并行时避免两边同时发送告警,可先让新端只读验证,再安排通知切换。旧实例下线后撤销 service account、OAuth secret、数据源凭证和代理访问,按保留要求处理数据库与快照。
实验结束执行 docker compose down 会保留 grafana-data;确认不再需要 dashboard、用户和告警状态后才能执行 docker compose down -v。一套真正可维护的 Grafana 不只是在浏览器里“能看到图”,而是数据源身份、对象所有权、权限、持久状态和升级路径都能被另一位工程师复现。
