4、监控系统部署:Prometheus+Grafana监控栈搭建、Exporter开发、告警规则配置

好,咱们进入实战环节。这一章我打算把PTN网络的监控系统完整地搭起来。说白了,就是让Prometheus当数据采集员,Grafana当仪表盘画师,再配上我们自己写的Exporter,最后把告警规则一配——一套能用的监控栈就齐活了。

我在多个运营商的项目里都这么干过,这套组合拳打下来,PTN网络的流量、时延、丢包率基本都能实时看到。嗯,咱们一步步来。

4.1 Prometheus + Grafana 基础部署

先装Prometheus。我个人习惯用Docker部署,省心、干净、好迁移。你想想看,要是每台机器都手动装一遍,那得多累。

# docker-compose.yml 示例
version: '3.8'
services:
  prometheus:
    image: prom/prometheus:latest
    container_name: prometheus
    volumes:
      - ./prometheus.yml:/etc/prometheus/prometheus.yml
      - ./data:/prometheus
    ports:
      - "9090:9090"
    command:
      - '--config.file=/etc/prometheus/prometheus.yml'
      - '--storage.tsdb.retention.time=30d'

  grafana:
    image: grafana/grafana:latest
    container_name: grafana
    ports:
      - "3000:3000"
    environment:
      - GF_SECURITY_ADMIN_PASSWORD=admin123
    volumes:
      - ./grafana-data:/var/lib/grafana

Prometheus的配置文件是关键。你得告诉它去哪抓数据。这里我踩过一个坑——抓取间隔设得太短,结果把PTN设备的CPU打满了。后来我改成15秒一次,稳得很。

# prometheus.yml
global:
  scrape_interval: 15s
  evaluation_interval: 15s

scrape_configs:
  - job_name: 'ptn_exporter'
    static_configs:
      - targets: ['192.168.1.100:9100']
        labels:
          group: 'ptn-devices'
小提示:Grafana第一次登录默认账号是admin/admin,记得改密码。我一般会先配好Prometheus数据源,再导入现成的PTN仪表盘模板。

4.2 Exporter 开发实战

Prometheus自己没法直接读懂PTN设备的SNMP数据,所以得写个Exporter做翻译。说白了,Exporter就是个中间人——它去设备上抓数据,然后转成Prometheus能吃的格式。

我推荐用Python写,快。下面这个例子,是我从一个真实项目中抽出来的核心代码。它通过SNMP采集PTN设备的端口流量。

# ptn_exporter.py
from prometheus_client import start_http_server, Gauge
import time
import subprocess

# 定义指标
port_rx_bytes = Gauge('ptn_port_rx_bytes', '接收字节数', ['device', 'port'])
port_tx_bytes = Gauge('ptn_port_tx_bytes', '发送字节数', ['device', 'port'])

def collect_snmp_data(device_ip, community='public'):
    """通过SNMP采集端口流量"""
    oid_if_in_octets = '1.3.6.1.2.1.2.2.1.10'
    oid_if_out_octets = '1.3.6.1.2.1.2.2.1.16'
    
    # 用snmpwalk获取数据
    result = subprocess.run(
        ['snmpwalk', '-v2c', '-c', community, device_ip, oid_if_in_octets],
        capture_output=True, text=True
    )
    
    for line in result.stdout.split('\n'):
        if line:
            # 解析SNMP响应
            parts = line.split('=')
            if len(parts) == 2:
                port_index = parts[0].split('.')[-1]
                value = int(parts[1].strip().split()[0])
                port_rx_bytes.labels(device=device_ip, port=port_index).set(value)

if __name__ == '__main__':
    start_http_server(9100)
    while True:
        collect_snmp_data('192.168.1.1')
        time.sleep(15)
注意:我曾经在生产环境里直接用Python的pysnmp库,结果发现性能不行。后来改用subprocess调snmpwalk,反而更稳定。原因嘛——snmpwalk是C写的,快。

4.3 告警规则配置

数据有了,仪表盘有了,但你不能24小时盯着屏幕吧?告警才是监控的灵魂。Prometheus的告警规则用YAML写,语法很直观。

我一般把告警分成三级:信息、警告、严重。比如端口流量超过80%带宽就警告,超过95%就严重。下面是我常用的规则。

# alert_rules.yml
groups:
  - name: ptn_alerts
    rules:
      - alert: PortBandwidthHigh
        expr: |
          rate(ptn_port_rx_bytes[5m]) / 1000000000 > 0.8
        for: 5m
        labels:
          severity: warning
        annotations:
          summary: "端口 {{ $labels.port }} 带宽使用率超过80%"
          description: "设备 {{ $labels.device }} 端口 {{ $labels.port }} 当前带宽使用率 {{ $value | humanizePercentage }}"

      - alert: PortBandwidthCritical
        expr: |
          rate(ptn_port_rx_bytes[5m]) / 1000000000 > 0.95
        for: 2m
        labels:
          severity: critical
        annotations:
          summary: "端口 {{ $labels.port }} 带宽使用率超过95%"
          description: "立即检查!设备 {{ $labels.device }} 端口 {{ $labels.port }} 已接近满载"
关键点:告警规则里的for字段很重要。它表示持续多长时间才触发告警。我建议设5分钟以上,避免网络抖动导致的误报。你想想看,要是半夜被一个假告警吵醒,那多闹心。

4.4 集成测试与验证

所有组件都部署好了,怎么验证?我有个习惯——先手动触发一个告警,看看能不能收到通知。比如用curl模拟高流量数据。

# 模拟高流量,触发告警
curl -X POST http://localhost:9100/metrics \
  -d 'ptn_port_rx_bytes{device="192.168.1.1",port="1"} 950000000'

然后去Grafana的Alerting页面看,告警状态应该从pending变成firing。嗯,这里要注意——Prometheus的告警状态机:pending表示条件满足但还没到持续时间,firing才是真正触发。

我曾在一次割接中,因为忘了配告警接收人,结果设备挂了半小时没人知道。从那以后,我每次部署完都会做一次端到端测试:从数据采集到告警通知,全链路走一遍。

4.5 避坑指南

最后,分享几个我踩过的坑,你遇到了能少走弯路。

  • 时间不同步:Prometheus和PTN设备的时间必须一致。我遇到过因为NTP没配,导致数据对不上的情况。解决办法:所有设备统一用NTP服务器同步。
  • SNMP版本:PTN设备大多支持v2c,但有些老设备只支持v1。我建议统一用v2c,性能好,安全性也还行。
  • 数据存储:Prometheus默认存15天。如果你需要长期保存,要么调大retention时间,要么用Thanos做远端存储。我个人习惯保留30天,够用了。
  • 告警风暴:别把所有告警都设成严重级别。我曾经一次割接触发了200多条告警,手机都快炸了。后来我按优先级分级,关键告警才发短信。

好了,这一章的内容就到这。Prometheus+Grafana这套栈,说白了就是三个步骤:搭环境、写Exporter、配告警。你按这个顺序来,基本不会出大问题。下一章咱们聊聊流量分析的高级玩法,比如如何识别异常流量模式。