Grafana —— 可视化与告警面板
Grafana —— 可视化与告警面板
分类:09 日志与监控 适用:Grafana 9.x / 10.x / 11.x 一句话:把 Prometheus、MySQL、ES、Zabbix 的数据画成图,配上变量与告警,做运维大屏和排障视图。
1. 它解决什么问题
- 指标有了,但需要一眼看懂的图表。
- 多个数据源要在一个面板里对齐时间线。
- 要按实例/服务切换视图(变量下拉)。
- 需要大屏给值班室看,或嵌入内部系统。
2. 安装
# 官方仓库
apt install -y grafana
dnf install -y grafana
systemctl enable --now grafana-server
# Docker(最省事)
docker run -d --name grafana -p 3000:3000 \
-v grafana-data:/var/lib/grafana \
grafana/grafana-oss:11.2.0
访问 http://<ip>:3000,默认 admin/admin(首次登录强制改密)。
配置文件:/etc/grafana/grafana.ini(或 /usr/share/grafana/conf/defaults.ini 作参考)。
3. 接入数据源
UI:Connections → Data sources → Add
| 数据源 | 用途 | 关键配置 |
|---|---|---|
| Prometheus | 指标 | URL http://prom:9090 |
| Loki | 日志 | URL http://loki:3100 |
| Elasticsearch | 日志/搜索 | URL、索引名、时间字段 |
| MySQL / PostgreSQL | 业务数据 | 连接串(只读账号) |
| Zabbix | 传统监控 | API URL + 账号 |
| InfluxDB | 时序 | URL + token |
Provisioning(推荐,配置即代码):
# /etc/grafana/provisioning/datasources/prom.yml
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://localhost:9090
isDefault: true
jsonData:
timeInterval: 15s
4. 面板与查询
- 新建 Dashboard → Add panel → 选数据源 → 写查询。
- Prometheus 数据源支持
Metrics browser与直接写 PromQL。 - 常用可视化:Time series、Stat、Gauge、Bar gauge、Table、Heatmap、Logs、Text。
常用 PromQL(面板里)
# CPU 使用率
100 - avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100
# 内存使用率
(1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes) * 100
# 磁盘使用率
(1 - node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes) * 100
# 网络流量
rate(node_network_receive_bytes_total{device="eth0"}[5m]) * 8
# QPS
sum(rate(http_requests_total[5m]))
# P99 延迟
histogram_quantile(0.99, sum by(le) (rate(http_request_duration_seconds_bucket[5m])))
单位与阈值
Standard options → Unit:bytes、percent(0-100)、reqps、seconds。Thresholds:绿/黄/红,Stat 面板会变色。Legend:{{instance}}显示标签。Min step:避免请求过密。
5. 变量(多环境切换)
Dashboard settings → Variables → New
| 类型 | 用途 | 查询示例 |
|---|---|---|
| Query | 从数据源拉值 | label_values(up, instance) |
| Custom | 手写列表 | prod,staging,dev |
| Interval | 时间间隔 | 1m,5m,15m,1h |
| Text box | 手动输入 | — |
在查询里引用:node_load1{instance=~"$instance"},多选时用 =~"$instance"(正则匹配)。
6. 告警
Grafana 8+ 统一告警:
Alerting → Alert rules → New alert rule- 选数据源与查询,设条件(如
IS ABOVE 80) - 设
Evaluate every 1m for 5m(持续 5 分钟才触发) - 配
Contact points(邮件、企微、钉钉、Webhook) - 配
Notification policies(分组、路由、静默)
# provisioning/alerting/contact.yml
apiVersion: 1
contactPoints:
- orgId: 1
name: ops-webhook
receivers:
- uid: ops-hook
type: webhook
settings:
url: https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx
指标类告警更推荐放在 Prometheus + Alertmanager,Grafana 告警适合"看图时顺手配"的场景,两者不要重复配同一规则。
7. 命令行与 API
# 重置 admin 密码
grafana-cli admin reset-admin-password 'NewPass!'
# 容器内
docker exec -it grafana grafana cli admin reset-admin-password 'NewPass!'
# 插件
grafana-cli plugins install grafana-piechart-panel
grafana-cli plugins ls
systemctl restart grafana-server
# 健康检查
curl -s localhost:3000/api/health | jq
# API:建 dashboard(需 token)
TOKEN=xxx
curl -s -H "Authorization: Bearer $TOKEN" localhost:3000/api/search?query=node | jq
curl -s -H "Authorization: Bearer $TOKEN" localhost:3000/api/datasources | jq '.[].name'
# 导出 dashboard JSON
curl -s -H "Authorization: Bearer $TOKEN" \
localhost:3000/api/dashboards/uid/<uid> | jq '.dashboard' > dash.json
# 导入
curl -s -X POST -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
-d "{\"dashboard\": $(cat dash.json), \"overwrite\": true}" \
localhost:3000/api/dashboards/db
8. 实战场景
8.1 单机资源总览面板
四个 Stat(CPU/内存/磁盘/负载)+ 两个 Time series(网络、磁盘 IO):
100 - avg(rate(node_cpu_seconds_total{mode="idle",instance=~"$instance"}[5m])) * 100
(1 - node_memory_MemAvailable_bytes{instance=~"$instance"} / node_memory_MemTotal_bytes{instance=~"$instance"}) * 100
max by(instance) ((1 - node_filesystem_avail_bytes{fstype!~"tmpfs|overlay",instance=~"$instance"} / node_filesystem_size_bytes) * 100)
node_load1{instance=~"$instance"}
变量 instance 用 label_values(up, instance)。
8.2 嵌入内部系统(iframe)
grafana.ini:
[security]
allow_embedding = true
[auth.anonymous]
enabled = true
org_role = Viewer
<iframe src="http://grafana:3000/d/xxx?kiosk&var-instance=web01"
width="100%" height="600" frameborder="0"></iframe>
&kiosk 隐藏侧边栏,适合大屏。
8.3 配置即代码(Git 管理面板)
provisioning/
├── datasources/prom.yml
├── dashboards/dash.yml
└── dashboards-json/node.json
# dashboards/dash.yml
apiVersion: 1
providers:
- name: 'default'
folder: 'Ops'
type: file
options:
path: /etc/grafana/provisioning/dashboards-json
重启后自动加载,UI 里的修改不会写回文件(需要导出后提交)。
8.4 排查"面板无数据"
# 1. 数据源连通性
curl -s localhost:9090/api/v1/query?query=up | jq '.data.result | length'
# 2. Grafana 后端能否访问
curl -s localhost:3000/api/health
# 3. 查询本身
# 在 Explore 里直接跑 PromQL,看是否返回时间序列
# 4. 时间范围与 step
# 面板时间范围太短、step 太大都会导致空图
9. 常见坑
- 默认密码未改:
admin/admin暴露在公网等于送人头。 - 匿名访问开太大:
org_role = Viewer仍能看到全部数据,敏感面板要单独控制。 - 时间范围与 step 不匹配:查 30 天用
15sstep 会被限制,图很粗糙是正常的。 - 变量多选没写
=~:instance="$instance"在多选时匹配不到。 - 单位设错:bytes 显示成 MB 数值,看图误判。
- 告警重复:Grafana 与 Prometheus 同时配同一规则,收到两遍。
- 面板变慢:查询返回过多序列(没加
sum by),或时间范围过大。 - Provisioning 与 UI 冲突:被 provisioning 管理的 dashboard 在 UI 改了会提示只读,改动要回写文件。
- 插件安装后不生效:需要重启服务,容器内要挂载插件目录。
- 数据源代理模式:
access: proxy由 Grafana 后端访问,direct由浏览器访问,内网地址必须用 proxy。 - 时区:Dashboard 时区默认浏览器本地,跨时区团队要统一为 UTC 或固定时区。
- 快照泄露:Snapshot 链接公开可访问,含数据,别随便分享。
10. 速查表
systemctl enable --now grafana-server
docker run -d -p 3000:3000 -v grafana-data:/var/lib/grafana grafana/grafana-oss
grafana-cli admin reset-admin-password 'NewPass!'
grafana-cli plugins install <plugin>
curl localhost:3000/api/health
# Provisioning
/etc/grafana/provisioning/datasources/*.yml
/etc/grafana/provisioning/dashboards/*.yml
/etc/grafana/provisioning/alerting/*.yml
# 常用 PromQL
100 - avg(rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100
(1 - node_memory_MemAvailable_bytes/node_memory_MemTotal_bytes) * 100
histogram_quantile(0.99, sum by(le)(rate(x_bucket[5m])))
sum(rate(http_requests_total[5m]))