容器资源指标采集原理
在构建容器容量预警规则之前,必须深入理解指标数据的来源与采集机制。本章聚焦三个核心采集路径:cAdvisor 的容器级指标暴露、kubelet 内置的指标聚合端点,以及 Node Exporter 与容器指标的本质差异。只有厘清这些原理,才能设计出精准、无歧义的 PromQL 预警表达式。
3.1 cAdvisor 工作原理
cAdvisor(Container Advisor)是 Google 开源的容器资源使用分析工具,自 Kubernetes 1.2 起被直接集成到 kubelet 中。它通过读取 Linux cgroups 和 namespace 信息,实时采集每个容器的 CPU、内存、网络、磁盘 IO 等指标。
3.1.1 关键指标类型
| 资源类别 | 典型指标名(Prometheus 格式) | 数据来源 |
|---|---|---|
| CPU | container_cpu_usage_seconds_total |
/sys/fs/cgroup/cpuacct/cpuacct.usage |
| 内存 | container_memory_working_set_bytes |
/sys/fs/cgroup/memory/memory.usage_in_bytes |
| 网络 | container_network_receive_bytes_total |
/proc/net/dev 按容器网络命名空间隔离 |
| 磁盘 IO | container_fs_reads_bytes_total |
/sys/fs/cgroup/blkio/blkio.throttle.io_service_bytes |
| 文件系统 | container_fs_usage_bytes |
容器镜像层与可写层 overlay 文件系统统计 |
3.1.2 采集周期与缓存
cAdvisor 默认以 10 秒 为间隔从 cgroups 读取原始计数器,并在内存中保留最近 2 分钟的历史样本。这意味着 Prometheus 拉取时获取的是瞬时快照,而非实时流。对于容量预警,建议使用 rate() 或 irate() 函数计算每秒变化率,以消除采样抖动。
container_cpu_usage_seconds_total 是累计计数器,直接使用 avg() 聚合会得到错误结果。必须配合 rate() 或 increase() 函数使用。
3.2 kubelet 内置指标暴露
kubelet 作为 Kubernetes 节点代理,内置了 cAdvisor 实例,并通过以下两个端点对外暴露容器指标:
/metrics/cadvisor:直接透传 cAdvisor 的原始容器指标,包含完整的容器级标签(pod、namespace、container 等)。/metrics/resource:Kubernetes 1.18+ 引入的优化端点,仅暴露 Pod 级别的资源指标(CPU、内存),减少标签基数,适合大规模集群。
Prometheus 通过 kubernetes_sd_configs 自动发现 kubelet 目标时,通常配置两个采集任务:
# 采集完整容器指标(用于详细诊断)
- job_name: 'kubelet-cadvisor'
kubernetes_sd_configs:
- role: node
relabel_configs:
- source_labels: [__meta_kubernetes_node_name]
target_label: node
metric_path: /metrics/cadvisor
# 采集精简资源指标(用于容量预警)
- job_name: 'kubelet-resource'
kubernetes_sd_configs:
- role: node
metric_path: /metrics/resource
/metrics/resource 端点,其指标基数更低,Prometheus 内存占用更小;排查单个容器异常时再回退到 /metrics/cadvisor。
3.3 Node Exporter 与容器指标的差异
Node Exporter 是 Prometheus 生态中用于采集宿主机级别指标的组件。很多 SRE 新手会混淆 Node Exporter 指标与 cAdvisor 指标,导致预警规则误判。下表列出核心差异:
| 对比维度 | Node Exporter | cAdvisor / kubelet |
|---|---|---|
| 采集范围 | 宿主机整体(所有进程共享) | 单个容器或 Pod(cgroup 隔离) |
| CPU 指标 | node_cpu_seconds_total(按 mode 分) |
container_cpu_usage_seconds_total(按容器分) |
| 内存指标 | node_memory_MemTotal_bytes / MemAvailable_bytes |
container_memory_working_set_bytes / container_memory_rss |
| 网络指标 | node_network_receive_bytes_total(宿主机网卡) |
container_network_receive_bytes_total(容器 veth 对) |
| 磁盘指标 | node_disk_io_time_seconds_total(物理磁盘) |
container_fs_io_time_seconds_total(容器文件系统) |
| 适用场景 | 节点容量规划、硬件故障检测 | 容器资源限制、Pod 水平扩缩容、预警 |
node_memory_MemAvailable_bytes 判断容器内存是否充足。容器内存受 cgroup 限制和 page cache 共享影响,必须使用 container_memory_working_set_bytes 作为预警依据。
3.4 采集架构总览
下图展示了从容器运行时到 Prometheus 的完整指标采集链路:
3.5 Node Exporter 与容器指标的对比图
为了更直观地理解两者在内存指标上的差异,下图展示了同一台宿主机上 Node Exporter 和 cAdvisor 对内存视图的不同呈现:
3.6 采集原理对预警设计的影响
理解上述原理后,在设计容量预警规则时需注意以下要点:
- 指标延迟: cAdvisor 采集周期为 10 秒,Prometheus 默认拉取间隔为 15 秒,预警评估窗口建议 ≥ 1 分钟,避免因采样错位产生误报。
- 标签基数:
/metrics/cadvisor会为每个容器生成大量时间序列(每个容器约 50+ 指标),大规模集群建议使用/metrics/resource或通过 relabel 过滤非必要容器。 - 计数器 vs 仪表盘: CPU 指标是计数器(counter),必须用
rate()转换;内存指标是仪表盘(gauge),可直接聚合。 - 容器重启影响: 容器重启后 cAdvisor 指标会重置,预警规则中应使用
rate()配合increase()避免重启瞬间的尖刺。
/metrics/resource 端点,配合 container_memory_working_set_bytes 和 rate(container_cpu_usage_seconds_total) 作为基础指标。Node Exporter 仅用于节点级别的容量规划,不可直接用于容器预警。