跳转至

第06章 监控告警系统

监控告警系统图

📎 交叉引用(本章侧重基础设施监控,ML模型监控见以下教程): - ML/AI模型监控与数据漂移 → MLOps/监控与持续优化 - LLM服务可观测性 → MLOps/LLM工程化实践

📚 章节概述

本章将深入讲解监控告警系统,包括Prometheus、Grafana、AlertManager等核心组件的配置和使用。通过本章学习,你将能够搭建完整的监控告警系统,实现实时监控和智能告警。

🎯 学习目标

完成本章后,你将能够:

  1. 理解监控系统的核心概念和架构
  2. 掌握Prometheus的配置和使用
  3. 熟练使用Grafana进行可视化
  4. 掌握AlertManager告警配置
  5. 了解Prometheus Exporter的使用
  6. 能够搭建生产级的监控告警系统

6.1 监控系统概述

6.1.1 什么是监控

监控是对系统、应用、网络等进行实时观测,收集指标、日志和追踪数据,及时发现和解决问题。

监控的三大支柱

  1. 指标(Metrics)
  2. 数值型数据
  3. 时间序列
  4. 示例:CPU使用率、内存使用量、请求QPS

  5. 日志(Logs)

  6. 事件记录
  7. 文本数据
  8. 示例:应用日志、访问日志、错误日志

  9. 追踪(Traces)

  10. 请求链路
  11. 分布式追踪
  12. 示例:HTTP请求链路、RPC调用链路

6.1.2 监控的黄金指标

  1. 延迟(Latency)
  2. 请求响应时间
  3. P50、P95、P99延迟
  4. 目标:延迟在可接受范围内

  5. 流量(Traffic)

  6. 请求量
  7. QPS、TPS
  8. 目标:流量稳定,符合预期

  9. 错误(Errors)

  10. 错误率
  11. HTTP 4xx、5xx
  12. 目标:错误率接近0

  13. 饱和度(Saturation)

  14. 资源使用率
  15. CPU、内存、磁盘
  16. 目标:资源使用率在合理范围

6.1.3 监控系统架构

Text Only
┌─────────────┐    ┌─────────────┐    ┌─────────────┐
│  应用服务    │    │  基础设施    │    │  网络设备    │
└──────┬──────┘    └──────┬──────┘    └──────┬──────┘
       │                   │                   │
       │                   │                   │
       └───────────────────┼───────────────────┘
                   ┌───────▼────────┐
                   │  Exporters    │
                   │  (数据采集)     │
                   └───────┬────────┘
                   ┌───────▼────────┐
                   │  Prometheus   │
                   │  (数据存储)     │
                   └───────┬────────┘
                   ┌───────▼────────┐
                   │  AlertManager │
                   │  (告警管理)     │
                   └───────┬────────┘
                   ┌───────▼────────┐
                   │  Grafana      │
                   │  (可视化)      │
                   └───────────────┘

6.2 Prometheus

6.2.1 Prometheus概述

Prometheus是一个开源的监控系统和时间序列数据库。

核心特性

  1. 多维数据模型
  2. 时间序列数据
  3. 键值对标签
  4. 灵活的查询语言

  5. Pull模式

  6. 主动拉取指标
  7. 服务发现
  8. 支持多种协议

  9. 时序数据库

  10. 高效存储
  11. 数据压缩
  12. 长期保留

  13. 告警规则

  14. 灵活的告警配置
  15. 告警分组
  16. 告警抑制

6.2.2 安装Prometheus

Docker安装

Bash
# 拉取Prometheus镜像
docker pull prom/prometheus:latest

# 运行Prometheus
docker run -d \
  --name prometheus \
  -p 9090:9090 \
  -v prometheus-data:/prometheus \
  -v $(pwd)/prometheus.yml:/etc/prometheus/prometheus.yml \  # $()命令替换:执行命令并获取输出
  prom/prometheus:latest \
  --config.file=/etc/prometheus/prometheus.yml \
  --storage.tsdb.path=/prometheus

Kubernetes安装

YAML
apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
  namespace: monitoring          # 监控组件统一部署在monitoring命名空间
data:
  prometheus.yml: |              # 内嵌的Prometheus主配置文件
    global:
      scrape_interval: 15s       # 全局抓取间隔:每15秒拉取一次指标
      evaluation_interval: 15s   # 告警规则评估间隔

    scrape_configs:
    # 任务1:监控Kubernetes API Server
    - job_name: 'kubernetes-apiservers'
      kubernetes_sd_configs:      # 使用K8s服务发现自动发现目标
      - role: endpoints
      scheme: https               # API Server使用HTTPS
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt  # K8s CA证书
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token  # ServiceAccount Token认证
      relabel_configs:            # 标签重写规则:只保留default命名空间的kubernetes服务的https端口
      - source_labels: [__meta_kubernetes_namespace, __meta_kubernetes_service_name, __meta_kubernetes_endpoint_port_name]
        action: keep
        regex: default;kubernetes;https

    # 任务2:监控所有K8s节点(kubelet指标)
    - job_name: 'kubernetes-nodes'
      kubernetes_sd_configs:
      - role: node                # 服务发现角色:node级别
      scheme: https
      tls_config:
        ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
      bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
      relabel_configs:
      - action: labelmap          # 将K8s节点标签映射为Prometheus标签
        regex: __meta_kubernetes_node_label_(.+)

    # 任务3:自动发现并监控Pod(通过Pod注解控制)
    - job_name: 'kubernetes-pods'
      kubernetes_sd_configs:
      - role: pod
      relabel_configs:
      # 只抓取带有 prometheus.io/scrape: "true" 注解的Pod
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
        action: keep
        regex: true
      # 使用Pod注解指定的自定义指标路径
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
        action: replace
        target_label: __metrics_path__
        regex: (.+)
      # 组合Pod IP和注解中指定的端口号,构成抓取地址
      - source_labels: [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
        action: replace
        regex: ([^:]+)(?::\d+)?;(\d+)
        replacement: $1:$2
        target_label: __address__
      # 将Pod标签映射为Prometheus指标标签
      - action: labelmap
        regex: __meta_kubernetes_pod_label_(.+)
      # 记录Pod所属的命名空间
      - source_labels: [__meta_kubernetes_namespace]
        action: replace
        target_label: kubernetes_namespace
      # 记录Pod名称
      - source_labels: [__meta_kubernetes_pod_name]
        action: replace
        target_label: kubernetes_pod_name
---
# Prometheus Deployment:部署Prometheus服务器
apiVersion: apps/v1
kind: Deployment
metadata:
  name: prometheus
  namespace: monitoring
spec:
  replicas: 1                    # 单副本部署(生产可配合Thanos实现高可用)
  selector:
    matchLabels:
      app: prometheus
  template:
    metadata:
      labels:
        app: prometheus
    spec:
      containers:
      - name: prometheus
        image: prom/prometheus:latest
        ports:
        - containerPort: 9090     # Prometheus Web UI和API端口
        volumeMounts:
        - name: config
          mountPath: /etc/prometheus   # 挂载配置文件
        - name: data
          mountPath: /prometheus        # 挂载数据存储目录
        args:
        - '--config.file=/etc/prometheus/prometheus.yml'     # 指定配置文件路径
        - '--storage.tsdb.path=/prometheus'                  # 时序数据库存储路径
        - '--web.console.libraries=/usr/share/prometheus/console_libraries'
        - '--web.console.templates=/usr/share/prometheus/consoles'
        resources:               # 资源限制,防止OOM
          requests:
            memory: "512Mi"       # 最小内存请求
            cpu: "500m"           # 最小CPU请求(0.5核)
          limits:
            memory: "2Gi"         # 内存上限
            cpu: "1000m"          # CPU上限(1核)
      volumes:
      - name: config
        configMap:
          name: prometheus-config  # 引用上面定义的ConfigMap
      - name: data
        persistentVolumeClaim:
          claimName: prometheus-pvc  # 持久化存储,确保Pod重启后数据不丢失
---
# Service:暴露Prometheus服务
apiVersion: v1
kind: Service
metadata:
  name: prometheus
  namespace: monitoring
spec:
  type: LoadBalancer             # 使用负载均衡器类型(云环境自动分配外部IP)
  ports:
  - port: 9090
    targetPort: 9090
  selector:
    app: prometheus
---
# PVC:请求持久化存储卷(保存监控数据)
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: prometheus-pvc
  namespace: monitoring
spec:
  accessModes:
    - ReadWriteOnce              # 单节点读写
  resources:
    requests:
      storage: 50Gi              # 请求50GB存储空间

6.2.3 Prometheus配置

基本配置

YAML
# Prometheus主配置文件
global:
  scrape_interval: 15s           # 全局指标抓取间隔
  evaluation_interval: 15s       # 告警规则评估间隔
  external_labels:               # 外部标签,用于远程写入/联邦时区分集群
    cluster: 'production'
    replica: '1'

# 告警规则文件路径(支持通配符加载多个规则文件)
rule_files:
  - 'alerts/*.yml'

# 抓取配置:定义需要监控的目标
scrape_configs:
  # 监控Prometheus自身指标
  - job_name: 'prometheus'
    static_configs:
      - targets: ['localhost:9090']

  # 监控主机节点(通过Node Exporter采集CPU/内存/磁盘等指标)
  - job_name: 'node_exporter'
    static_configs:
      - targets: ['node1:9100', 'node2:9100', 'node3:9100']  # Node Exporter默认端口9100
        labels:
          env: 'production'      # 添加环境标签,便于按环境筛选

  # 自动发现K8s Pod(基于注解的服务发现)
  - job_name: 'kubernetes-pods'
    kubernetes_sd_configs:
      - role: pod
    relabel_configs:
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
        action: keep
        regex: true              # 只抓取带有scrape注解的Pod

# AlertManager连接配置:告警规则触发后发送到AlertManager
alerting:
  alertmanagers:
    - static_configs:
        - targets:
          - alertmanager:9093     # AlertManager默认端口9093

告警规则配置

YAML
# Prometheus告警规则配置文件
groups:
- name: alert_rules
  interval: 30s                  # 规则评估间隔(30秒检查一次)
  rules:
  # === 实例宕机告警 ===
  # up指标为0表示目标不可达,持续5分钟触发critical级别告警
  - alert: InstanceDown
    expr: up == 0
    for: 5m                      # 持续时间阈值,避免瞬时抖动误报
    labels:
      severity: critical
    annotations:
      summary: "实例 {{ $labels.instance }} 宕机"
      description: "实例 {{ $labels.instance }} 已经宕机超过5分钟"

  # === CPU使用率告警 ===
  # irate计算5分钟内CPU空闲率的瞬时增长率,100减去空闲率得到使用率
  - alert: HighCPUUsage
    expr: 100 - (avg by(instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100) > 80
    for: 10m
    labels:
      severity: warning
    annotations:
      summary: "实例 {{ $labels.instance }} CPU使用率过高"
      description: "实例 {{ $labels.instance }} CPU使用率超过80%,当前值:{{ $value }}%"

  # === 内存使用率告警 ===
  # MemAvailable/MemTotal 计算可用内存比例,1减去即为使用率
  - alert: HighMemoryUsage
    expr: (1 - (node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)) * 100 > 90
    for: 10m
    labels:
      severity: warning
    annotations:
      summary: "实例 {{ $labels.instance }} 内存使用率过高"
      description: "实例 {{ $labels.instance }} 内存使用率超过90%,当前值:{{ $value }}%"

  # === 磁盘使用率告警 ===
  # 排除tmpfs临时文件系统,计算实际磁盘使用率
  - alert: HighDiskUsage
    expr: (1 - (node_filesystem_avail_bytes{fstype!="tmpfs"} / node_filesystem_size_bytes{fstype!="tmpfs"})) * 100 > 85
    for: 10m
    labels:
      severity: warning
    annotations:
      summary: "实例 {{ $labels.instance }} 磁盘使用率过高"
      description: "实例 {{ $labels.instance }} 挂载点 {{ $labels.mountpoint }} 磁盘使用率超过85%,当前值:{{ $value }}%"

  # === HTTP错误率告警 ===
  # rate计算5分钟内HTTP 5xx错误的每秒速率,超过0.05(5%)触发
  - alert: HighHTTPErrorRate
    expr: rate(http_requests_total{status=~"5.."}[5m]) > 0.05
    for: 5m
    labels:
      severity: critical
    annotations:
      summary: "服务 {{ $labels.service }} HTTP错误率过高"
      description: "服务 {{ $labels.service }} HTTP 5xx错误率超过5%,当前值:{{ $value }}"

  # === API响应时间告警 ===
  # histogram_quantile计算P99响应时间,超过1秒触发告警
  - alert: HighAPILatency
    expr: histogram_quantile(0.99, rate(http_request_duration_seconds_bucket[5m])) > 1
    for: 10m
    labels:
      severity: warning
    annotations:
      summary: "服务 {{ $labels.service }} API响应时间过长"
      description: "服务 {{ $labels.service }} P99响应时间超过1秒,当前值:{{ $value }}秒"

6.3 Grafana

6.3.1 Grafana概述

Grafana是一个开源的可视化平台,支持多种数据源。

核心特性

  1. 多数据源支持
  2. Prometheus
  3. InfluxDB
  4. Elasticsearch
  5. MySQL等

  6. 丰富的可视化

  7. 图表、仪表板
  8. 热力图、地图
  9. 自定义插件

  10. 告警功能

  11. 可视化告警
  12. 多种通知渠道
  13. 告警路由

6.3.2 安装Grafana

Docker安装

Bash
# 拉取Grafana镜像
docker pull grafana/grafana:latest

# 运行Grafana
docker run -d \
  --name grafana \
  -p 3000:3000 \
  -v grafana-data:/var/lib/grafana \
  grafana/grafana:latest

Kubernetes安装

YAML
# Grafana Deployment:部署Grafana可视化平台
apiVersion: apps/v1  # apiVersion指定K8s API版本
kind: Deployment  # kind指定资源类型
metadata:
  name: grafana
  namespace: monitoring
spec:  # spec定义资源的期望状态
  replicas: 1
  selector:
    matchLabels:
      app: grafana
  template:
    metadata:
      labels:
        app: grafana
    spec:
      containers:
      - name: grafana
        image: grafana/grafana:latest
        ports:
        - containerPort: 3000       # Grafana Web UI端口
        env:
        # 从 Secret 中读取管理员密码(避免硬编码)
        - name: GF_SECURITY_ADMIN_PASSWORD
          valueFrom:
            secretKeyRef:
              name: grafana-secret
              key: admin-password
        # 自动安装插件(此处安装Redis数据源插件)
        - name: GF_INSTALL_PLUGINS
          value: "redis-datasource"
        volumeMounts:
        - name: data
          mountPath: /var/lib/grafana            # Grafana数据目录(仪表盘、插件等)
        - name: dashboards
          mountPath: /etc/grafana/provisioning/dashboards  # 仪表盘自动加载配置
        - name: datasources
          mountPath: /etc/grafana/provisioning/datasources # 数据源自动加载配置
        resources:
          requests:
            memory: "256Mi"
            cpu: "250m"
          limits:
            memory: "512Mi"
            cpu: "500m"
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: grafana-pvc     # 持久化存储,Pod重启不丢失仪表盘
      - name: dashboards
        configMap:
          name: grafana-dashboards   # 仪表盘配置ConfigMap
      - name: datasources
        configMap:
          name: grafana-datasources  # 数据源配置ConfigMap
---  # YAML文档分隔符
apiVersion: v1
kind: Service
metadata:
  name: grafana
  namespace: monitoring
spec:
  type: LoadBalancer               # 负载均衡器类型,提供外部访问
  ports:
  - port: 3000
    targetPort: 3000
  selector:
    app: grafana
---
# 数据源自动配置(Provisioning):Grafana启动时自动注册Prometheus数据源
apiVersion: v1
kind: ConfigMap
metadata:
  name: grafana-datasources
  namespace: monitoring
data:
  datasources.yml: |
    apiVersion: 1
    datasources:
    - name: Prometheus
      type: prometheus
      access: proxy              # 通过Grafana后端代理访问(而非浏览器直连)
      url: http://prometheus:9090  # K8s集群内服务名称解析
      isDefault: true            # 设为默认数据源
      editable: true
---
# 仪表盘自动加载配置:从json文件自动导入仪表盘
apiVersion: v1
kind: ConfigMap
metadata:
  name: grafana-dashboards
  namespace: monitoring
data:
  dashboards.yml: |
    apiVersion: 1
    providers:
    - name: 'default'
      orgId: 1
      folder: ''
      type: file
      disableDeletion: false
      updateIntervalSeconds: 10    # 每10秒扫描一次新仪表盘文件
      allowUiUpdates: true         # 允许通过UI修改仪表盘
      options:
        path: /var/lib/grafana/dashboards  # 仪表盘JSON文件所在目录
---
# Grafana PVC:持久化存储卷
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: grafana-pvc
  namespace: monitoring
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 10Gi                # Grafana数据存储10GB即可

6.4 练习题

基础题

  1. 选择题
  2. 监控的三大支柱是什么?

    • A. 指标、日志、追踪
    • B. 延迟、流量、错误
    • C. CPU、内存、磁盘
    • D. 告警、可视化、存储
  3. 简答题

  4. 解释Prometheus的Pull模式。
  5. 说明Grafana的核心功能。

进阶题

  1. 实践题
  2. 搭建一个完整的Prometheus监控系统。
  3. 配置Grafana仪表板。
  4. 配置告警规则。

  5. 设计题

  6. 设计一个生产级的监控架构。
  7. 设计一个多环境监控方案。

答案

1. 选择题答案

  1. A(监控的三大支柱是指标、日志、追踪)

2. 简答题答案

Prometheus的Pull模式: - Prometheus主动从目标拉取指标 - 支持服务发现 - 灵活的配置

Grafana的核心功能: - 多数据源支持 - 丰富的可视化 - 告警功能

3. 实践题答案

参见6.2-6.3节的示例。

4. 设计题答案

参见6.1-6.3节的架构设计。

6.5 面试准备

大厂面试题

字节跳动

  1. 解释监控的黄金指标。
  2. Prometheus的数据模型是什么?
  3. 如何设计告警规则?
  4. 如何优化Prometheus性能?

腾讯

  1. Grafana的数据源有哪些?
  2. 如何实现监控数据的长期存储?
  3. 如何处理告警风暴?
  4. 如何设计监控大盘?

阿里云

  1. Prometheus的存储机制是什么?
  2. 如何实现分布式监控?
  3. 如何监控Kubernetes集群?
  4. 如何设计监控告警策略?

📚 参考资料

🎯 本章小结

本章深入讲解了监控告警系统,包括:

  1. 监控系统的核心概念和架构
  2. Prometheus的配置和使用
  3. Grafana的可视化
  4. 告警规则的配置
  5. 完整的实战案例

通过本章学习,你掌握了监控告警的核心技术,能够搭建生产级的监控系统。下一章将深入学习日志管理系统。