主题
NFS 高可用存储监控告警方案
方案概述
基于 Prometheus + Grafana + Alertmanager 构建 NFS 高可用存储监控体系,覆盖:
- 节点层面:CPU、内存、磁盘、网络
- GlusterFS 层面:卷状态、brick 状态、容量、自愈
- NFS-Ganesha 层面:服务存活、导出可用性
- Keepalived 层面:VIP 漂移、VRRP 状态
- 告警通道:邮件 / 钉钉 / 企业微信 / Slack
监控架构
┌─────────────────┐
│ Grafana │
│ (可视化) │
└────────┬────────┘
│
┌────────▼────────┐
│ Prometheus │
│ (时序数据库) │
└────────┬────────┘
│
┌────────────────────┼────────────────────┐
│ │ │
┌───────▼───────┐ ┌────────▼────────┐ ┌──────▼──────┐
│ Node Exporter │ │ Gluster Exporter │ │ Ganesha │
│ (节点指标) │ │ (卷/brick 指标) │ │ Exporter │
└───────────────┘ └─────────────────┘ └─────────────┘
│ │ │
└────────────────────┼────────────────────┘
│
┌──────────▼──────────┐
│ Alertmanager │
│ (告警通知) │
└─────────────────────┘环境规划
| 组件 | 部署节点 | 端口 |
|---|---|---|
| Prometheus | 独立监控节点(或 node1) | 9090 |
| Grafana | 独立监控节点(或 node1) | 3000 |
| Alertmanager | 独立监控节点(或 node1) | 9093 |
| Node Exporter | 所有存储节点 | 9100 |
| Gluster Exporter | 所有存储节点 | 9189 |
| Ganesha Exporter | 所有存储节点 | 9580 |
为简化,以下假设监控组件部署在
monitor节点(IP:10.0.0.20),存储节点为node1/2/3。
1. 部署 Prometheus
在监控节点执行:
bash
useradd --no-create-home --shell /bin/false prometheus
mkdir -p /etc/prometheus /var/lib/prometheus
cd /tmp
wget https://github.com/prometheus/prometheus/releases/download/v2.53.0/prometheus-2.53.0.linux-amd64.tar.gz
tar xvf prometheus-2.53.0.linux-amd64.tar.gz
cd prometheus-2.53.0.linux-amd64
cp prometheus promtool /usr/local/bin/
cp -r consoles/ console_libraries/ /etc/prometheus/
chown -R prometheus:prometheus /var/lib/prometheus /etc/prometheus创建 /etc/prometheus/prometheus.yml:
yaml
global:
scrape_interval: 15s
evaluation_interval: 15s
alerting:
alertmanagers:
- static_configs:
- targets: ['localhost:9093']
rule_files:
- /etc/prometheus/rules/*.yml
scrape_configs:
- job_name: 'prometheus'
static_configs:
- targets: ['localhost:9090']
- job_name: 'node-exporter'
static_configs:
- targets:
- 'node1:9100'
- 'node2:9100'
- 'node3:9100'
- job_name: 'gluster-exporter'
static_configs:
- targets:
- 'node1:9189'
- 'node2:9189'
- 'node3:9189'
- job_name: 'ganesha-exporter'
static_configs:
- targets:
- 'node1:9580'
- 'node2:9580'
- 'node3:9580'创建 systemd 服务 /etc/systemd/system/prometheus.service:
ini
[Unit]
Description=Prometheus Monitoring System
After=network.target
[Service]
User=prometheus
Group=prometheus
Type=simple
ExecStart=/usr/local/bin/prometheus \
--config.file=/etc/prometheus/prometheus.yml \
--storage.tsdb.path=/var/lib/prometheus/ \
--web.console.templates=/etc/prometheus/consoles \
--web.console.libraries=/etc/prometheus/console_libraries
Restart=always
[Install]
WantedBy=multi-user.target启动:
bash
systemctl daemon-reload
systemctl enable --now prometheus2. 部署 Node Exporter(所有存储节点)
bash
cd /tmp
wget https://github.com/prometheus/node_exporter/releases/download/v1.8.1/node_exporter-1.8.1.linux-amd64.tar.gz
tar xvf node_exporter-1.8.1.linux-amd64.tar.gz
cp node_exporter-1.8.1.linux-amd64/node_exporter /usr/local/bin/创建 systemd 服务 /etc/systemd/system/node_exporter.service:
ini
[Unit]
Description=Node Exporter
After=network.target
[Service]
User=root
Type=simple
ExecStart=/usr/local/bin/node_exporter \
--collector.filesystem.mount-points-exclude='^/(sys|proc|dev|run|var/lib/docker/.+|var/lib/containers/storage/.+)($|/)'
Restart=always
[Install]
WantedBy=multi-user.target启动:
bash
systemctl daemon-reload
systemctl enable --now node_exporter3. 部署 Gluster Exporter(所有存储节点)
使用社区版 gluster_exporter:
bash
cd /tmp
wget https://github.com/ofesseler/gluster_exporter/releases/download/v0.2.7/gluster_exporter-0.2.7-linux-amd64.tar.gz
tar xvf gluster_exporter-0.2.7-linux-amd64.tar.gz
cp gluster_exporter /usr/local/bin/创建 systemd 服务 /etc/systemd/system/gluster_exporter.service:
ini
[Unit]
Description=GlusterFS Prometheus Exporter
After=network.target
[Service]
User=root
Type=simple
ExecStart=/usr/local/bin/gluster_exporter \
--web.listen-address=:9189 \
--web.telemetry-path=/metrics
Restart=always
[Install]
WantedBy=multi-user.target启动:
bash
systemctl daemon-reload
systemctl enable --now gluster_exporter验证指标:
bash
curl http://localhost:9189/metrics | head4. 部署 Ganesha Exporter(所有存储节点)
NFS-Ganesha 原生通过 D-Bus 暴露统计信息,但没有成熟 exporter。这里使用一个轻量自定义 Python exporter。
4.1 安装依赖
bash
# Ubuntu
apt install -y python3-pip
pip3 install prometheus-client dbus-python --break-system-packages
# RHEL/Rocky
dnf install -y python3-pip python3-dbus
pip3 install prometheus-client4.2 创建 exporter 脚本
写入 /usr/local/bin/ganesha_exporter.py:
python
#!/usr/bin/env python3
import dbus
import sys
from prometheus_client import start_http_server, Gauge, Info
import time
EXPORTS_TOTAL = Gauge('ganesha_exports_total', 'Total NFS exports')
GANESHA_UP = Gauge('ganesha_up', 'NFS-Ganesha service status')
def collect():
try:
bus = dbus.SystemBus()
obj = bus.get_object('org.ganesha.nfsd', '/org/ganesha/nfsd/admin')
iface = dbus.Interface(obj, 'org.ganesha.nfsd.admin')
stats = iface.GetAllStats()
EXPORTS_TOTAL.set(len(stats.get('exports', [])))
GANESHA_UP.set(1)
except Exception as e:
print(f"Error: {e}", file=sys.stderr)
EXPORTS_TOTAL.set(0)
GANESHA_UP.set(0)
if __name__ == '__main__':
start_http_server(9580)
while True:
collect()
time.sleep(15)bash
chmod +x /usr/local/bin/ganesha_exporter.py4.3 创建 systemd 服务
写入 /etc/systemd/system/ganesha_exporter.service:
ini
[Unit]
Description=NFS-Ganesha Prometheus Exporter
After=nfs-ganesha.service
[Service]
User=root
Type=simple
ExecStart=/usr/local/bin/ganesha_exporter.py
Restart=always
[Install]
WantedBy=multi-user.target启动:
bash
systemctl daemon-reload
systemctl enable --now ganesha_exporter验证:
bash
curl http://localhost:9580/metrics5. 配置告警规则
创建目录并写入规则文件:
bash
mkdir -p /etc/prometheus/rules/etc/prometheus/rules/nfs-ha-alerts.yml
yaml
groups:
- name: node_alerts
rules:
- alert: NodeDown
expr: up{job="node-exporter"} == 0
for: 1m
labels:
severity: critical
annotations:
summary: "节点 {{ $labels.instance }} 不可达"
description: "Node Exporter 在 {{ $labels.instance }} 上已经 1 分钟无响应。"
- alert: DiskSpaceLow
expr: (node_filesystem_avail_bytes / node_filesystem_size_bytes) < 0.1
for: 5m
labels:
severity: warning
annotations:
summary: "节点 {{ $labels.instance }} 磁盘空间不足"
description: "挂载点 {{ $labels.mountpoint }} 可用空间低于 10%。"
- alert: HighCPUUsage
expr: 100 - (avg(irate(node_cpu_seconds_total{mode="idle"}[5m])) by (instance) * 100) > 85
for: 5m
labels:
severity: warning
annotations:
summary: "节点 {{ $labels.instance }} CPU 使用率过高"
description: "CPU 使用率超过 85%。"
- name: gluster_alerts
rules:
- alert: GlusterVolumeDown
expr: gluster_volume_status == 0
for: 1m
labels:
severity: critical
annotations:
summary: "GlusterFS 卷异常"
description: "卷 {{ $labels.volume }} 状态异常。"
- alert: GlusterBrickDown
expr: gluster_brick_status == 0
for: 1m
labels:
severity: critical
annotations:
summary: "GlusterFS Brick 离线"
description: "卷 {{ $labels.volume }} 的 brick {{ $labels.brick }} 离线。"
- alert: GlusterVolumeUsageHigh
expr: (gluster_volume_size_used_bytes / gluster_volume_size_total_bytes) > 0.85
for: 5m
labels:
severity: warning
annotations:
summary: "GlusterFS 卷使用率过高"
description: "卷 {{ $labels.volume }} 使用率超过 85%。"
- alert: GlusterHealPending
expr: gluster_heal_count > 0
for: 10m
labels:
severity: warning
annotations:
summary: "GlusterFS 存在待修复条目"
description: "卷 {{ $labels.volume }} 有 {{ $value }} 个待修复条目,超过 10 分钟。"
- name: ganesha_alerts
rules:
- alert: GaneshaServiceDown
expr: ganesha_up == 0
for: 1m
labels:
severity: critical
annotations:
summary: "NFS-Ganesha 服务异常"
description: "节点 {{ $labels.instance }} 的 NFS-Ganesha 服务不可用。"
- alert: GaneshaNoExports
expr: ganesha_exports_total == 0
for: 1m
labels:
severity: critical
annotations:
summary: "NFS-Ganesha 无可用导出"
description: "节点 {{ $labels.instance }} 没有活动的 NFS 导出。"注:
gluster_exporter实际指标名可能与上述略有不同,部署后请访问http://node1:9189/metrics确认实际指标名,再调整规则。
重载 Prometheus:
bash
systemctl reload prometheus
# 或
curl -X POST http://localhost:9090/-/reload6. 部署 Alertmanager
bash
cd /tmp
wget https://github.com/prometheus/alertmanager/releases/download/v0.27.0/alertmanager-0.27.0.linux-amd64.tar.gz
tar xvf alertmanager-0.27.0.linux-amd64.tar.gz
cp alertmanager-0.27.0.linux-amd64/alertmanager /usr/local/bin/
cp alertmanager-0.27.0.linux-amd64/amtool /usr/local/bin/
mkdir -p /etc/alertmanager /var/lib/alertmanager6.1 邮件通知配置
创建 /etc/alertmanager/alertmanager.yml:
yaml
global:
smtp_smarthost: 'smtp.example.com:587'
smtp_from: 'alert@example.com'
smtp_auth_username: 'xxx'
smtp_auth_password: 'xxx'
route:
receiver: 'email-admin'
group_by: ['alertname']
group_wait: 10s
group_interval: 10s
repeat_interval: 1h
receivers:
- name: 'email-admin'
email_configs:
- to: 'admin@example.com'
send_resolved: true6.2 钉钉通知配置(可选)
yaml
receivers:
- name: 'dingtalk'
webhook_configs:
- url: 'http://localhost:8060/dingtalk/webhook1/send'
send_resolved: true需额外部署 prometheus-webhook-dingtalk:
bash
docker run -d \
-p 8060:8060 \
-v /etc/prometheus-webhook-dingtalk/config.yml:/etc/prometheus-webhook-dingtalk/config.yml \
--name dingtalk \
timonwong/prometheus-webhook-dingtalk6.3 启动 Alertmanager
创建 /etc/systemd/system/alertmanager.service:
ini
[Unit]
Description=Alertmanager
After=network.target
[Service]
User=root
Type=simple
ExecStart=/usr/local/bin/alertmanager \
--config.file=/etc/alertmanager/alertmanager.yml \
--storage.path=/var/lib/alertmanager
Restart=always
[Install]
WantedBy=multi-user.target启动:
bash
systemctl daemon-reload
systemctl enable --now alertmanager7. 部署 Grafana
bash
# Ubuntu
apt install -y apt-transport-software-properties wget
wget -q -O /usr/share/keyrings/grafana.key https://apt.grafana.com/gpg.key
echo "deb [signed-by=/usr/share/keyrings/grafana.key] https://apt.grafana.com stable main" | tee /etc/apt/sources.list.d/grafana.list
apt update
apt install -y grafana
# RHEL/Rocky
cat > /etc/yum.repos.d/grafana.repo <<EOF
[grafana]
name=grafana
baseurl=https://rpm.grafana.com
repo_gpgcheck=1
enabled=1
gpgcheck=1
gpgkey=https://rpm.grafana.com/gpg.key
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
EOF
dnf install -y grafana启动:
bash
systemctl enable --now grafana-server默认访问:http://monitor-ip:3000,默认账号 admin/admin。
7.1 添加 Prometheus 数据源
- 登录 Grafana
- Configuration → Data Sources → Add data source
- 选择 Prometheus
- URL 填
http://localhost:9090 - Save & Test
7.2 推荐仪表盘
| 用途 | 导入 ID / 来源 |
|---|---|
| Node Exporter 主机监控 | ID: 1860 |
| GlusterFS 监控 | 可基于本文指标自建或搜索社区模板 |
| NFS-Ganesha 监控 | 自建仪表盘 |
8. 关键监控指标速查
| 层级 | 指标 | 含义 |
|---|---|---|
| 节点 | node_cpu_seconds_total | CPU 使用 |
| 节点 | node_memory_MemAvailable_bytes | 可用内存 |
| 节点 | node_filesystem_avail_bytes | 磁盘可用空间 |
| GlusterFS | gluster_volume_status | 卷是否在线 |
| GlusterFS | gluster_brick_status | brick 是否在线 |
| GlusterFS | gluster_volume_size_used_bytes | 卷已用容量 |
| GlusterFS | gluster_heal_count | 待修复条目数 |
| Ganesha | ganesha_up | 服务是否存活 |
| Ganesha | ganesha_exports_total | 导出数量 |
9. 验证告警
9.1 手动触发告警测试
停止 node1 的 Ganesha 服务:
bash
systemctl stop nfs-ganesha预期:
- Prometheus Alert 页面出现
GaneshaServiceDown - 1 分钟后 Alertmanager 发送告警通知
恢复后:
bash
systemctl start nfs-ganesha9.2 查看告警状态
bash
# Prometheus 告警页面
http://monitor-ip:9090/alerts
# Alertmanager
http://monitor-ip:909310. 日常运维命令
bash
# 查看所有 targets 状态
curl -s http://localhost:9090/api/v1/targets | jq
# 手动测试告警规则
/usr/local/bin/promtool check rules /etc/prometheus/rules/*.yml
# 检查 Alertmanager 配置
/usr/local/bin/amtool check-config /etc/alertmanager/alertmanager.yml
# 查看 GlusterFS 指标
curl -s http://node1:9189/metrics | grep gluster
# 查看 Ganesha 指标
curl -s http://node1:9580/metrics11. 注意事项
- 防火墙:确保监控节点能访问存储节点的
9100、9189、9580端口。 - 时间同步:Prometheus 依赖时间戳,所有节点必须保持时间一致。
- ** retention**:生产环境建议配置 Prometheus 数据保留策略,如
--storage.tsdb.retention.time=30d。 - 指标名差异:不同版本的 exporter 指标名可能不同,请以实际
/metrics输出为准调整告警规则。 - 安全:生产环境建议为 Prometheus/Grafana 配置 HTTPS 和认证。
文档版本:v1.0
适用系统:Ubuntu 22.04 / RHEL 9 / Rocky Linux 9