Grafana对接Prometheus核心配置指南

📅 2026/6/22 4:59:24
Grafana对接Prometheus核心配置指南
1. 这不是“点几下就完事”的操作而是监控系统里最关键的神经接口你刚在服务器上跑起 Prometheus看着http://localhost:9090/metrics里密密麻麻的process_cpu_seconds_total、go_memstats_heap_alloc_bytes指标心里踏实了一半——数据有了。但下一秒打开 Grafana面对空荡荡的“Create your first dashboard”提示手却停住了指标是活的可它们不会自己长出图表来。这不是功能缺失而是两个系统之间最核心的“神经接口”还没接通。Prometheus 是监控系统的心脏与血管负责持续搏动、采集、存储时序数据Grafana 则是它的视觉皮层与运动中枢负责把原始脉冲翻译成可视化的血压曲线、心率热图并驱动告警动作。而“添加 Prometheus Dashboard”这个动作本质是给这套神经系统装上第一副能看清自身状态的眼镜——它不单是导入一个 JSON 文件更是建立一套语义映射告诉 Grafana“node_cpu_seconds_total{modeuser}”这个字符串对应的是“CPU 用户态使用率”这条线横轴是时间纵轴是秒/秒即百分比采样间隔应为 30 秒且需叠加过去 6 小时的数据。我第一次部署时就是卡在这一步Dashboard 导入后图表全为空排查了两小时才发现问题不在 JSON 文件本身而在 Prometheus Data Source 的Scrape Interval 配置与 Dashboard 中 Panel 查询的时间范围不匹配——Grafana 默认查最近 5 分钟而我的 Prometheus 只每 2 分钟抓一次导致大量时间点无数据。这提醒我Dashboard 不是静态快照而是动态查询的实时视图它的生命力完全依赖于底层数据源的配置精度。所以这篇文章不会只告诉你“点击 Import”而是带你亲手拧紧每一颗螺丝从 Data Source 的认证方式选择Basic Auth 还是 Bearer Token为什么在 Kubernetes 环境中后者几乎是唯一安全选项到 Dashboard JSON 中datasource字段的精确匹配逻辑它必须与 Grafana 中 Data Source 的Name 字段完全一致包括大小写和空格再到导入后如何用Explore视图反向验证查询是否真正生效。你将看到的是一个运维工程师在真实生产环境里如何把 Prometheus 和 Grafana 从两个独立模块焊接成一个呼吸同步的有机体。2. Data SourceDashboard 能否“看见”数据的唯一决定者所有 Dashboard 的失效90% 的根因都藏在这里——Data Source 配置。它不是安装完 Grafana 后的一个可选步骤而是 Dashboard 存在的先决条件。就像你要看一张地图首先得确认 GPS 信号是否已接入否则再精美的地图也只是张静态图片。我们来拆解这个“信号接入”过程的核心细节。2.1 URL 配置别被 localhost 欺骗了在本地开发环境你可能习惯性地填http://localhost:9090。这在单机 Docker Compose 部署时或许能工作但在任何稍复杂的场景下它必然失败。原因很简单Grafana 容器内部的localhost指向的是它自己而不是宿主机上的 Prometheus。我曾在一个客户现场遇到过这个问题他们用docker run -p 3000:3000 grafana/grafana启动 GrafanaPrometheus 则是另一个容器网络模式是默认的 bridge。结果 Dashboard 全部报Failed to fetch data。解决方案不是改 URL而是改网络——让两个容器处于同一个自定义 bridge 网络中# 创建网络 docker network create monitoring-net # 启动 Prometheus指定网络并分配别名 docker run -d \ --name prometheus \ --network monitoring-net \ -p 9090:9090 \ -v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml \ prom/prometheus # 启动 Grafana同样加入该网络 docker run -d \ --name grafana \ --network monitoring-net \ -p 3000:3000 \ -e GF_SECURITY_ADMIN_PASSWORDadmin \ grafana/grafana此时在 Grafana 的 Data Source 配置中URL 应填写http://prometheus:9090。这里的prometheus是容器名Docker 内置 DNS 会自动将其解析为对应容器的 IP。这是容器化部署的黄金法则永远用服务名Service Name代替 localhost 或 IP 地址。如果你用 Kubernetes道理一样URL 应为http://prometheus-service.monitoring.svc.cluster.local:9090其中prometheus-service是 Service 名monitoring是命名空间svc.cluster.local是集群内 DNS 后缀。2.2 认证方式安全与便利的平衡点Prometheus 默认不启用认证但这绝不意味着 Grafana 可以裸连。在生产环境你必须考虑两点一是防止 Grafana 的 Data Source 配置被未授权用户导出里面可能包含敏感地址二是防止 Prometheus 的 metrics 端点被外部扫描。因此认证是必选项。Grafana 提供了三种主流方式认证类型适用场景关键配置项我的经验No Auth仅限完全隔离的本地测试环境无需配置一旦离开本机立刻禁用。我把它视为“临时创可贴”贴完就得撕掉。Basic AuthPrometheus 已配置 Nginx 反向代理并启用了 HTTP Basic 认证Username / Password配置简单但密码明文存储在 Grafana 数据库中虽经加密但非绝对安全。适合中小团队快速上线。Bearer TokenPrometheus 运行在 Kubernetes 中且通过 ServiceAccount Token 认证Bearer Token 字段强烈推荐。Token 由 K8s 自动签发有生命周期权限可精细控制如只读metrics。Grafana 配置中只需粘贴 Token无密码泄露风险。提示如果你的 Prometheus 是通过kube-prometheus套件部署的其 Service 默认启用了serviceAccountToken认证。获取 Token 的命令是kubectl -n monitoring get secret prometheus-k8s-token-xxxxx -o jsonpath{.data.token} | base64 -d。把这个输出的长字符串完整粘贴到 Grafana Data Source 的 Bearer Token 字段即可。2.3 查询设置让 Dashboard “呼吸”起来的关键参数很多新手导入 Dashboard 后发现图表是空的或者只显示最近几分钟的数据问题往往出在这里。Data Source 的Query Options并非可有可无的高级设置而是直接影响 Dashboard 行为的底层开关。Min step: 这个值决定了 Grafana 向 Prometheus 请求数据时最小的时间步长即每个数据点之间的时间间隔。如果设为10s而你的 Prometheusscrape_interval是60s那么 Grafana 实际拿到的就是每 60 秒一个点10s的设置毫无意义反而可能增加查询压力。最佳实践是将其设为 Prometheus 的scrape_interval值。你可以在 Prometheus 的/status页面或prometheus.yml配置文件中找到它。HTTP Method: 默认是GET但某些高负载场景下Prometheus 的/api/v1/query_range接口对 GET 请求的 URL 长度有限制通常 2048 字节。当你的 Dashboard 查询包含大量标签过滤器如job~app1|app2|app3|...时URL 可能超长导致 414 错误。此时将 HTTP Method 改为POST即可解决。这是一个典型的“小配置大效果”的案例。Time Range Auto Adjust: 勾选此项后Grafana 会根据当前面板的时间范围如 Last 6 hours自动调整查询的start和end参数。这是绝大多数 Dashboard 的预期行为务必保持勾选。如果取消查询将始终使用固定时间范围Dashboard 就失去了“实时滚动”的能力。3. Dashboard 导入JSON 文件背后的三重校验逻辑当你从 Grafana 官方仪表盘库https://grafana.com/grafana/dashboards/下载一个 JSON 文件比如著名的 Node Exporter FullID: 1860你以为导入就是“上传 → 确认 → 完成”不这背后有三道隐形的校验关卡任何一道失败Dashboard 都会变成一堆无法渲染的空白面板。3.1 第一重校验Datasource 名称的精确匹配这是最常见、也最容易被忽略的错误。Dashboard JSON 文件中每一个 Panel图表的查询都硬编码了一个datasource字段。例如一个 CPU 使用率 Panel 的 JSON 片段可能是{ targets: [ { expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode\idle\}[5m])) * 100), legendFormat: {{instance}}, refId: A } ], datasource: Prometheus }注意最后一行datasource: Prometheus。这个字符串Prometheus必须与你在 Grafana 中创建的 Data Source 的Name 字段完全一致。如果你在创建 Data Source 时Name 填的是My-Prometheus或prometheus小写那么这个 Panel 就会找不到数据源直接报错Data source not found。我见过太多人因为复制粘贴时多了一个空格或者大小写不一致折腾半天。导入前请务必打开 Grafana 的 Data Sources 页面记下你那个 Prometheus Data Source 的精确 Name。导入时在弹出的对话框里有一个下拉菜单让你选择目标 Data Source这里的选择就是在覆盖 JSON 文件中硬编码的datasource值。所以即使 JSON 里写的是Prometheus只要你在这里选择了My-PrometheusGrafana 就会自动把所有 Panel 的datasource字段替换成My-Prometheus。这是最安全的做法。3.2 第二重校验变量Variable的依赖关系一个成熟的 Dashboard 往往包含多个下拉变量Variables比如job、instance、node。这些变量不是装饰品它们是 Dashboard 的“交互式神经元”。它们的值会动态注入到每个 Panel 的 PromQL 查询中实现“选一个节点看它的所有指标”。但变量本身需要数据源来填充其可选项列表。例如job变量的查询可能是label_values(node_cpu_seconds_total, job)。这个查询同样需要指向一个有效的 Prometheus Data Source。如果这个变量所依赖的 Data Source 在导入时没有被正确关联比如你导入时选错了 Data Source那么变量下拉框就会是空的进而导致所有依赖它的 Panel 查询失败因为job的值是空的。导入后第一步不是看图表而是打开 Dashboard 右上角的变量下拉框检查它们是否能正常加载出选项。如果不能说明变量的 Data Source 配置有问题需要进入 Dashboard Settings → Variables → 编辑该变量手动为其指定正确的 Data Source。3.3 第三重校验Panel 查询的语法与语义有效性即使前两关都过了Dashboard 仍可能显示“no data”。这时你需要深入到单个 Panel 的编辑模式。点击 Panel 标题 →Edit→ 切换到Metrics标签页。这里你会看到完整的 PromQL 查询。不要只看表达式要重点检查标签匹配是否合理例如node_cpu_seconds_total{jobnode-exporter}。你的 Prometheus 里job标签的值真的是node-exporter吗还是prometheus或kubernetes-nodes这取决于你部署 Node Exporter 的方式。用curl http://prometheus-ip:9090/api/v1/label/job/values可以列出所有job的值。时间范围是否足够查询中的[5m]表示计算过去 5 分钟的速率。如果你的 Prometheus 才启动了 2 分钟那自然查不到数据。可以临时把[5m]改成[1m]来测试。函数使用是否正确rate()函数要求时间窗口至少是scrape_interval的 4 倍否则会返回NaN。如果你的scrape_interval是15s那么[1m]是安全的但[30s]就很可能失败。注意在 Grafana 的 Explore 视图中你可以直接粘贴并执行任意 PromQL 查询这是验证查询有效性的最快方法。它绕过了 Dashboard 的所有中间环节直连 Prometheus是排错的终极武器。4. 从零开始构建一个可落地的 Node Exporter 监控 Dashboard 实战与其依赖一个庞大的、可能包含你不关心指标的官方 Dashboard不如亲手搭建一个最小可行的MVPDashboard。这不仅能让你彻底理解每个组件的作用还能确保它 100% 匹配你的环境。下面我将带你从零开始构建一个只监控服务器 CPU、内存、磁盘和网络的核心 Dashboard。整个过程你只需要一个文本编辑器和 Grafana 的 Web UI。4.1 步骤一创建四个核心变量Dashboard 的灵魂在于交互性。我们先创建四个变量让 Dashboard 活起来。instance变量用于选择要监控的具体服务器。Name:instanceLabel:InstanceType:QueryData Source: 选择你配置好的 Prometheus Data SourceQuery:label_values(node_cpu_seconds_total, instance)Refresh:On Dashboard LoadMulti-value: ✅ (允许选择多个实例进行对比)Include All option: ✅ (添加一个All选项)job变量用于区分不同类型的 exporter虽然我们目前只有 node-exporter但为未来扩展留接口。Name:jobLabel:JobType:QueryData Source: 同上Query:label_values(node_cpu_seconds_total, job)Refresh:On Dashboard Loadcpu_mode变量用于选择 CPU 模式user, system, idle 等方便切换查看。Name:cpu_modeLabel:CPU ModeType:CustomCustom all value:.*(正则匹配所有)Options:user,system,idle,iowait,irq,softirqtime_range变量用于快速切换时间范围替代右上角的全局时间选择器。Name:time_rangeLabel:Time RangeType:CustomOptions:1h,6h,24h,7dDefault:6h提示变量的Refresh设置至关重要。On Dashboard Load意味着每次打开 Dashboard 时变量选项都会重新从 Prometheus 拉取最新数据确保你看到的是真实的、最新的服务器列表。如果设为Never变量列表将永远停留在你第一次创建时的状态。4.2 步骤二添加第一个 Panel —— CPU 使用率现在我们添加第一个真正的监控图表CPU 使用率。点击 Add new panel。在 Metrics 标签页输入 PromQL100 - (avg by(instance) (rate(node_cpu_seconds_total{modeidle, instance~$instance, job~$job}[5m])) * 100)这个表达式的意思是对每个instance计算过去 5 分钟内idle模式的 CPU 时间占比然后用100减去它得到实际使用率。$instance和$job是变量占位符Grafana 会在查询时自动替换为用户在变量下拉框中选择的值。在 Visualization 标签页选择Time series。在 Display 标签页勾选Stack series这样多个实例的曲线会堆叠显示便于直观比较总量。在 Panel Options 标签页设置 Title 为CPU Usage (%)。点击右上角Apply。4.3 步骤三添加第二个 Panel —— 内存使用率再次点击 Add new panel。输入 PromQL(node_memory_MemTotal_bytes{instance~$instance, job~$job} - node_memory_MemAvailable_bytes{instance~$instance, job~$job}) / node_memory_MemTotal_bytes{instance~$instance, job~$job} * 100这里我们用MemAvailableLinux 3.14而非MemFree因为它更准确地反映了真正可用的内存排除了可回收的缓存。Visualization 选择Time series。Title 设为Memory Usage (%)。4.4 步骤四添加第三个 Panel —— 根分区磁盘使用率新建 Panel。PromQL100 * (node_filesystem_size_bytes{mountpoint/, fstype~ext4|xfs, instance~$instance, job~$job} - node_filesystem_free_bytes{mountpoint/, fstype~ext4|xfs, instance~$instance, job~$job}) / node_filesystem_size_bytes{mountpoint/, fstype~ext4|xfs, instance~$instance, job~$job}这里我们加了fstype过滤确保只监控 ext4 或 xfs 文件系统避免因挂载了 NFS 或其他类型文件系统而引入噪音。Title:Root FS Usage (%)。4.5 步骤五保存与分享点击右上角Save按钮。给 Dashboard 命名为My Server Monitor。点击Save确认。现在你拥有了一个完全属于自己的、轻量级、可定制的监控 Dashboard。它没有冗余的图表每一个 Panel 都是你亲手写的、理解其含义的查询。更重要的是它已经内置了变量交互你可以轻松地在不同服务器、不同时间范围之间切换。这就是从“使用者”迈向“构建者”的关键一步。后续你可以基于这个 MVP逐步添加网络流量、进程数、温度等更多 Panel让它成长为你的专属监控中心。5. 故障排查全景图从“图表为空”到“数据飞升”的完整链路在 Grafana 世界里“图表为空”是最常见的报错但它背后的原因千差万别。与其大海捞针不如按一个清晰的、自底向上的排查链路来系统性地诊断。这个链路我称之为“三层漏斗模型”从最底层的基础设施逐层向上直到最顶层的用户交互。5.1 第一层漏斗基础设施层Is the data even there?这是最根本的问题。如果 Prometheus 本身就没有采集到数据那么 Grafana 再怎么努力也是无米之炊。检查 Prometheus Target 状态访问http://prometheus-ip:9090/targets。这里列出了所有被 Prometheus 主动抓取的目标Targets。找到你的node-exporter或其他 exporter那一行观察其State列。如果是UP说明抓取成功如果是DOWN则需要检查 exporter 是否在运行、网络是否通畅、Prometheus 的scrape_config是否配置正确。Last Scrape时间应该在几秒到几十秒内更新。直接查询 Prometheus API在浏览器中访问http://prometheus-ip:9090/api/v1/query?querynode_cpu_seconds_total{modeuser}。如果返回了类似{status:success,data:{resultType:vector,result:[{metric:{__name__:node_cpu_seconds_total,instance:192.168.1.100:9100,job:node-exporter,mode:user},value:[1712345678.123,12345.67]}]}}的 JSON说明数据存在且可访问。如果返回{status:error,errorType:bad_data,error:invalid parameter \query\: empty query string}说明你的查询语法有误如果返回404说明 Prometheus 服务本身不可达。5.2 第二层漏斗Grafana Data Source 层Can Grafana talk to it?数据存在了但 Grafana 能否顺利“对话”Test Save回到 Grafana 的 Data Source 配置页面点击右上角的Save test按钮。Grafana 会立即尝试连接 Prometheus 并执行一个简单的健康检查查询。如果这里报错比如HTTP Error Bad Gateway (502)说明网络或认证配置有误如果报Unauthorized说明用户名/密码或 Token 错误。这是最快速的验证方式。检查日志如果Save test成功但 Dashboard 仍为空那就需要看 Grafana 的日志。在 Docker 环境中执行docker logs grafana在 systemd 环境中执行journalctl -u grafana-server -f。查找包含prometheus或datasource关键字的 ERROR 或 WARN 日志。我曾经遇到过一个案例日志里有一行Failed to execute query: context deadline exceeded这明确指向了网络超时最终发现是防火墙规则限制了 Grafana 容器到 Prometheus 容器的 9090 端口。5.3 第三层漏斗Dashboard 层Is the query right?数据源通了最后的障碍就是 Dashboard 本身的查询逻辑。Use Explore这是最强大的工具。在 Grafana 左侧菜单点击Explore图标。在顶部选择你的 Prometheus Data Source。然后把你 Dashboard 中某个 Panel 的 PromQL 完整粘贴进去点击Run query。如果 Explore 能返回数据而 Dashboard 不能那问题 100% 出在 Dashboard 的配置上比如变量没关联好或者 Panel 的datasource字段写错了。如果 Explore 也返回空那就回到第二步检查查询本身。检查变量值在 Dashboard 页面把鼠标悬停在右上角的变量下拉框上Grafana 会显示一个 tooltip告诉你当前选中的值是什么。确保它不是no value或All如果你的查询不支持All比如node_cpu_seconds_total{instanceAll}是非法的。检查时间范围Grafana 右上角的时间选择器其范围必须覆盖 Prometheus 中数据的时间戳。如果你的 Prometheus 只保留了 24 小时的数据而你把时间范围设为Last 7 days那自然查不到东西。可以临时把时间范围调小到Last 5 minutes来测试。最后一个经验当你反复排查无果时最有效的方法是“降级验证”。新建一个最简 Dashboard只包含一个 Panel只用一个最简单的查询比如count(node_cpu_seconds_total)。如果这个最简版能工作说明你的基础环境是 OK 的问题一定出在你原来那个复杂 Dashboard 的某个特定配置上。然后你就可以像剥洋葱一样一层层地添加回原来的变量、Panel 和查询直到找到那个“引爆点”。这是一种极其高效、且能极大提升你对系统理解深度的排错哲学。