首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >Prometheus Grafana 搭建教程:服务器监控与告警配置

Prometheus Grafana 搭建教程:服务器监控与告警配置

原创
作者头像
hollyx
发布2026-09-16 10:12:14
发布2026-09-16 10:12:14
1100
举报

摘要

监控体系的价值在于让问题在用户反馈之前被发现。本文用 Prometheus 采集指标、Grafana 做可视化、Alertmanager 发送告警,搭建一套完整的服务器与服务监控。内容涵盖组件职责、Docker 部署、节点与容器指标采集、面板配置、告警规则编写与通知对接,以及指标缺失和存储膨胀的排查方法。

一、组件职责与数据流

先理清各组件分工,配置时才不会混淆。

组件

职责

Prometheus

定期从各目标拉取指标并存储,执行告警规则判断

Exporter

部署在被监控对象上,把系统或应用状态暴露为指标接口

Grafana

从 Prometheus 查询数据并渲染成图表面板

Alertmanager

接收 Prometheus 触发的告警,去重分组后发送通知

数据流向是:Exporter 暴露指标 → Prometheus 定期拉取并存储 → Grafana 查询展示,同时 Prometheus 根据规则判断异常 → 触发告警给 Alertmanager → 发送通知。

这里有个关键概念:Prometheus 采用主动拉取模式,是它去访问各个 Exporter,而不是 Exporter 推送给它。所以网络连通性方向是 Prometheus 能访问被监控目标,配置时要确认这个方向的可达性和端口放通。

二、资源规划

项目

最低配置

建议配置

CPU

2 核

2~4 核

内存

2 GB

4 GB 及以上

磁盘

40 GB

100 GB 以上

磁盘是这里需要认真估算的项。Prometheus 把所有采集到的指标按时间序列存储,占用与监控目标数量、指标数量和保留时长成正比。

粗略估算方式:每个时间序列每天约产生几 MB 数据。监控十几台机器时,默认配置下一个月的数据通常在几 GB 到几十 GB 之间。实际用量差异较大,建议先按较大值规划,运行一段时间后根据实际增长调整保留策略。

需要放通的端口:

端口

协议

用途

22

TCP

SSH 登录(默认已放通)

80 / 443

TCP

通过反向代理访问面板

9100

TCP

节点指标接口,仅对监控服务器放通

9100 这类指标端口的放通范围要特别注意。指标接口会暴露主机名、磁盘挂载点、进程信息等内部细节,对公网开放等于泄露基础设施信息。这些端口只应对 Prometheus 所在的机器或内网网段放通。轻量应用服务器在实例详情页的「防火墙」页签添加规则时可指定来源;云服务器 CVM 在安全组入站规则中同样支持按网段限定。

三、部署监控组件

代码语言:bash
复制
mkdir -p ~/apps/monitor && cd ~/apps/monitor
mkdir -p prometheus grafana alertmanager

编写 compose.yaml

代码语言:yaml
复制
services:
  prometheus:
    image: prom/prometheus:v3.0.1
    ports:
      - "127.0.0.1:9090:9090"
    volumes:
      - ./prometheus:/etc/prometheus
      - prom-data:/prometheus
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.path=/prometheus'
      - '--storage.tsdb.retention.time=30d'
      - '--web.enable-lifecycle'
    restart: unless-stopped

  alertmanager:
    image: prom/alertmanager:v0.28.0
    ports:
      - "127.0.0.1:9093:9093"
    volumes:
      - ./alertmanager:/etc/alertmanager
    restart: unless-stopped

  grafana:
    image: grafana/grafana:11.4.0
    ports:
      - "127.0.0.1:3000:3000"
    volumes:
      - grafana-data:/var/lib/grafana
    environment:
      GF_SECURITY_ADMIN_PASSWORD: 替换为强密码
      GF_USERS_ALLOW_SIGN_UP: "false"
      GF_SERVER_ROOT_URL: https://monitor.example.com
      TZ: Asia/Shanghai
    restart: unless-stopped

  node-exporter:
    image: prom/node-exporter:v1.8.2
    ports:
      - "9100:9100"
    volumes:
      - /proc:/host/proc:ro
      - /sys:/host/sys:ro
      - /:/rootfs:ro
    command:
      - '--path.procfs=/host/proc'
      - '--path.sysfs=/host/sys'
      - '--path.rootfs=/rootfs'
    restart: unless-stopped

  cadvisor:
    image: gcr.io/cadvisor/cadvisor:v0.49.1
    ports:
      - "127.0.0.1:8080:8080"
    volumes:
      - /:/rootfs:ro
      - /var/run:/var/run:ro
      - /sys:/sys:ro
      - /var/lib/docker/:/var/lib/docker:ro
    restart: unless-stopped

volumes:
  prom-data:
  grafana-data:

几处配置的说明:

  • retention.time=30d 设置数据保留 30 天。这个值直接影响磁盘占用,按实际需求和磁盘容量调整。
  • GF_USERS_ALLOW_SIGN_UP: "false" 关闭 Grafana 的开放注册,避免任何人都能创建账号。
  • 除 node-exporter 外,其他服务端口都绑定到 127.0.0.1,通过反向代理访问。node-exporter 需要被 Prometheus 从其他机器访问,所以对外监听,但要用防火墙限制来源。
  • 镜像版本固定为具体版本号,便于升级控制。

编写 Prometheus 配置 prometheus/prometheus.yml

代码语言:yaml
复制
global:
  scrape_interval: 30s
  evaluation_interval: 30s

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

rule_files:
  - '/etc/prometheus/rules/*.yml'

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

  - job_name: 'node'
    static_configs:
      - targets:
          - 'node-exporter:9100'
          - '10.0.1.20:9100'
          - '10.0.1.21:9100'
        labels:
          env: 'prod'

  - job_name: 'containers'
    static_configs:
      - targets: ['cadvisor:8080']

scrape_interval 决定采集频率。30 秒对多数场景够用,缩短能提高精度但会增加存储和负载。

其他被监控机器只需部署 node-exporter,然后把它们的地址加入 targets 列表。

启动服务:

代码语言:bash
复制
docker compose up -d
docker compose ps

四、配置告警规则

创建规则目录和文件:

代码语言:bash
复制
mkdir -p prometheus/rules
nano prometheus/rules/basic.yml

写入基础告警规则:

代码语言:yaml
复制
groups:
  - name: node-basic
    rules:
      - alert: 实例不可达
        expr: up{job="node"} == 0
        for: 3m
        labels:
          severity: critical
        annotations:
          summary: "{{ $labels.instance }} 已失联"
          description: "目标已持续 3 分钟无法采集"

      - alert: CPU 使用率过高
        expr: 100 - (avg by(instance) (rate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 85
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "{{ $labels.instance }} CPU 使用率偏高"
          description: "当前值 {{ $value | printf \"%.1f\" }}%,已持续 10 分钟"

      - alert: 内存可用率过低
        expr: node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes * 100 < 15
        for: 10m
        labels:
          severity: warning
        annotations:
          summary: "{{ $labels.instance }} 可用内存不足"
          description: "可用内存仅剩 {{ $value | printf \"%.1f\" }}%"

      - alert: 磁盘空间不足
        expr: node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"} / node_filesystem_size_bytes{fstype!~"tmpfs|overlay"} * 100 < 15
        for: 15m
        labels:
          severity: warning
        annotations:
          summary: "{{ $labels.instance }} 磁盘空间不足"
          description: "挂载点 {{ $labels.mountpoint }} 剩余 {{ $value | printf \"%.1f\" }}%"

      - alert: 磁盘将在数天内写满
        expr: predict_linear(node_filesystem_avail_bytes{fstype!~"tmpfs|overlay"}[6h], 4*24*3600) < 0
        for: 30m
        labels:
          severity: warning
        annotations:
          summary: "{{ $labels.instance }} 磁盘预计将写满"
          description: "按当前增长趋势,挂载点 {{ $labels.mountpoint }} 预计 4 天内写满"

几个设计要点:

for 字段避免误报。 它要求条件持续满足指定时长才触发告警。没有这个约束,一次短暂的 CPU 尖峰就会发一条告警,很快就会让人对告警脱敏。

阈值要留出处置时间。 磁盘告警设在剩余 15% 而不是 5%,是为了留出处理窗口。等到只剩 5% 时往往已经开始影响业务了。

趋势预测比静态阈值更有价值。 最后一条规则基于增长趋势预测磁盘写满时间,能在还有充足空间时就发出提醒。这类规则对容量规划很实用。

过滤掉临时文件系统。 不加 fstype 过滤会对容器的临时挂载点产生大量无意义告警。

配置 Alertmanager alertmanager/alertmanager.yml

代码语言:yaml
复制
global:
  resolve_timeout: 5m

route:
  receiver: 'default'
  group_by: ['alertname', 'instance']
  group_wait: 30s
  group_interval: 5m
  repeat_interval: 4h
  routes:
    - matchers:
        - severity = "critical"
      receiver: 'urgent'
      repeat_interval: 1h

receivers:
  - name: 'default'
    webhook_configs:
      - url: 'https://你的通知接收地址'
        send_resolved: true

  - name: 'urgent'
    webhook_configs:
      - url: 'https://你的紧急通知接收地址'
        send_resolved: true

group_by 把同类告警合并成一条通知,避免十台机器同时告警时收到十条消息。repeat_interval 控制未恢复告警的重复提醒间隔,设太短会造成骚扰,设太长可能忘记处理。

重载配置:

代码语言:bash
复制
curl -X POST http://127.0.0.1:9090/-/reload
docker compose restart alertmanager

五、配置 Grafana 面板

先配好反向代理访问:

代码语言:caddyfile
复制
monitor.example.com {
    reverse_proxy 127.0.0.1:3000
}

访问域名并用配置的管理员密码登录。

添加数据源:进入连接设置,添加 Prometheus 类型的数据源,地址填 http://prometheus:9090(容器间通过服务名通信)。保存并测试,显示连接成功即可。

导入现成面板:社区提供了大量成熟的面板模板。在面板导入页面输入模板编号即可导入。常用的有节点资源总览、容器资源监控等类型。导入后选择刚配置的数据源。

导入的面板通常需要微调。指标名称在不同 Exporter 版本间可能有差异,如果某些图表显示无数据,检查该图表使用的查询语句中的指标名是否与实际采集到的一致。

验证指标名是否存在:在 Prometheus 界面的查询框输入指标名,看是否有返回。这比在 Grafana 里猜测更直接。

六、验证监控是否真正可用

监控系统本身失效是很危险的——你会以为一切正常。逐项验证。

采集目标全部健康

访问 Prometheus 的目标页面(通过反向代理或 SSH 转发),确认所有目标状态为 UP。有目标显示 DOWN 时,页面会给出错误原因。

也可以用接口查询:

代码语言:bash
复制
curl -s http://127.0.0.1:9090/api/v1/targets | grep -o '"health":"[^"]*"' | sort | uniq -c

指标能查到数据

在 Prometheus 查询框执行:

代码语言:txt
复制
up
node_memory_MemAvailable_bytes

应返回各实例的数据点。

Grafana 面板有数据:打开导入的面板,确认图表正常渲染而不是显示无数据。

告警规则已加载:在 Prometheus 的规则页面确认所有规则都已加载且无语法错误。

告警能真实触发并送达。这一项最关键,必须主动测试而不是等真实故障。方法是临时构造一个必然满足的条件:

代码语言:yaml
复制
      - alert: 告警链路测试
        expr: up{job="node"} == 1
        for: 1m
        labels:
          severity: warning
        annotations:
          summary: "这是一条测试告警"

加入规则后重载,等待触发并确认收到了通知。验证完立即删除这条规则。

没有做过这一步验证的监控系统,等于不知道告警到底能不能送达。很多人是在真实故障发生后才发现通知配置有误。

恢复通知也要验证:删除测试规则后,确认收到了告警恢复的通知。只有触发没有恢复通知,会让人不清楚问题是否已解决。

七、常见问题与排查

目标显示为 DOWN

按顺序检查:目标机器上的 Exporter 是否运行;9100 端口是否对 Prometheus 所在机器放通;目标地址填写是否正确。从 Prometheus 所在机器实测:

代码语言:bash
复制
docker compose exec prometheus wget -qO- http://10.0.1.20:9100/metrics | head -5

能返回指标内容说明网络通,问题在配置;不通则是网络或防火墙问题。

Grafana 面板显示无数据

先在 Prometheus 中验证该指标是否存在。存在但面板无数据,检查面板的数据源选择和时间范围;指标不存在则是 Exporter 版本差异导致指标名变化,需要调整查询语句。

告警不触发

检查规则是否已加载、表达式在 Prometheus 中执行是否返回结果、for 时长是否已满足。可以在查询框直接运行告警表达式验证。

告警触发但收不到通知

查看 Alertmanager 日志:

代码语言:bash
复制
docker compose logs alertmanager --tail 50

常见原因是通知地址配置错误或目标服务拒绝请求。

告警太多形成噪音

这是监控系统最常见的失败模式——告警多到没人看。处理思路:提高阈值到真正需要干预的水平;延长 for 时长过滤瞬时波动;用 group_by 合并同类;区分严重级别,只让真正紧急的走即时通知渠道。

能触发但不知道该怎么处理的告警,应该删掉或降级。 每条告警都应该对应一个明确的处置动作。

磁盘占用增长快

代码语言:bash
复制
docker compose exec prometheus du -sh /prometheus
df -h

处理方式:缩短数据保留时长;减少采集频率;减少不需要的指标采集。如果确实需要长期保留,考虑配置远程存储把历史数据归档出去。

内存占用高

Prometheus 的内存占用与活跃时间序列数量相关。监控目标或指标维度过多时会明显上升。检查是否有高基数标签(例如把请求 ID 作为标签),这类标签会产生大量时间序列。

八、维护与安全

备份要点

内容

说明

Prometheus 配置与规则

采集配置和告警规则,是核心配置资产

Grafana 数据卷

面板定义、数据源配置、用户账号

指标数据

历史监控数据,可按需决定是否备份

配置文件建议纳入版本管理,改动有记录可追溯。Grafana 的面板也可以导出为 JSON 文件保存。

指标数据是否备份取决于是否需要长期趋势分析。多数场景下丢失历史指标的影响有限,配置反而更重要。

变更前创建快照:升级组件版本前给实例创建快照。回滚会把整块系统盘恢复到快照时间点,之后写入的数据会被清除,运行中的实例会自动关机。使用存储型套餐的实例不支持创建快照。

访问控制

  • 指标接口只对监控服务器放通,不要对公网开放。
  • Prometheus 和 Alertmanager 的界面绑定到本机,通过反向代理并加认证访问。
  • Grafana 关闭开放注册,管理员密码足够强,按需为团队成员创建只读账号。
  • 监控面板会暴露基础设施拓扑和资源水位,属于内部信息,不应公开访问。

日常检查

  • 每周确认所有采集目标健康。
  • 定期审阅告警记录,把噪音告警调整或删除。
  • 关注磁盘水位,及时调整保留策略。
  • 每季度做一次告警链路验证,确认通知渠道仍然有效。通知渠道的配置可能因为对接系统变更而失效。

监控系统自身也需要被监控

这是个容易被忽略的问题:如果 Prometheus 挂了,谁来告警?简单的做法是配置一个外部的可用性检查,定期访问监控服务的健康接口,异常时通过独立渠道通知。至少要保证监控失效时你能知道。

监控搭起来之后,如果需要把日志也纳入统一观测,或为关键业务接口配置更细粒度的可用性监控,可以作为下一步方向。

监控服务需要持续运行且对磁盘容量有一定要求,云服务器 CVM 的规格可按需调整;指标数据增长后可使用云硬盘扩容,历史数据归档可使用对象存储 COS

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

目录
  • 摘要
  • 一、组件职责与数据流
  • 二、资源规划
  • 三、部署监控组件
  • 四、配置告警规则
  • 五、配置 Grafana 面板
  • 六、验证监控是否真正可用
  • 七、常见问题与排查
  • 八、维护与安全
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档