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 作为用量与元数据的主来源,账单数据用于校准节点、磁盘、负载均衡器等外部资源的真实单价。
节点成本与 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。
默认成本模型与口径一致性
Kubecost 的默认成本模型可以概括为:节点成本按 request 比例分配给 Pod,共享成本按配置策略分摊,未分配部分标记为闲置或未归属。这个模型不追求会计意义上的精确,而是追求可解释、可复现、可对比。
在实际使用中,最容易出问题的是口径不一致。例如,财务看的是云账单的月度总支出,平台团队看的是 Kubecost 的按需价格估算,两者可能因为折扣、预留实例、Spot 实例和信用额度而产生差异。解决办法是在 Kubecost 中启用账单集成,让节点单价来自实际账单,而不是公开价格;同时在成本报告里区分“按需价”和“实际摊销价”。
| 成本类型 | 默认来源 | 分配方式 | 常见偏差原因 |
|---|---|---|---|
| 节点 CPU / 内存 | 云账单或默认单价 | 按 Pod request 比例 | request 远大于实际用量 |
| GPU | 实例类型价格 | 按 GPU request 数量 | GPU 共享或 MIG 未正确建模 |
| PV 存储 | 云盘账单 | 按 PVC 绑定关系归属 | 未绑定 PVC 或动态供应延迟 |
| 共享成本 | 节点成本汇总 | 按比例或固定权重 | 分摊策略未随组织调整 |
| 闲置成本 | 节点成本减 Pod 分配 | 不分配,单独展示 | 节点规格过大或副本过多 |
理解这条从指标到模型的链路后,再看到 Kubecost 里的成本数字时,就能回答三个问题:这个数字来自哪里、它被分给了谁、它用的是哪种口径。这三个问题,正是后续做成本治理和优化的前提。