欢迎光临

VPS 监控系统搭建完全指南:Prometheus + Grafana + Alertmanager 从零到生产环境

写在前面:为什么你的 VPS 需要一套正经监控系统

很多站长在 VPS 上跑着业务,服务器状态全靠”感觉”——感觉今天网站慢了,感觉磁盘快满了,感觉 CPU 负载有点高。等到真正出问题的时候,往往是网站已经挂了几个小时,用户投诉了才手忙脚乱地登录上去看日志。这种”佛系运维”在小站时代或许还能凑合,但只要你的站点有一定流量,或者跑了多个服务,一套自动化的监控告警系统就是刚需。

开源监控方案里,Prometheus + Grafana 的组合是目前社区最主流的选择。Prometheus 负责采集和存储时序数据,Grafana 负责可视化展示,Alertmanager 负责告警推送。三者配合默契,而且全都免费开源,跑在 512MB 的小鸡上也能流畅运行。本文会从零开始,手把手教你在 VPS 上搭建完整的监控栈,并集成 Telegram 告警通知。

监控仪表盘概念图

一、架构概览:这套监控系统由哪些组件组成

在开始动手之前,我们先搞清楚整个系统的架构和工作流程。这样可以避免”知其然而不知其所以然”的尴尬。

核心组件

组件 功能 资源占用
Prometheus Server 时序数据库,负责拉取指标数据并存储 内存 ~150MB,磁盘视保留策略而定
Node Exporter 部署在被监控机器上,暴露系统指标 内存 ~20MB,CPU 几乎无感
Grafana 可视化面板,接入 Prometheus 数据源 内存 ~80MB,含 SQLite 和面板渲染
Alertmanager 接收告警规则触发的事件,负责路由和去重 内存 ~30MB

数据流

Node Exporter 每 15 秒采集一次系统指标(CPU、内存、磁盘、网络等),暴露在 HTTP 端点上。Prometheus Server 定期从这些端点拉取数据(pull 模式),存入本地的时序数据库。Grafana 通过 PromQL 查询 Prometheus 中的数据,绘制成可视化图表。Alertmanager 接收 Prometheus 触发的告警,根据规则路由到 Telegram、邮件等渠道。

这种 pull 模式的设计有一个显著优势:你不需要在被监控机器上安装 Agent(除了 Node Exporter 这个只读指标暴露器),监控端完全掌控采集节奏,不会因为被监控端异常而导致数据丢失。被监控机器即使挂了,Prometheus 也能通过”最后一次拉取失败”这一事实来触发告警。

二、安装 Prometheus Server

Prometheus 官方提供了预编译的二进制包,安装非常简洁。我们直接下载最新稳定版。

下载与解压


1
2
3
4
5
cd /opt
wget https://github.com/prometheus/prometheus/releases/download/v2.53.0/prometheus-2.53.0.linux-amd64.tar.gz
tar xzf prometheus-2.53.0.linux-amd64.tar.gz
mv prometheus-2.53.0.linux-amd64 prometheus
cd prometheus

创建系统用户

从安全角度考虑,不要让 Prometheus 以 root 身份运行:


1
2
3
4
useradd --no-create-home --shell /bin/false prometheus
mkdir -p /data/prometheus
chown prometheus:prometheus /data/prometheus
chown -R prometheus:prometheus /opt/prometheus

配置文件

编辑

1
/opt/prometheus/prometheus.yml

,这是最简可用的配置:


1
2
3
4
5
6
7
8
9
10
11
12
global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  - job_name: 'node'
    static_configs:
      - targets: ['localhost:9100']

这里

1
scrape_interval

表示每 15 秒拉取一次指标,

1
evaluation_interval

表示每 15 秒评估一次告警规则。

1
scrape_configs

中定义了两个 job:一个是 Prometheus 自身(暴露自身运行指标),另一个是 Node Exporter。后面加了新机器,只需在

1
targets

列表里追加 IP 即可。

Systemd 服务

创建

1
/etc/systemd/system/prometheus.service


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[Unit]
Description=Prometheus
After=network.target

[Service]
User=prometheus
Group=prometheus
Type=simple
ExecStart=/opt/prometheus/prometheus \
  --config.file=/opt/prometheus/prometheus.yml \
  --storage.tsdb.path=/data/prometheus \
  --web.console.templates=/opt/prometheus/consoles \
  --web.console.libraries=/opt/prometheus/console_libraries
Restart=always

[Install]
WantedBy=multi-user.target

启动并设为开机自启:


1
2
3
systemctl daemon-reload
systemctl enable --now prometheus
systemctl status prometheus

确认 Prometheus 正常运行后,访问

1
http://你的VPS_IP:9090

,应该能看到 Prometheus 的 Web UI。在”Status → Targets”页面可以确认所有目标是否处于 UP 状态。

三、部署 Node Exporter

Node Exporter 负责采集系统层面的指标,是整套监控系统的”眼睛”。

安装


1
2
3
4
5
6
cd /opt
wget https://github.com/prometheus/node_exporter/releases/download/v1.8.2/node_exporter-1.8.2.linux-amd64.tar.gz
tar xzf node_exporter-1.8.2.linux-amd64.tar.gz
mv node_exporter-1.8.2.linux-amd64 node_exporter
useradd --no-create-home --shell /bin/false node_exporter
chown -R node_exporter:node_exporter /opt/node_exporter

Systemd 服务


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
cat > /etc/systemd/system/node_exporter.service << 'EOF'
[Unit]
Description=Node Exporter
After=network.target

[Service]
User=node_exporter
Group=node_exporter
Type=simple
ExecStart=/opt/node_exporter/node_exporter \
  --collector.logind \
  --collector.systemd \
  --collector.processes \
  --web.listen-address=:9100
Restart=always

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable --now node_exporter

这里启用了几个有用的 collector:

1
logind

监控登录会话,

1
systemd

监控 systemd 服务状态,

1
processes

监控进程数量和状态。如果你的 VPS 内存非常紧张(512MB 以下),可以去掉

1
--collector.processes

来节省一点资源。

验证 Node Exporter 是否正常工作:


1
curl http://localhost:9100/metrics | head -20

如果返回了一大堆以

1
# HELP

1
# TYPE

开头的指标数据,说明采集成功。现在回到 Prometheus 的配置,如果之前已经加上了

1
localhost:9100

,Prometheus 会自动开始拉取数据。

四、安装配置 Grafana

Grafana 负责将 Prometheus 里枯燥的时序数据变成可视化的仪表盘。

安装(Ubuntu/Debian)


1
2
3
4
5
apt-get install -y software-properties-common
wget -q -O - https://packages.grafana.com/gpg.key | apt-key add -
add-apt-repository "deb https://packages.grafana.com/oss/deb stable main"
apt-get update
apt-get install -y grafana

CentOS/RHEL 用户


1
2
3
4
5
6
7
8
9
10
11
12
cat > /etc/yum.repos.d/grafana.repo << 'EOF'
[grafana]
name=grafana
baseurl=https://packages.grafana.com/oss/rpm
repo_gpgcheck=1
enabled=1
gpgcheck=1
gpgkey=https://packages.grafana.com/gpg.key
sslverify=1
sslcacert=/etc/pki/tls/certs/ca-bundle.crt
EOF
yum install -y grafana

启动 Grafana


1
2
systemctl enable --now grafana-server
systemctl status grafana-server

Grafana 默认监听 3000 端口。访问

1
http://你的VPS_IP:3000

,默认用户名和密码都是

1
admin

,首次登录会要求修改密码。

连接 Prometheus 数据源

  1. 登录 Grafana 后,点击左侧齿轮图标 → “Data Sources”
  2. 点击 “Add data source” → 选择 “Prometheus”
  3. 在 URL 一栏填入
    1
    http://localhost:9090
  4. 点击底部的 “Save & Test”,看到绿色提示 “Data source is working” 即表示连接成功

导入 Node Exporter 仪表盘

Grafana 社区有大量现成的仪表盘模板,我们不需要从头画图表。Node Exporter 最流行的仪表盘 ID 是 1860(作者:rfrail3,专为 Node Exporter 设计)。

  1. 在 Grafana 左侧菜单选择 “+” → “Import”
  2. 在 “Import via grafana.com” 输入框里填入
    1
    1860

    ,点击 “Load”

  3. 选择刚才创建的 Prometheus 数据源,点击 “Import”

几秒钟后,你就能看到 CPU 使用率、内存占用、磁盘 IO、网络流量、系统负载、进程数等几十个指标的实时图表。这个仪表盘非常全面,涵盖了日常运维需要关注的几乎所有系统指标。

Grafana 仪表盘示意图

五、配置告警:当服务器出问题时第一时间通知你

监控数据再好看,如果没人盯着看就失去了意义。告警功能才是监控系统的灵魂。当 CPU 持续飙高、磁盘快满、服务宕机时,我们需要第一时间收到通知。

安装 Alertmanager


1
2
3
4
5
6
cd /opt
wget https://github.com/prometheus/alertmanager/releases/download/v0.27.0/alertmanager-0.27.0.linux-amd64.tar.gz
tar xzf alertmanager-0.27.0.linux-amd64.tar.gz
mv alertmanager-0.27.0.linux-amd64 alertmanager
useradd --no-create-home --shell /bin/false alertmanager
chown -R alertmanager:alertmanager /opt/alertmanager

配置 Telegram 告警

首先创建一个 Telegram Bot,获取 Token。在 Telegram 中搜索 @BotFather,发送

1
/newbot

,按提示创建一个新 Bot,拿到 HTTP API Token(格式类似

1
123456789:ABCdefGHIjklmNOPqrsTUVwxyz

)。然后搜索你的 Bot 用户名,发送

1
/start

,再访问以下 URL 获取 Chat ID:


1
https://api.telegram.org/bot&lt;你的Token&gt;/getUpdates

在返回的 JSON 中找到

1
chat.id

字段。

编辑

1
/opt/alertmanager/alertmanager.yml


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
global:
  resolve_timeout: 5m

route:
  group_by: ['alertname']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  receiver: 'telegram'

receivers:
- name: 'telegram'
  telegram_configs:
  - bot_token: 'YOUR_BOT_TOKEN'
    chat_id: YOUR_CHAT_ID
    send_resolved: true
    parse_mode: 'HTML'
    message: |
      {{ if eq .Status "firing" }}🚨 <b>告警触发</b>{{ else }}✅ <b>告警恢复</b>{{ end }}
      <b>告警名称:</b>{{ .GroupLabels.alertname }}
      <b>严重级别:</b>{{ .CommonLabels.severity }}
      <b>触发时间:</b>{{ .StartsAt.Format "2006-01-02 15:04:05" }}
      <b>详情:</b>{{ .CommonAnnotations.summary }}
      {{ .CommonAnnotations.description }}

创建 Systemd 服务:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
cat > /etc/systemd/system/alertmanager.service << 'EOF'
[Unit]
Description=Alertmanager
After=network.target

[Service]
User=alertmanager
Group=alertmanager
Type=simple
ExecStart=/opt/alertmanager/alertmanager \
  --config.file=/opt/alertmanager/alertmanager.yml \
  --storage.path=/data/alertmanager
Restart=always

[Install]
WantedBy=multi-user.target
EOF

systemctl daemon-reload
systemctl enable --now alertmanager

在 Prometheus 中定义告警规则

创建

1
/opt/prometheus/alert_rules.yml


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
groups:
- name: node_alerts
  interval: 15s
  rules:
  - alert: HighCPUUsage
    expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "CPU 使用率超过 80%(当前值:{{ $value | humanizePercentage }})"
      description: "实例 {{ $labels.instance }} 的 CPU 使用率持续 5 分钟超过 80%,请检查是否有异常进程。"

  - alert: HighDiskUsage
    expr: (1 - (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"})) * 100 > 85
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "磁盘空间使用率超过 85%(当前值:{{ $value | humanizePercentage }})"
      description: "实例 {{ $labels.instance }} 的根分区磁盘使用率已超过 85%,请及时清理或扩容。"

  - alert: DiskFull
    expr: (1 - (node_filesystem_avail_bytes{mountpoint="/"} / node_filesystem_size_bytes{mountpoint="/"})) * 100 > 93
    for: 2m
    labels:
      severity: critical
    annotations:
      summary: "磁盘空间即将耗尽(当前值:{{ $value | humanizePercentage }})"
      description: "实例 {{ $labels.instance }} 的根分区使用率已超过 93%,有宕机风险!"

  - alert: HighMemoryUsage
    expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 90
    for: 5m
    labels:
      severity: warning
    annotations:
      summary: "内存使用率超过 90%(当前值:{{ $value | humanizePercentage }})"
      description: "实例 {{ $labels.instance }} 的内存使用率超过 90%,建议检查内存泄漏或考虑扩容。"

  - alert: NodeDown
    expr: up == 0
    for: 1m
    labels:
      severity: critical
    annotations:
      summary: "服务器宕机"
      description: "实例 {{ $labels.instance }} 已离线超过 1 分钟!"

  - alert: HighLoadAverage
    expr: node_load15 > (count(node_cpu_seconds_total{mode="idle"}) by (instance)) * 0.8
    for: 10m
    labels:
      severity: warning
    annotations:
      summary: "系统负载过高(15 分钟负载:{{ $value }})"
      description: "实例 {{ $labels.instance }} 的 15 分钟平均负载超过了 CPU 核心数的 80%,系统可能处于过载状态。"

然后在

1
prometheus.yml

中引用这个规则文件:


1
2
3
4
5
6
7
rule_files:
  - "alert_rules.yml"

alerting:
  alertmanagers:
  - static_configs:
    - targets: ['localhost:9093']

重启 Prometheus 使配置生效:


1
systemctl restart prometheus

现在,当 CPU 持续超过 80%、磁盘使用率超过 85%、服务器宕机等情况发生时,你的 Telegram 会立刻收到告警消息。当指标恢复正常时,Alertmanager 还会发送一条”告警恢复”的通知。

六、监控多台 VPS

如果你手里不止一台机器,这套方案同样可以轻松扩展。只需要在其他 VPS 上也安装 Node Exporter,然后在 Prometheus 的配置文件中添加对应目标即可。

在其他机器上安装 Node Exporter(步骤同上),然后在主 Prometheus 的

1
prometheus.yml

中追加:


1
2
3
4
5
6
7
  - job_name: 'node'
    static_configs:
      - targets:
        - 'localhost:9100'        # 本机
        - '192.168.1.2:9100'      # 第二台 VPS
        - '192.168.1.3:9100'      # 第三台 VPS
        - '你的其他VPS_IP:9100'

重启 Prometheus 后,Grafana 仪表盘会自动显示所有机器的数据,下拉菜单可以切换查看不同实例。Grafana 的 1860 号仪表盘已经内置了实例选择器,多台机器共享同一个面板,非常直观。

需要注意的是,如果被监控的 VPS 和 Prometheus 不在同一个内网,你需要确保 Node Exporter 的端口(9100)在防火墙上对 Prometheus 服务器的 IP 放开。但不要对全世界开放——只允许监控服务器的 IP 访问即可,可以在 Node Exporter 侧用 iptables 限制:


1
2
iptables -A INPUT -p tcp --dport 9100 -s 你的监控服务器IP -j ACCEPT
iptables -A INPUT -p tcp --dport 9100 -j DROP

七、数据保留策略与磁盘优化

Prometheus 默认将数据保留 15 天。对于小 VPS 来说,15 天的数据量大约占用 2-5GB 磁盘空间,取决于采集的指标数量。如果你的磁盘空间很紧张,可以缩短保留时间:


1
--storage.tsdb.retention.time=7d   # 只保留 7 天数据

也可以在启动参数中加入

1
--storage.tsdb.retention.size=10GB

来限制数据最大占用空间,Prometheus 会自动删除最旧的数据来满足大小限制。

另外,Prometheus 的 WAL(预写日志)默认会占用不少磁盘 IO。如果你的 VPS 是 HDD 而非 SSD,可以考虑将 WAL 目录单独放在内存盘上:


1
2
mkdir -p /dev/shm/prometheus_wal
mount --bind /dev/shm/prometheus_wal /data/prometheus/wal

注意:重启后需要重新挂载,建议写入

1
/etc/fstab

八、安全加固要点

监控系统本身如果不安全,就等于把服务器的命脉拱手让人。以下是一些必须做的安全措施:

Grafana 反向代理 + HTTPS

永远不要直接通过公网 IP + 3000 端口暴露 Grafana。用 Nginx 反代并配置 HTTPS:


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
server {
    listen 443 ssl;
    server_name grafana.yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/grafana.yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/grafana.yourdomain.com/privkey.pem;

    location / {
        proxy_pass http://127.0.0.1:3000;
        proxy_set_header Host $host;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header X-Forwarded-Proto $scheme;
    }
}

Prometheus 加上认证

Prometheus 原生不支持认证,但可以通过 Nginx 反代加 basic auth 来实现:


1
2
3
apt-get install apache2-utils
htpasswd -c /etc/nginx/.htpasswd promadmin
# 输入密码

然后在 Nginx 配置中为 Prometheus 的 location 加上

1
auth_basic

指令。

Node Exporter 限制来源 IP

前面已经说过,用 iptables 限制只允许 Prometheus 服务器访问:


1
2
iptables -A INPUT -p tcp --dport 9100 -s 你的监控服务器IP -j ACCEPT
iptables -A INPUT -p tcp --dport 9100 -j DROP

想持久化保存 iptables 规则,Ubuntu 可以用

1
iptables-persistent

包,CentOS 则默认已经持久化。

九、扩展思考:还能监控什么

这套监控方案的可扩展性非常好。除了系统层面的指标,你还可以监控非常多的东西:

  • Nginx 指标:开启 Nginx 的
    1
    stub_status

    模块,用 nginx-lua-prometheus 或 nginx-prometheus-exporter 采集请求数、连接数、响应状态码分布

  • MySQL/PostgreSQL 指标:使用 mysqld_exporter 或 postgres_exporter 监控数据库连接数、慢查询、InnoDB 状态
  • Redis 指标:使用 redis_exporter 监控缓存命中率、内存使用、客户端连接数
  • Docker 容器指标:使用 cadvisor 或 dockerd 暴露的 Prometheus 端点,监控每个容器的 CPU、内存、网络 IO
  • SSL 证书过期:使用 ssl_exporter 或 blackbox_exporter 监控域名证书的剩余有效期,提前通知续期
  • HTTP 端点探活:使用 blackbox_exporter 对网站首页、API 接口进行 ICMP 和 HTTP 探测,发现 5xx 错误立刻告警
  • WordPress 指标:通过自定义 exporter 采集 WordPress 的数据库查询次数、缓存命中率、PHP 进程数

所有这些 exporter 的部署方式都和 Node Exporter 一样——下载二进制文件、创建 systemd 服务、在 Prometheus 中添加 target。社区里几乎你能想到的所有中间件都有对应的 exporter。

十、常见问题排查

Prometheus 页面显示目标为 DOWN

最常见的原因是防火墙没有放开端口。检查 iptables 或云服务商的安全组规则,确保 Prometheus 所在的机器能访问到目标节点的 9100 端口。也可以用

1
telnet 目标IP 9100

简单测试一下连通性。

Grafana 图表显示 “No data”

检查 Grafana 数据源配置是否正确。在 Grafana 的 Explore 页面(左侧指南针图标)输入 PromQL 查询

1
up

,如果能返回数据,说明数据源连接和 Prometheus 采集都正常。如果返回空结果,去 Prometheus 的 Web UI 确认数据是否正常写入。

告警没有触发

检查 Alertmanager 的 Web UI(端口 9093)看是否有告警被路由到。如果 Alertmanager 收到了告警但没有发送 Telegram 消息,检查

1
bot_token

1
chat_id

是否正确。Telegram Bot 需要在目标 Chat 中先被启动(发送

1
/start

)。

Prometheus 占用内存过高

Prometheus 的内存使用量和指标基数(cardinality)直接相关。如果你发现内存占用过高,检查是否有 exporter 暴露了过多高基数标签(比如包含大量唯一值的 label)。常用的优化手段包括:在

1
scrape_config

中用

1
metric_relabel_configs

丢弃不需要的高基数指标,或者缩短

1
scrape_interval

减少数据采样频率。

总结

Prometheus + Grafana + Alertmanager 这套组合拳,可以说是目前开源监控领域的最优解。它没有商业监控系统的授权限制,也没有 SaaS 监控服务的按节点收费,一套部署好之后可以无限扩展。对于 VPS 站长来说,花一个下午的时间搭好这套系统,以后就能在服务器出问题之前收到预警,而不是等问题发生了才去救火。

从最早的 Node Exporter 系统指标,到后续的数据库、中间件、自定义业务指标,这套方案可以伴随你的业务增长一路升级。真正的运维高手不是会修服务器的,而是能让服务器在出问题之前就被修好的——而监控系统就是做到这一点的基石。

【本站文章皆为原创,未经允许不得转载】:汤不热吧 » VPS 监控系统搭建完全指南:Prometheus + Grafana + Alertmanager 从零到生产环境
分享到: 更多 (0)