2. 监控体系架构:Pull vs Push模型、时间序列数据库原理、多维数据模型与标签设计

2.1 Pull vs Push 模型:架构选择与适用场景

Prometheus 采用 Pull(拉取) 模型作为核心数据采集方式,这与传统的 Push(推送)模型在架构设计、运维复杂度和故障隔离能力上存在本质差异。理解两者的区别是设计可靠监控体系的基础。

对比维度 Pull 模型(Prometheus 默认) Push 模型(传统方案)
数据流向 监控系统主动连接目标端点拉取指标 被监控对象主动向中央收集器发送数据
故障检测 拉取超时或失败可立即判定目标不可达 数据缺失难以区分是故障还是延迟推送
配置复杂度 中心化配置,只需维护 targets 列表 每个被监控端需配置接收端地址和认证
网络要求 监控端需路由可达所有目标 被监控端需路由可达收集器
扩展性 通过服务发现自动扩缩,适合动态环境 需手动管理推送端,扩容时易遗漏
数据一致性 拉取时间由监控端控制,采样间隔稳定 推送时间由被监控端控制,可能突发拥塞
控制面场景建议: 控制面组件(如 kube-apiserver、etcd、kube-scheduler)均暴露 /metrics 端点,天然适配 Pull 模型。使用 Prometheus 的 kubernetes_sd_configs 自动发现所有控制面 Pod,无需在组件侧做任何推送配置。

Pull 模型并非万能。对于短生命周期任务(如 Job、CronJob)或位于防火墙后的遗留系统,Prometheus 提供了 Pushgateway 作为补充。Pushgateway 作为中间代理接收临时任务的推送数据,再由 Prometheus 从 Pushgateway 拉取。

Pushgateway 使用限制: Pushgateway 不是聚合器,也不是高可用存储。它仅用于无法直接 Pull 的场景。滥用 Pushgateway 会导致单点故障和指标延迟,控制面监控中应优先使用原生 Pull。
Pull vs Push 监控架构对比 Pull 模型(Prometheus) Prometheus Server Target A (exporter) Target B (exporter) Target C (exporter) Prometheus 主动拉取 /metrics 采样间隔由 Server 控制 故障立即感知(超时/错误) 服务发现自动管理 targets Push 模型(传统方案) 中央收集器 Agent 1 Agent 2 Agent 3 Agent 主动推送数据 推送间隔由 Agent 控制 故障检测依赖心跳超时 需手动管理 Agent 配置

2.2 时间序列数据库原理:存储结构与写入路径

Prometheus 内置的 TSDB(时间序列数据库)是其高性能查询的核心。理解 TSDB 的存储原理,有助于在控制面高基数场景下进行调优。

2.2.1 核心概念

  • Sample(样本): 时间序列中的单个数据点,由 timestamp(毫秒精度)和 value(float64)组成。
  • Series(序列): 由 Metric Name + Labels 唯一标识的一组有序样本。例如 http_requests_total{method="GET", endpoint="/api/v1"} 是一个序列。
  • Block(数据块): TSDB 将数据按时间窗口切分为不可变的 block,每个 block 包含该时间窗口内的所有样本数据。

2.2.2 写入路径与压缩机制

  1. WAL(Write-Ahead Log): 所有写入先追加到 WAL,保证崩溃恢复不丢数据。
  2. Head Block(内存块): 最近的数据暂存在内存中的 Head Block,支持快速查询最新数据。
  3. 压缩与持久化: 当 Head Block 达到阈值(默认 2 小时),TSDB 将其压缩为不可变的持久化 block,并写入磁盘。
  4. 合并(Compaction): 后台定期合并较小的 block 为更大的 block,减少文件数量,提升查询效率。
控制面调优要点: 控制面组件(特别是 kube-apiserver 和 etcd)会产生大量高基数序列(如每个 Pod 的请求指标)。建议监控 prometheus_tsdb_head_series 指标,若超过 1000 万,需考虑调整 --storage.tsdb.retention.time 或启用 --storage.tsdb.retention.size 限制。
Prometheus TSDB 写入与压缩流程 Scrape 数据 WAL Head Block 持久化 Block Compaction 合并后大 Block 关键参数 --storage.tsdb.retention.time=15d | --storage.tsdb.retention.size=50GB | --storage.tsdb.min-block-duration=2h

2.3 多维数据模型与标签设计:从指标到黄金信号

Prometheus 的数据模型是 多维的。每个指标(Metric)可以附加任意数量的标签(Label),标签的键值对组合构成了不同的时间序列。这种设计使得查询可以沿任意维度进行聚合、过滤和分组。

2.3.1 指标命名规范

  • 基础格式: <namespace>_<subsystem>_<unit>[_<suffix>]
  • 示例: kubelet_node_config_error、etcd_server_leader_changes_seen_total
  • 控制面常用命名空间: kube_(Kubernetes 组件)、etcd_、apiserver_、scheduler_、controller_manager_

2.3.2 标签设计原则

原则 说明 控制面示例
可区分性 标签应能唯一标识一个监控对象 instance="10.0.1.5:10250"
可聚合性 标签值应支持按业务维度分组 node="node-01"、zone="us-east-1"
基数控制 避免标签值无限增长(如 Pod Name、User ID) 使用 namespace 而非 pod 作为聚合标签
一致性 同一类资源使用相同的标签键 所有控制面组件统一使用 component 标签
高基数陷阱: 控制面中 kube_pod_info 或 kube_deployment_status_replicas 等指标如果附加了 uid 或 pod_ip 标签,会导致序列数量爆炸。在 Prometheus 配置中通过 metric_relabel_configs 丢弃不必要的标签,是控制面监控的必备操作。

2.3.3 标签在查询中的应用

多维模型使得 PromQL 可以灵活地沿标签进行切片和聚合:

# 查询所有控制面组件的内存使用量,按组件分组
sum(process_resident_memory_bytes{job=~"kube-.*"}) by (job)

# 查询 etcd 集群中每个节点的 leader 变更次数
etcd_server_leader_changes_seen_total{cluster="prod"}

# 计算 apiserver 请求错误率(按资源类型)
sum(rate(apiserver_request_total{code=~"5.."}[5m])) by (resource)
标签设计检查清单:
  • 每个指标至少包含 job 和 instance 标签。
  • 控制面组件额外添加 component、cluster 标签。
  • 避免在标签值中使用随机字符串、UUID、Pod 全名。
  • 使用 __meta_kubernetes_* 标签进行服务发现时,只保留必要的标签。
Prometheus 多维数据模型结构 Metric: http_requests_total method="GET" endpoint="/api/v1" status="200" Series: http_requests_total{method="GET", endpoint="/api/v1", status="200"} t=1000, v=42 t=2000, v=45 t=3000, v=48 t=4000, v=53