Kubernetes 的成本管理比传统虚拟机复杂得多。一台云主机通常有明确规格和单价,但一个 Kubernetes 集群承载大量混合负载,Pod 在节点间漂移,多个团队共享同一批计算资源。若只盯着云厂商的总账单,很难判断哪项业务消耗了成本,也不知道扩容是否合理。要让 FinOps 真正落地,需要把成本从集群层级拆到命名空间、工作负载和团队,并把优化动作嵌入日常发布与容量规划流程中。

一、建立可量化的成本分摊模型
成本可视化是 FinOps 的基础。Kubernetes 本身不提供账单,但可以通过资源请求和实际使用量来折算成本。以 CPU 为例,节点的可分配 CPU 是固定的,某个命名空间里所有 Pod 的 request 之和占节点总可分配资源的比例,可以作为该命名空间分摊节点成本的系数。云厂商按小时或按秒出的账单信息可以与节点标签、实例规格结合,形成更精确的单位价格。
为了让分层分摊可行,需要先给命名空间打上成本中心、团队、环境等标签。标签不参与调度,但能让 Prometheus、Kubecost 或 OpenCost 等工具按维度聚合。下面的 YAML 展示了一个带财务标签的命名空间:
apiVersion: v1
kind: Namespace
metadata:
name: order-service
labels:
finops.team: trading
finops.cost-center: cc-202
finops.env: production
光有标签还不够,还需要把资源消耗转化为金额。以 Prometheus 为例,可以用 kube_pod_container_resource_requests 指标统计某个命名空间申请的 CPU 核数,再乘以节点单价。更推荐的做法是引入 Kubecost 或 OpenCost。它们会采集节点价格、Pod 请求、实际用量和持久卷信息,生成 namespace、deployment、label 等维度的成本报表。对多数团队而言,用成熟工具先跑通成本可见性,比重头搭建 PromQL 计算体系更划算。
需要注意的是,request 和实际使用量经常不一致。开发为了保险把 request 写高,导致成本分摊数值虚高,但实际节点利用率很低。因此成本模型至少要同时展示 request 口径和 usage 口径。request 口径适合做预算归因,usage 口径适合发现真正浪费。
二、从资源画像入手优化规格
Kubernetes 中常见的浪费来自缺少资源画像。CPU 和内存 request 一旦设置不合理,要么导致 Pod 无法调度,要么留下大量闲置资源。尤其内存不像 CPU 可以压缩,超量分配容易诱发 OOMKilled,进一步加重故障成本。VPA(Vertical Pod Autoscaler)可以根据历史用量给出推荐值,适合用来修正长期运行的服务的规格。
在观察模式下使用 VPA 不会自动修改 Deployment,只会生成推荐值。这样既能获取数据,又不会在业务高峰期触发重启。下面的配置开启 VPA 推荐但关闭自动更新:
apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: order-service-vpa
spec:
targetRef:
apiVersion: apps/v1
kind: Deployment
name: order-service
updatePolicy:
updateMode: "Off"
运行 7 到 14 天后,可以通过 kubectl describe vpa order-service-vpa 查看 Recommendation 部分。建议将生产环境的 request 设置为略高于 P95 实际用量,而不是直接用最大值。这样既能保证稳定性,又能避免以峰值容量长期付费。对于不承担核心流量的测试环境,可以采用更激进的超卖策略,但需要配合监控和告警。
除了垂直规格,水平伸缩也影响成本。HPA 能根据 CPU、内存或自定义指标调整副本数,让服务在低谷用更少 Pod,在高峰快速扩容。不过 HPA 只是手段,目标应该围绕单位请求成本而非单纯减少副本。若业务指标和资源指标偏离较大,建议使用 KEDA 或自定义 metrics 驱动伸缩,使扩容行为更贴合收入转化。
三、搭建预算告警与成本复盘机制
成本可视化之后必须形成闭环。没有告警和复盘,团队往往在月底账单出来后才被动响应。可以在 Prometheus 中配置规则,当某个命名空间的估算成本超过每日预算时触发告警。估算成本可以用 CPU 使用量乘以业务约定的内部单价,也可以直接接入 Kubecost 的 budget 能力。
以下是一个 PrometheusRule 示例,用命名空间的 CPU 累计使用量乘以系数作为成本估算,超过阈值时告警:
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: finops-budget-alert
spec:
groups:
- name: cost
rules:
- alert: NamespaceCostOverBudget
expr: sum(increase(container_cpu_usage_seconds_total{namespace="order-service"}[24h])) * 0.03 > 100
for: 1h
labels:
severity: warning
annotations:
summary: "order-service namespace daily cpu cost over 100"
告警只是起点。真正有效的 FinOps 机制是把成本写进周会,由平台团队提供按团队维度的费用趋势,业务负责人确认异常项。预算可以按季度或月度滚动,允许短时超支,但必须给出原因和优化时间点。这样做不是为了追责,而是让资源决策从拍脑袋变成数据驱动。坚持几个迭代后,很多团队会主动提出缩容、下线无用环境或调整副本策略。
预算口径要尽量简单。建议初期只对 CPU、内存和存储三项计费,网络流量暂不计入,避免数据复杂导致推广困难。等到大家习惯看成本报表后,再逐步加入负载均衡、NAT 网关等平台级费用。
四、通过弹性算力和节点分级降低单价
规格优化解决的是少买资源,弹性算力解决的是低价购买资源。不同云厂商的 Spot 实例、抢占式实例、Savings Plans 或预留实例价格差异明显。适合 Kubernetes 的做法是把节点池分级:核心业务使用按需或包年节点,批处理、开发测试、可重试的异步任务使用 Spot 节点。这样既控制单价,又不牺牲关键服务的稳定性。
要让 Pod 正确落到 Spot 节点,需要利用污点和容忍。先给 Spot 节点池打上特定标签和污点,然后在可中断工作负载中声明容忍和亲和性。下面是一个 Pod 级别的示例:
apiVersion: v1
kind: Pod
metadata:
name: batch-import-task
spec:
tolerations:
- key: "node.kubernetes.io/capacity-type"
operator: "Equal"
value: "spot"
effect: "NoSchedule"
affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: "node.kubernetes.io/capacity-type"
operator: In
values: ["spot"]
restartPolicy: Never
containers:
- name: importer
image: batch-import:latest
更进一步可以使用 Karpenter 这类自动伸缩组件。它能根据 Pod 需求动态选择实例类型、可用区和购买方式,在满足调度约束时倾向选择更便宜的机型。不过自动弹性也要防止误伤,例如数据库等有状态服务不能随意漂移,必须结合 PodDisruptionBudget 和持久化策略。选择 Spot 前还要评估应用是否能容忍节点被回收,必要时通过优雅终止和重试机制保证任务最终完成。
除了 Spot,还可以关注 ARM 架构节点。很多云厂商的 ARM 实例单 vCPU 成本更低,对 Go、Java、Rust 等语言编译的容器镜像可以直接迁移。前提是基础镜像需要支持 arm64,且所有依赖都能在两套架构上稳定运行。平台团队可以为不同架构维护节点池,并用 buildx 或云原生构建工具同时产出多架构镜像。
五、把 FinOps 能力沉淀到平台流程
如果每个团队都要自己理解成本模型和优化手段,FinOps 很难长期持续。应该由平台团队把成本治理做成默认能力。例如在 CI/CD 流水线中校验资源请求范围,拒绝明显不合理的配置;在部署清单合并时自动注入成本标签;在集群中加入 LimitRange 和 ResourceQuota,防止个别命名空间无限制占用资源。
下面是一个 ResourceQuota 示例,限制某个命名空间的总 CPU 和内存申请量,避免团队绕过预算继续扩容:
apiVersion: v1
kind: ResourceQuota
metadata:
name: order-service-quota
namespace: order-service
spec:
hard:
requests.cpu: "20"
requests.memory: 40Gi
limits.cpu: "40"
limits.memory: 80Gi
这种平台化的限制需要与成本报表打通。可以把 quota 上限与团队预算挂钩,当团队需要更多资源时,走申请流程并同步修改配额。平台团队还应提供自助查询页面,让开发者实时看到自己的资源占用和预估费用。开发者如果能看到自己部署的某个副本每天多花多少钱,优化意愿会明显增强。
最终 Kubernetes FinOps 不是一次性项目,而是一套持续运行的成本工程实践。建立模型、优化规格、告警复盘、弹性降本、平台沉淀,五个环节相互配合,才能让成本不再随着集群数量增长而失控。
Kubernetes FinOps云成本治理资源优化修改时间:2026-10-03 11:54:18