3. Kubecost数据采集与成本模型

Kubecost 的成本数字并不是从账单系统直接读出来的,而是由采集层、分配层和模型层共同推导出来的。理解这条链路,才能解释为什么同一个集群在不同视图里会出现不同的“成本”,也才能在成本异常时判断问题出在采集、分配还是模型假设上。

指标来源:三类数据汇合成成本输入

Kubecost 的输入主要来自三个方向。第一是 Prometheus 中的资源使用指标,例如 container_cpu_usage_seconds_total、container_memory_working_set_bytes、kube_pod_container_resource_requests 等,它们回答“用了多少、申请了多少”。第二是 云厂商或账单侧的计价数据,通过 AWS CUR、GCP BigQuery 账单导出或 Azure 成本导出获得,回答“这些资源实际花了多少钱”。第三是 Kubernetes 对象元数据,包括 namespace、label、annotation、ownerReferences、PVC 与 PV 的绑定关系,回答“这笔钱应该归到谁头上”。

三者缺一不可。只有用量没有价格,只能算相对占比;只有价格没有用量,无法拆分到 Pod;没有元数据,成本就无法按团队、应用或环境聚合。Kubecost 默认以 Prometheus 作为用量与元数据的主来源,账单数据用于校准节点、磁盘、负载均衡器等外部资源的真实单价。

Kubecost 成本推导链路:从原始指标到可分摊成本 采集层 · 指标来源 Prometheus 用量指标 云账单 / 价格数据 K8s 对象元数据 分配层 · 成本归属 节点成本 → 节点池 / 节点 节点成本 → Pod(按请求/用量) 共享成本 → 按权重分摊 模型层 · 成本口径 默认模型:请求量优先 闲置成本识别与标记 未分配 / 未归属成本 输出:按 Namespace / Label / Controller / Pod 聚合的成本视图 CPU 成本 · 内存成本 · GPU 成本 · PV 成本 · 网络成本 · 共享成本 · 闲置成本 每条成本记录都携带来源、归属对象与模型口径 关键判断: 若用量指标缺失 → 成本为 0 或偏低;若价格数据缺失 → 使用默认单价;若元数据缺失 → 成本落入“未分配”桶。 排查成本异常时,先确认数据来源是否完整,再检查分配权重与模型口径是否与预期一致。

节点成本与 Pod 成本分配

节点成本是 Kubecost 成本模型的起点。对于云上节点,Kubecost 优先使用账单中的实际价格;如果账单不可用,则回退到按实例类型查询的公开价格或用户配置的默认单价。节点成本包含 CPU、内存、GPU、本地磁盘以及节点上运行的 DaemonSet 等系统组件开销。

把节点成本拆到 Pod 时,Kubecost 默认采用 基于请求量(request)的分配方式。假设一个节点每小时成本为 1.20 美元,节点可分配 CPU 为 8 核、内存为 32 GiB。某 Pod 的 CPU request 为 2 核、内存 request 为 8 GiB,则它分到的 CPU 成本为 1.20 × (2/8) = 0.30 美元/小时,内存成本为 1.20 × (8/32) = 0.30 美元/小时。如果节点上所有 Pod 的 request 总和小于节点容量,剩余部分就是闲置成本。

这种分配方式的好处是稳定、可预测,适合做容量规划和预算归属;缺点是当 Pod 实际用量远低于 request 时,成本会被高估。Kubecost 同时提供基于实际用量的视图,但默认模型仍以 request 为主,因为 request 才是调度器真正预留的资源。

共享成本分摊

集群里有一类成本不属于任何单个 Pod,例如 kube-system 中的系统组件、Ingress Controller、监控 Agent、服务网格 Sidecar、共享存储和负载均衡器。Kubecost 将这些归为共享成本,并提供多种分摊策略:

  • 按 CPU/内存请求比例分摊:把共享成本按各 Namespace 或工作负载的 request 占比摊下去,适合大多数场景。
  • 按实际用量比例分摊:更贴近真实消耗,但受采样波动影响较大。
  • 按固定权重分摊:通过 annotation 或配置为特定团队指定权重,适合平台团队与业务团队之间的内部结算。
  • 不摊分:共享成本单独展示,不进入业务成本,适合先观察再决策。

选择哪种策略取决于组织目标。如果目的是让业务团队感知真实资源占用,按请求比例通常最平衡;如果目的是内部计费,固定权重更容易达成一致。无论选哪种,都要在成本报告里明确标注口径,避免同一份数据被不同团队做出不同解读。

闲置成本识别

闲置成本是节点上已预留但未被任何 Pod 请求的资源所对应的成本。它不等于“浪费”,因为预留本身是为了应对突发流量和调度余量。Kubecost 会把闲置成本单独列出,帮助判断集群是否存在过度预留。

识别逻辑可以简化为:节点总成本减去所有 Pod 分配成本,剩余部分即为闲置成本。如果闲置成本持续高于总成本的 30%,通常意味着 request 设置偏大、节点规格偏大或副本数过多。此时可以结合 Kubecost 的 request 与实际用量对比,逐步下调 request,再观察闲置成本是否下降、以及是否出现 CPU throttling 或 OOM。

闲置成本高不一定是坏事。对于延迟敏感型服务,保留 20%~30% 的余量是合理的。关键是把闲置成本显式化,让容量决策从“感觉够用”变成“有数据支撑”。

默认成本模型与口径一致性

Kubecost 的默认成本模型可以概括为:节点成本按 request 比例分配给 Pod,共享成本按配置策略分摊,未分配部分标记为闲置或未归属。这个模型不追求会计意义上的精确,而是追求可解释、可复现、可对比。

在实际使用中,最容易出问题的是口径不一致。例如,财务看的是云账单的月度总支出,平台团队看的是 Kubecost 的按需价格估算,两者可能因为折扣、预留实例、Spot 实例和信用额度而产生差异。解决办法是在 Kubecost 中启用账单集成,让节点单价来自实际账单,而不是公开价格;同时在成本报告里区分“按需价”和“实际摊销价”。

成本类型 默认来源 分配方式 常见偏差原因
节点 CPU / 内存 云账单或默认单价 按 Pod request 比例 request 远大于实际用量
GPU 实例类型价格 按 GPU request 数量 GPU 共享或 MIG 未正确建模
PV 存储 云盘账单 按 PVC 绑定关系归属 未绑定 PVC 或动态供应延迟
共享成本 节点成本汇总 按比例或固定权重 分摊策略未随组织调整
闲置成本 节点成本减 Pod 分配 不分配,单独展示 节点规格过大或副本过多

理解这条从指标到模型的链路后,再看到 Kubecost 里的成本数字时,就能回答三个问题:这个数字来自哪里、它被分给了谁、它用的是哪种口径。这三个问题,正是后续做成本治理和优化的前提。