第一篇:认识 Prometheus ------ 云原生监控的基础
我最近在折腾 K8s 集群,装好之后第一个让我犯难的问题不是部署,而是监控:这么多 Pod 天天来来回回,到底怎么监控?
这一篇就是我把这件事从头想明白的记录。
一、传统监控为什么在云原生环境里失灵
先看传统监控是怎么玩的。
以前的世界很单纯:机器就那么几台,IP 固定,装一个监控 Agent,然后在监控平台里手动把每台机器配好。像 Nagios、Zabbix 那套,大概是这么个结构:
服务器 → 监控 Agent → 监控平台
配一次就完事。因为机器不跑不跳,配置是静态的。
但 K8s 里的世界完全不是这样。Pod 随时在创建、销毁、扩容、缩容,今天这个节点上跑 3 个副本,明天可能变成 8 个。IP 是动态分配的,这分钟一个样,下分钟又一个样:
Pod Pod Pod (不断创建、销毁)
↑ ↑ ↑
节点 节点 节点
这带来一个很朴素的问题:监控对象本身一直在变,你没法靠"人工写死配置"去盯它。
打个比方,传统监控像校医对着固定班级点名册,谁病了翻名字就行;云原生环境里,"学生"会凭空冒出来又消失,点名册根本来不及更新。所以监控系统要能在云原生环境下活下去,靠的不是"配置得多全",而是两个能力:
自动发现 + 自动采集
不靠人去登记,让系统自己找到新目标、自己去采集数据。

二、Prometheus 从哪里来
Prometheus 是 SoundCloud 在 2012 年为了解决自家微服务架构的监控问题开发的,2015 年开源,2016 年加入 CNCF ------ 是继 Kubernetes 之后第二个加入 CNCF 的项目,2018 年正式毕业(graduated)。
我特意查了这个背景,因为它解释了 Prometheus 为什么长这样:它不是先有通用监控的需求再硬套云原生的,而是从诞生起就在为"服务不断变化"的环境而设计。 所以它的核心思路天然贴合 K8s,而不是像传统监控那样靠补丁去适配。
三、核心设计:它是"拉"数据的,不是"推"数据的
我第一次看 Prometheus 架构时,最大的认知冲击是:它居然是**拉(pull)的,不是推(push)**的。
传统监控通常是 Agent 主动把数据推到监控平台。Prometheus 反过来------它自己定时去目标那里"取"。
打个比方:这像便利店总部盘点库存。传统做法是每家分店主动打电话来报数(push);Prometheus 的做法是总部派人定期上门盘点(pull)。上门盘点有个额外好处------总部亲眼看到哪家店还开着、哪家已经关门了。
机制层面是这样的:Prometheus 服务端每隔一段时间,向目标的 HTTP 接口(约定俗成是 /metrics)发一次 GET 请求。目标什么都不用知道,只要把这个接口暴露出来,返回一段纯文本格式的指标数据就行。
这个"拉"的设计带来两个连锁好处,正好解决云原生的问题:
-
目标不需要知道监控方在哪、有几个。 它只管把
/metrics接口开着。于是新起一个 Pod 很自然------Prometheus 通过服务发现(比如看 K8s 的 API)找到它,然后去拉。Pod 挂了就拉不到,拉不到就在列表里自然消失,全程不需要人手动加配置、删配置。 -
监控方对"目标死活"有第一手判断。 push 模式下,一个目标死掉了,它的数据就停了,但你也分不清它到底是"没数据可报"还是"已经死了"。pull 模式下,每次拉取成功或失败 Prometheus 自己清清楚楚,还专门有一个
up指标记录"最近一次拉取成不成功",是 1 还是 0。谁挂了,一眼就能看出来。
这就是"自动发现 + 自动采集"能成立的根本原因。
四、指标长什么样
Prometheus 监控的数据叫 Metric(指标)。一条指标长这样:
指标名{标签=值} 数值
拿最常见的例子:
node_cpu_seconds_total{cpu="0",mode="user"} 1234.56
拆开看:
- 指标名
node_cpu_seconds_total:说明这是什么数据。node-exporter 把 Linux 系统的指标翻译出来,这就是"CPU 累计运行了多少秒"。 - 标签
cpu="0", mode="user":把这条数据切得更细。同一个指标名,不同标签组合就是不同的记录。看整体看单核、看用户态还是看系统态,都由标签决定。 - 数值
1234.56:真实的值。
标签(label)是我一开始最没当回事、后来发现最核心的设计。它让一条指标变成多维 的:我既想看整台节点的 CPU,也想只挑 cpu="0" 那颗核,还想按 mode="user" 只看用户态占比------用 PromQL 查的时候按标签筛选就行,不用为每种维度单独发明一个指标名。
再比如内存:
node_memory_MemAvailable_bytes 8589934592
或者你自己写的服务:
http_requests_total{method="GET"} 1000
(机制收尾)我一开始以为标签只是"备注",后来才意识到它是身份的组成部分。Prometheus 内部把"指标名 + 标签组合"当成这条时间序列的唯一标识。标签写错了,就成了另一条指标,所以命名要规范,别随手写。
五、整体架构:四个角色
官方架构图很复杂,但第一篇里抓住四个角色就够:
Grafana(展示)
↑
Prometheus(存储 + 查询)
↑ 定时拉取
┌────────┴────────┐
│ │
node-exporter 你的应用 /metrics
│
Linux 系统
- Prometheus:主角。定时去拉指标,存进自己的时序数据库(TSDB),并提供 PromQL 查询。数据从哪来到哪去,都围着它转。
- Exporter :很多程序本身不会暴露 Prometheus 格式的指标,所以需要一个小工具把"系统或程序的状态"翻译成
/metrics接口。node-exporter 就是干这个的------它把 Linux 系统的 CPU、内存、磁盘状态翻译成上面那种格式。 - Grafana:Prometheus 自带的图表很朴素,它主要负责存和查。Grafana 专门把数据画成漂亮的仪表盘,两者是黄金搭档。
- Alertmanager:光监控不告警等于没监控。Prometheus 里配告警规则,触发后交给 Alertmanager 去发通知(邮件、钉钉那些)。这是后面的话题了。
另外补一句:图里漏了一个"拉不到"的场景------像一次性批处理任务,跑完就消失,Prometheus 来不及拉。官方给了一个叫 Pushgateway 的东西专门收这种短命任务推来的数据。先记个名字,以后单独讲。
六、这一篇的复盘
想明白的三件事:
- 云原生监控的核心矛盾是监控对象一直在变,所以关键能力是自动发现 + 自动采集。
- Prometheus 用"拉"的模型解决了这个矛盾:目标只暴露
/metrics接口,Prometheus 主动来取,谁死谁活它自己最清楚。 - 指标 = 指标名 + 标签 + 数值,标签是多维查询的钥匙。
还留着、准备下一篇解决的困惑:
- 指标名后面那个
_total后缀是什么意思?它好像和"一直在涨"有关。 - 四种指标类型 Counter、Gauge、Histogram、Summary 到底啥区别?
- PromQL 怎么写,才能查出"最近 5 分钟的 CPU 使用率"?
(2026-08-24,在 WSL2 上折腾 K8s 集群时)