前言
Prometheus 的数据是文本和 JSON,直接看不直观。Grafana 是最流行的可视化平台,与 Prometheus 天然搭档。本篇讲解 Grafana 的安装、数据源配置和 Dashboard 设计原则。
一、Grafana 安装
Docker 部署
bash
docker run -d \
--name grafana \
-p 3000:3000 \
-v grafana-data:/var/lib/grafana \
-e GF_SECURITY_ADMIN_PASSWORD=admin123 \
-e GF_INSTALL_PLUGINS=grafana-piechart-panel,grafana-worldmap-panel \
grafana/grafana:11.0.0
Kubernetes 部署
bash
helm repo add grafana https://grafana.github.io/helm-charts
helm install grafana grafana/grafana \
--namespace monitoring \
--create-namespace \
--set persistence.enabled=true \
--set persistence.size=10Gi \
--set adminPassword=admin123
访问
bash
# 默认端口 3000,用户名 admin
# Docker 部署后端口转发
docker exec -it grafana cat /etc/grafana/grafana.ini | grep admin_password
# K8s 端口转发
kubectl port-forward svc/grafana -n monitoring 3000:80
二、配置 Prometheus 数据源
UI 配置
Configuration → Data Sources → Add data source → Prometheus
Name: Prometheus
URL: http://prometheus:9090
Access: Server (default) ← Grafana 服务器端访问
Auth: None
→ Save & Test
Provisioning 配置(推荐)
yaml
# /etc/grafana/provisioning/datasources/prometheus.yml
apiVersion: 1
datasources:
- name: Prometheus
type: prometheus
access: proxy
url: http://prometheus.monitoring:9090
isDefault: true
editable: false
jsonData:
timeInterval: 15s
httpMethod: POST
manageAlerts: false
# Thanos 数据源(长期数据)
- name: Thanos
type: prometheus
access: proxy
url: http://thanos-query.monitoring:9090
isDefault: false
jsonData:
timeInterval: 30s
# 多集群
- name: Prometheus-Staging
type: prometheus
access: proxy
url: http://prometheus-staging:9090
jsonData:
timeInterval: 15s
三、Dashboard 设计原则
原则一:单一职责
每个 Dashboard 只解决一个问题:
✅ "Node Exporter Dashboard" → 主机指标
✅ "Kubernetes API Server Dashboard" → API Server
❌ "All-in-One Dashboard" → 什么都放,什么都看不清
原则二:分层展示
Dashboard 结构(从上到下):
1. 概览行(Row):全局关键指标
- 集群状态、总节点数、总 Pod 数
2. 资源行:CPU/内存/磁盘
- CPU 使用率(时序图)
- 内存使用率(时序图)
- 磁盘使用率(Gauge 图)
3. 网络行:流量/延迟
- 网络带宽(时序图)
- HTTP 延迟 P50/P95/P99(时序图)
4. 错误行:错误率/状态
- HTTP 5xx 率(时序图)
- 连接数(Gauge)
原则三:合理选择图表类型
| 数据类型 | 推荐图表 | 示例 |
|---|---|---|
| 时序数据 | Time Series | CPU 使用率 |
| 当前值/阈值 | Gauge / Stat | 内存使用率 |
| 百分比占比 | Pie Chart | 请求方法分布 |
| 表格数据 | Table | Pod 列表及状态 |
| 分布数据 | Heatmap | 延迟分布 |
| 拓扑关系 | Node Graph | 服务依赖 |
四、创建第一个 Dashboard
示例:Node Exporter Dashboard
1. 创建变量
Dashboard Settings → Variables → Add Variable
变量 1:instance
Name: instance
Type: Query
Data source: Prometheus
Query: label_values(node_cpu_seconds_total, instance)
Refresh: On Dashboard Load
变量 2:job
Name: job
Type: Query
Query: label_values(node_cpu_seconds_total, job)
变量 3:interval
Name: interval
Type: Interval
Values: 1m,5m,10m,30m,1h,6h,12h,1d,7d,30d
2. CPU 使用率面板
promql
# Panel 1: CPU Usage
# Query
100 - (avg(rate(node_cpu_seconds_total{instance=~"$instance",mode="idle"}[$__interval])) * 100)
# Legend
{{ instance }}
# Visualization: Time Series
# Unit: Percent (0-100)
# Color mode: Background
3. 内存使用率面板
promql
# Panel 2: Memory Usage
(1 - node_memory_MemAvailable_bytes{instance=~"$instance"} / node_memory_MemTotal_bytes{instance=~"$instance"}) * 100
# Visualization: Gauge
# Unit: Percent
# Thresholds: 70 (yellow), 90 (red)
4. 磁盘使用率面板
promql
# Panel 3: Disk Usage
(1 - node_filesystem_avail_bytes{instance=~"$instance",fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{instance=~"$instance",fstype!~"tmpfs|overlay"}) * 100
# Legend
{{ instance }} {{ mountpoint }}
# Visualization: Time Series
# Unit: Percent
5. 网络流量面板
promql
# Panel 4: Network RX
sum by(instance) (rate(node_network_receive_bytes_total{instance=~"$instance",device!~"lo|docker.*|veth.*"}[$__interval]) * 8)
# Panel 5: Network TX
sum by(instance) (rate(node_network_transmit_bytes_total{instance=~"$instance",device!~"lo|docker.*|veth.*"}[$__interval]) * 8)
# Visualization: Time Series
# Unit: bits/sec (SI)
五、Dashboard JSON 结构
json
{
"dashboard": {
"id": null,
"uid": "node-exporter",
"title": "Node Exporter Full",
"tags": ["linux", "node"],
"timezone": "browser",
"schemaVersion": 39,
"version": 1,
"refresh": "15s",
"time": {
"from": "now-6h",
"to": "now"
},
"templating": {
"list": [
{
"name": "instance",
"type": "query",
"datasource": "Prometheus",
"query": "label_values(node_cpu_seconds_total, instance)",
"refresh": 1,
"includeAll": true,
"multi": true
}
]
},
"panels": [
{
"id": 1,
"title": "CPU Usage",
"type": "timeseries",
"datasource": "Prometheus",
"gridPos": { "h": 8, "w": 12, "x": 0, "y": 0 },
"targets": [
{
"expr": "100 - (avg(rate(node_cpu_seconds_total{instance=~\"$instance\",mode=\"idle\"}[$__interval])) * 100)",
"legendFormat": "{{ instance }}"
}
],
"fieldConfig": {
"defaults": {
"unit": "percent",
"thresholds": {
"steps": [
{ "color": "green", "value": null },
{ "color": "yellow", "value": 70 },
{ "color": "red", "value": 90 }
]
}
}
}
}
]
}
}
六、常用 Dashboard 模板
导入社区模板
Grafana → Dashboards → Import → 输入 Dashboard ID
推荐模板:
1860 → Node Exporter Full(最常用)
13105 → Node Exporter for Prometheus Dashboard EN 20201010
7249 → Kubernetes Cluster Monitor
15760 → Kubernetes Views (Pods/Nodes/Namespaces)
11354 → MySQL Overview
11835 → Redis Dashboard
7589 → Kafka Exporter Overview
11074 → Nginx Ingress Controller
Provisioning 自动导入
yaml
# /etc/grafana/provisioning/dashboards/dashboards.yml
apiVersion: 1
providers:
- name: 'default'
orgId: 1
folder: 'Monitoring'
type: file
disableDeletion: false
updateIntervalSeconds: 30
allowUiUpdates: true
options:
path: /var/lib/grafana/dashboards
foldersFromFilesStructure: true
# 目录结构
/var/lib/grafana/dashboards/
├── node-exporter.json
├── kubernetes-cluster.json
├── mysql-overview.json
└── app-dashboard.json
七、面板设计技巧
1. 阈值着色
yaml
# Field → Thresholds
Thresholds:
- 70: yellow
- 90: red
# Panel → Color
Mode: Background
2. 单位设置
常见单位:
- CPU 使用率 → Percent (0-100)
- 内存 → bytes(IEC) → GiB
- 网络带宽 → bits/sec (SI) → Mbps
- 延迟 → seconds → ms
- 计数 → short → K/M/B
3. 图例布局
Layout: Table
Placement: Bottom
Width: 100%
排序:Value (Current) → 降序
4. 告警面板
yaml
# Panel type: Alert List
# 显示当前活跃的告警
mode: all_alerts
stateFilter: [firing, pending]
八、Dashboard 变量进阶
级联变量
yaml
# 变量 1:namespace
query: label_values(kube_pod_info, namespace)
# 变量 2:pod(依赖 namespace)
query: label_values(kube_pod_info{namespace=~"$namespace"}, pod)
# 变量 3:container(依赖 pod)
query: label_values(kube_pod_container_info{namespace=~"$namespace",pod=~"$pod"}, container)
自定义变量
yaml
# 类型:Custom
# 选项:1m, 5m, 10m, 30m, 1h
# 用法:rate(metric[$interval])
数据源变量
yaml
# 类型:Datasource
# 限制:Prometheus
# 用法:面板中选择 $datasource
九、性能优化
减少 Panel 数量
❌ 一个 Dashboard 50 个 Panel
✅ 一个 Dashboard 10-15 个 Panel
✅ 用 Row 折叠不常用的 Panel
减少返回序列数
promql
# ❌ 返回所有序列
rate(cpu_usage[5m])
# ✅ 聚合后返回
avg by(instance)(rate(cpu_usage[5m]))
# ✅ Top N
topk(5, rate(cpu_usage[5m]))
合理设置刷新间隔
概览 Dashboard:15-30s
详细 Dashboard:30-60s
大屏展示:5s(需高性能 Prometheus)
⚠️ 踩坑提示 :
变量名不要用 Grafana 内置关键字(如
$__interval)多变量面板注意级联依赖
rate()的范围用$__interval自动适配,不要写死[5m]Dashboard JSON 版本控制,存入 Git
要点回顾
| 设计原则 | 要点 |
|---|---|
| 单一职责 | 一个 Dashboard 只解决一个问题 |
| 分层展示 | 概览 → 资源 → 网络 → 错误 |
| 合理图表 | 时序用 Time Series,当前值用 Gauge |
| 变量驱动 | 用变量实现动态筛选 |
| 阈值着色 | 绿→黄→红 视觉提示 |
| 性能控制 | Panel ≤ 15,用聚合减少序列 |
- Grafana 数据源用 Provisioning 管理
- 变量是 Dashboard 动态化的核心
- 社区模板 ID 直接导入,1860 最常用
- 告警面板用 Alert List 类型
- Dashboard JSON 存入 Git 做版本控制
下一篇预告
基础可视化掌握了,下一篇 【Prometheus·可视化篇】Grafana 进阶:变量、模板、告警与 Dashboard 管理 将深入高级功能。