4. 容器级成本采集架构:cAdvisor、Metrics Server、Prometheus 采集 CPU/内存/网络/存储的架构设计

容器级成本分摊的精度取决于底层指标采集链路的可靠性。本章深入剖析从 cAdvisor 原始数据暴露、Metrics Server 聚合采样,到 Prometheus 拉取与存储的完整架构,并针对 CPU、内存、网络、存储四类资源的采集路径与常见故障点进行拆解。

4.1 四层采集架构总览

容器资源指标采集遵循“节点代理 → 聚合缓存 → 时序存储 → 成本计算”的分层模型。每一层承担不同的职责,也对应不同的故障模式。

核心原则:成本分摊的准确性不会超过原始采集数据的精度。采集链路上任何一层的丢点、延迟或精度截断,都会直接导致分摊账单出现偏差。
层级 组件 核心职责 数据粒度 常见故障
L1 节点代理 cAdvisor (内嵌于 kubelet) 从 cgroup 读取原始容器资源使用量 容器级 / 15s 窗口 cgroup 统计遗漏、磁盘统计缺失
L2 聚合缓存 Metrics Server 采集节点指标并聚合为 Pod 级 Resource Metrics Pod 级 / 15s~60s 资源配额不足导致 OOM、节点不可达
L3 时序存储 Prometheus (Server + kubelet/cadvisor 目标) 拉取、存储、查询历史指标 容器级 / 采集间隔可配置 拉取超时、样本重复、存储膨胀
L4 成本计算 成本引擎 (基于 Prometheus 数据) 按 CPU/内存/网络/存储单价计算分摊金额 容器级 / 小时或天聚合 标签缺失、单价映射错误
容器级成本采集四层架构 L1 节点代理 — cAdvisor (内嵌 kubelet) 读取 cgroup cpuacct / memory.stat / blkio / net 原始计数器 暴露 /metrics/cadvisor 端点,15s 窗口滚动 L2 聚合缓存 — Metrics Server 调用 kubelet /metrics/resource 接口,聚合为 Pod 级 Resource Metrics 缓存周期 60s,用于 HPA / kubectl top L3 时序存储 — Prometheus Server 配置 scrape_config 拉取 kubelet /metrics/cadvisor 及 /metrics/resource 存储容器级 CPU / 内存 / 网络 / 磁盘时序数据 L4 成本计算 — 成本分摊引擎 PromQL 查询容器资源使用量 × 单价模型 → 按命名空间/标签/服务分摊 输出容器级成本明细表,对接 FinOps 仪表盘

4.2 CPU 与内存采集路径

CPU 和内存是成本分摊中最核心的两类资源。它们的采集路径有显著差异,故障表现也各不相同。

4.2.1 CPU 采集:从 cgroup 到 Prometheus

  • 原始数据源:/sys/fs/cgroup/cpu,cpuacct/cpuacct.usage — 纳秒级累计计数器。
  • cAdvisor 处理:计算 delta(cpuacct.usage) / delta(time) / 核数,得到 CPU 使用率(小数)。
  • Prometheus 指标:container_cpu_usage_seconds_total{container="...", pod="..."}。
  • 成本计算:使用 rate(container_cpu_usage_seconds_total[5m]) 转换为每秒使用量,乘以 CPU 单价。
常见故障:当容器设置 CPU quota 且 CFS 周期 较短时,cAdvisor 可能报告 throttled 时间。如果成本引擎误将 throttled 时间计入使用量,会导致高估实际消耗。建议使用 container_cpu_cfs_throttled_seconds_total 进行修正。

4.2.2 内存采集:RSS 与 WorkingSet 的选择

指标 Prometheus 名称 含义 适用场景
RSS container_memory_rss 常驻物理内存,不含缓存 成本分摊(保守模型)
WorkingSet container_memory_working_set_bytes RSS + 活跃缓存,接近实际压力 资源配额规划、HPA
Usage container_memory_usage_bytes RSS + 所有缓存(含非活跃) 不推荐用于成本分摊(高估)
最佳实践:成本分摊场景推荐使用 container_memory_working_set_bytes,因为它更真实反映容器对内存资源的竞争压力。如果使用 RSS,需注意部分语言运行时(如 Java JVM)的堆外内存可能被低估。

4.3 网络与存储采集路径

网络和存储的采集复杂度高于 CPU/内存,因为涉及多接口、多驱动和持久卷映射。

4.3.1 网络采集:接口级与 Pod 级

  • cAdvisor 暴露:container_network_receive_bytes_total 和 container_network_transmit_bytes_total,按网络接口(eth0, lo)区分。
  • Pod 级聚合:PromQL 使用 sum by (pod, namespace) (rate(container_network_receive_bytes_total{interface="eth0"}[5m]))。
  • 成本分摊:通常只统计 eth0 流量,忽略 lo。按入站/出站分别计价。
故障排查要点:如果 Pod 使用 hostNetwork 模式,cAdvisor 无法准确区分容器网络流量,此时网络成本分摊会失效。建议对 hostNetwork Pod 单独使用节点级网络指标或固定费率。

4.3.2 存储采集:临时存储与持久卷

存储类型 采集方式 Prometheus 指标 注意事项
临时存储 (emptyDir) cAdvisor 读取 cgroup blkio 或 filesystem 统计 container_fs_usage_bytes 仅统计容器可写层,不包含镜像层
持久卷 (PV/PVC) kubelet 卷指标或 CSI 驱动暴露 kubelet_volume_stats_used_bytes 需要 CSI 指标暴露,cAdvisor 不直接采集
镜像层存储 节点级磁盘使用统计 node_filesystem_avail_bytes 通常按节点均摊,不按容器分摊
网络与存储采集路径对比 网络采集路径 1. cgroup net 统计 → cAdvisor 读取 2. 按 interface 暴露 bytes_total 3. Prometheus 按 eth0 聚合 4. 成本引擎按入/出站计价 故障点:hostNetwork 容器无法区分 存储采集路径 1. 临时存储:cAdvisor filesystem 统计 2. 持久卷:kubelet volume_stats 或 CSI 3. 镜像层:节点级 filesystem 指标 4. 成本引擎按类型分别计价 故障点:CSI 指标未暴露时 PV 数据缺失 采集差异与故障对比 • 网络:cAdvisor 依赖 cgroup net 统计,hostNetwork 模式失效 • 临时存储:cAdvisor 仅统计容器可写层,emptyDir 大小限制不影响采集 • 持久卷:必须依赖 CSI 驱动暴露指标,否则成本引擎无法获取使用量 • 镜像层:建议按节点均摊,避免按容器分摊导致的复杂度

4.4 采集链路故障排查清单

当成本分摊数据出现异常时,按以下链路逐层排查,可快速定位故障层。

  1. 检查 cAdvisor 端点:curl http://<node-ip>:10250/metrics/cadvisor | head -50,确认容器指标是否正常暴露。
  2. 验证 Metrics Server:kubectl top pod -n <namespace>,确认 Pod 级资源指标是否可用。
  3. 检查 Prometheus 目标状态:在 Prometheus UI 的 Targets 页面确认 kubelet 和 cadvisor 目标为 UP 状态。
  4. 验证指标存在性:在 Prometheus 中查询 container_cpu_usage_seconds_total{container!="POD"},确认有数据返回。
  5. 检查标签完整性:确认指标包含 container、pod、namespace 标签,且无空值。
  6. 验证成本计算 PromQL:在 Prometheus 中直接执行成本分摊 PromQL,确认计算结果合理。
快速诊断命令:
# 检查 cAdvisor 指标是否包含目标容器
  curl -sk https://node-ip:10250/metrics/cadvisor | grep "container_cpu_usage_seconds_total{container=\"my-app\"}"
  
  # 检查 Metrics Server 聚合延迟
  kubectl get --raw /apis/metrics.k8s.io/v1beta1/namespaces/default/pods/my-app | jq .

4.5 精度与性能权衡

采集间隔、保留周期和指标粒度直接影响成本分摊的精度和存储开销。以下为推荐配置:

参数 推荐值 精度影响 存储影响
Prometheus 采集间隔 15s~30s 间隔越小,CPU 峰值捕捉越准 间隔减半,存储翻倍
指标保留周期 30 天(原始) + 90 天(聚合) 保留越长,历史回溯越完整 线性增长,建议配置 TSDB 保留策略
容器级 vs Pod 级 容器级(成本分摊) 容器级可区分 sidecar 与主容器 容器级指标量约为 Pod 级的 2~5 倍
网络指标接口过滤 仅保留 eth0 排除 lo 流量,避免成本虚高 减少约 30% 的指标基数
注意:如果集群规模超过 500 节点,建议使用 Prometheus 分片或 Thanos 架构,避免单点 Prometheus 成为采集瓶颈。同时,cAdvisor 指标基数随容器数量线性增长,需提前规划指标数量上限。