第06章 监控告警系统¶
📎 交叉引用(本章侧重基础设施监控,ML模型监控见以下教程): - ML/AI模型监控与数据漂移 → MLOps/监控与持续优化 - LLM服务可观测性 → MLOps/LLM工程化实践
📚 章节概述¶
本章将深入讲解监控告警系统,包括Prometheus、Grafana、AlertManager等核心组件的配置和使用。通过本章学习,你将能够搭建完整的监控告警系统,实现实时监控和智能告警。
🎯 学习目标¶
完成本章后,你将能够:
- 理解监控系统的核心概念和架构
- 掌握Prometheus的配置和使用
- 熟练使用Grafana进行可视化
- 掌握AlertManager告警配置
- 了解Prometheus Exporter的使用
- 能够搭建生产级的监控告警系统
6.1 监控系统概述¶
6.1.1 什么是监控¶
监控是对系统、应用、网络等进行实时观测,收集指标、日志和追踪数据,及时发现和解决问题。
监控的三大支柱¶
- 指标(Metrics)
- 数值型数据
- 时间序列
-
示例:CPU使用率、内存使用量、请求QPS
-
日志(Logs)
- 事件记录
- 文本数据
-
示例:应用日志、访问日志、错误日志
-
追踪(Traces)
- 请求链路
- 分布式追踪
- 示例:HTTP请求链路、RPC调用链路
6.1.2 监控的黄金指标¶
- 延迟(Latency)
- 请求响应时间
- P50、P95、P99延迟
-
目标:延迟在可接受范围内
-
流量(Traffic)
- 请求量
- QPS、TPS
-
目标:流量稳定,符合预期
-
错误(Errors)
- 错误率
- HTTP 4xx、5xx
-
目标:错误率接近0
-
饱和度(Saturation)
- 资源使用率
- CPU、内存、磁盘
- 目标:资源使用率在合理范围
6.1.3 监控系统架构¶
Text Only
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 应用服务 │ │ 基础设施 │ │ 网络设备 │
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ │ │
│ │ │
└───────────────────┼───────────────────┘
│
┌───────▼────────┐
│ Exporters │
│ (数据采集) │
└───────┬────────┘
│
┌───────▼────────┐
│ Prometheus │
│ (数据存储) │
└───────┬────────┘
│
┌───────▼────────┐
│ AlertManager │
│ (告警管理) │
└───────┬────────┘
│
┌───────▼────────┐
│ Grafana │
│ (可视化) │
└───────────────┘
6.2 Prometheus¶
6.2.1 Prometheus概述¶
Prometheus是一个开源的监控系统和时间序列数据库。
核心特性¶
- 多维数据模型
- 时间序列数据
- 键值对标签
-
灵活的查询语言
-
Pull模式
- 主动拉取指标
- 服务发现
-
支持多种协议
-
时序数据库
- 高效存储
- 数据压缩
-
长期保留
-
告警规则
- 灵活的告警配置
- 告警分组
- 告警抑制
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是一个开源的可视化平台,支持多种数据源。
核心特性¶
- 多数据源支持
- Prometheus
- InfluxDB
- Elasticsearch
-
MySQL等
-
丰富的可视化
- 图表、仪表板
- 热力图、地图
-
自定义插件
-
告警功能
- 可视化告警
- 多种通知渠道
- 告警路由
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 练习题¶
基础题¶
- 选择题
-
监控的三大支柱是什么?
- A. 指标、日志、追踪
- B. 延迟、流量、错误
- C. CPU、内存、磁盘
- D. 告警、可视化、存储
-
简答题
- 解释Prometheus的Pull模式。
- 说明Grafana的核心功能。
进阶题¶
- 实践题
- 搭建一个完整的Prometheus监控系统。
- 配置Grafana仪表板。
-
配置告警规则。
-
设计题
- 设计一个生产级的监控架构。
- 设计一个多环境监控方案。
答案¶
1. 选择题答案¶
- A(监控的三大支柱是指标、日志、追踪)
2. 简答题答案¶
Prometheus的Pull模式: - Prometheus主动从目标拉取指标 - 支持服务发现 - 灵活的配置
Grafana的核心功能: - 多数据源支持 - 丰富的可视化 - 告警功能
3. 实践题答案¶
参见6.2-6.3节的示例。
4. 设计题答案¶
参见6.1-6.3节的架构设计。
6.5 面试准备¶
大厂面试题¶
字节跳动¶
- 解释监控的黄金指标。
- Prometheus的数据模型是什么?
- 如何设计告警规则?
- 如何优化Prometheus性能?
腾讯¶
- Grafana的数据源有哪些?
- 如何实现监控数据的长期存储?
- 如何处理告警风暴?
- 如何设计监控大盘?
阿里云¶
- Prometheus的存储机制是什么?
- 如何实现分布式监控?
- 如何监控Kubernetes集群?
- 如何设计监控告警策略?
📚 参考资料¶
- Prometheus官方文档:https://prometheus.io/docs/
- Grafana官方文档:https://grafana.com/docs/
- AlertManager文档:https://prometheus.io/docs/alerting/latest/alertmanager/
- 《Prometheus监控实战》
- 《Grafana可视化指南》
🎯 本章小结¶
本章深入讲解了监控告警系统,包括:
- 监控系统的核心概念和架构
- Prometheus的配置和使用
- Grafana的可视化
- 告警规则的配置
- 完整的实战案例
通过本章学习,你掌握了监控告警的核心技术,能够搭建生产级的监控系统。下一章将深入学习日志管理系统。