Kubernetes 成本优化:FinOps、资源画像与降本实践

系统讲解 Kubernetes 成本优化:成本构成与分摊模型、Request 与实际用量画像(VPA/KRR)、节点池与 Spot 实例、Karpenter 自动伸缩、OpenCost/Kubecost 成本工具,以及降本优先级与成本指标看板。

K8s 的账单常常很迷惑:买了一堆节点,但每个团队到底用了多少?很多 Pod 的 Request 写得很"慷慨",实际用量不到 20%;节点池空转却照付钱。成本优化不是"压榨资源",而是"让每块钱对应到真实的工作负载"。本指南把 K8s 成本优化的全链路讲清楚:成本怎么构成与分摊、怎么用 VPA/KRR 画像真实用量、节点池与 Spot 怎么组合、Karpenter 怎么把节点数对准实际需求,以及用 OpenCost/Kubecost 把成本变成可观测的指标。


目录


1. 成本构成与分摊模型

1.1 K8s 账单由什么构成

云账单按"资源"计价,K8s 账单则要把实例成本分摊到工作负载。分摊要素:**计算(CPU)**按节点规格 × 时长、内存按申请量、存储按 PV 容量与 IOPS、网络按跨区域/公网流量(K8s 工具常算不到,要补)、托管费(EKS/GKE/AKS 的集群管理费)。三个口径别混:节点成本(买的)≠ Pod 成本(用的)≠ 业务成本(分摊的)。

1.2 分摊模型的两种做法

按 Request 分摊(默认):成本 = 节点单价 × (该 Pod 的 requests / 节点总容量),简单稳定但高估"要得多用得少"的 Pod。按实际用量分摊:成本 = 节点单价 × (实际用量 / 节点总量),更贴近真实但波动大、采集成本高。生产建议:用 Request 分摊做"预算",用实际用量做"优化依据"——谁占的承诺资源谁买单,但优化看真实用量。


2. 资源画像:Request 与真实用量

2.1 为什么要画像

现实很普遍:Deployment 里 requests 是"拍脑袋"写的(比如 CPU 4 核、内存 8Gi,实际 P99 只用 500m/1Gi),节点被"虚占",其他 Pod 挤不上,节点却要多买。画像 = 用历史指标回答:真实用量是多少(P50/P95/P99)、Request 应该设多少(要留多少余量)。

2.2 用 Prometheus 看用量

# CPU 利用率(按 request 归一)
sum by (pod) (rate(container_cpu_usage_seconds_total{pod=~"order-.*"}[5m]))
  / sum by (pod) (kube_pod_container_resource_requests{pod=~"order-.*",resource="cpu"})

# 内存峰值
max_over_time(container_memory_working_set_bytes{pod=~"order-.*"}[7d])

画像经验:看 P95/P99 而非平均值;CPU 容忍短尖峰(可限流),内存是硬上限(OOM 即死);内存 requests 建议取 P95~P99,CPU requests 可适度收紧。


3. VPA 与资源推荐

3.1 VPA 原理

VPA(Vertical Pod Autoscaler)观察 Pod 实际用量,给出/自动调整 requests 与 limits。模式:Off(只给推荐,不自动改,推荐用于"画像起步")、Initial(只在创建时设初值)、Auto(自动更新并重启 Pod 生效)。注意 VPA 不能与 HPA(按 CPU 伸缩)同指标混用,会打架。

3.2 VPA 配置示例

apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
  name: order-vpa
  namespace: shop
spec:
  targetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: order
  updatePolicy:
    updateMode: "Off"
  resourcePolicy:
    containerPolicies:
      - containerName: "*"
        controlledResources: ["cpu", "memory"]
        minAllowed: { cpu: 100m, memory: 128Mi }
        maxAllowed: { cpu: "4", memory: 8Gi }

查看推荐:kubectl get vpa order-vpa -n shop -o jsonpath='{.status.recommendations}'。

3.3 KRR:命令行的轻量画像

**KRR(Kubernetes Resource Recommender)**一条命令扫描全集群:krr simple 输出每个 Deployment 的推荐表(如 Deployment order: cpu request 4 → 1.2(省 70%),mem 8Gi → 3Gi)。

ℹ️ VPA Off 模式的用法:先 updateMode: Off 挂上一周让 VPA/KRR 收集数据,再人工 review 推荐值,最后才切 Auto。上来就 Auto 会频繁重启 Pod。


4. 节点池与 Spot 实例

4.1 节点池分层

按负载特性分池:通用池(在线服务,稳定随业务伸缩)、批处理池(Job/训练,可中断、Spot 优先)、系统池(kube-system/监控,最小规模、不可中断)、GPU 池(贵,严格按需伸缩)。反模式:一个池跑所有负载 → 高峰互相挤、Spot 与关键服务混跑。

4.2 Spot 实例的正确用法

Spot(抢占式/竞价实例)价格是按需的 30%~70%,但随时可能被回收,只适合能容忍中断/能重新拉起的负载:批处理 Job(失败可重试)、无状态在线服务(多副本可漂移)、数据处理/CI。不适合:单副本有状态服务(数据库)、关键控制面、监控存储。用 nodeSelector 把 Job 拉到 Spot 池:spec.nodeSelector: { lifecycle: spot }。

Spot 的坑:
  - 云商给约 2 分钟回收告警,用 node-drain/终止处理程序响应
  - 至少 2 副本 + PDB,回收一个不影响
  - 别把 Spot 当主力:占比过高,高峰大规模回收会雪崩

5. Karpenter 与弹性伸缩

5.1 为什么需要 Karpenter

传统 Cluster Autoscaler 按节点池配置缩放,粒度粗、慢(分钟级)、不会混搭机型。Karpenter 直接根据"待调度 Pod 的资源需求"创建最合适的节点,支持多种实例规格、Spot/按需混合、bin-packing,秒级扩缩、闲置节点自动回收——让"节点数"紧跟"真实需求",消除空转。

5.2 Karpenter 配置示例

apiVersion: karpenter.sh/v1beta1
kind: NodePool
metadata:
  name: general
spec:
  disruption:
    consolidationPolicy: WhenUnderutilized
  template:
    spec:
      requirements:
        - key: karpenter.sh/capacity-type
          operator: In
          values: ["on-demand", "spot"]
      nodeClassRef:
        group: karpenter.k8s.aws
        kind: EC2NodeClass
        name: general

配合 HPA:Pod 多 → 节点自动补 → 高峰过去 → 合并回收。

ℹ️ Karpenter 的省钱本质:它把"该有 3 台还是 7 台"从"人定"变成"按 Pod 需求动态算"。但前提是 Pod 的 requests 必须真实——Request 虚高,Karpenter 也只会多买节点。


6. 成本工具:OpenCost 与 Kubecost

6.1 OpenCost:开源成本引擎

OpenCost(CNCF 项目)安装:kubectl apply -f https://raw.githubusercontent.com/opencost/opencost/develop/kubernetes/opencost.yaml,然后 kubectl port-forward -n opencost svc/opencost 9090:9090 访问 Web UI,或调 API /model/allocation/compute?window=7d。它能告诉你每个命名空间/标签/Deployment 花了多少钱、按 Request 与实际用量两个口径、与云账单对账(接入 AWS/GCP/Azure 价格表)。

6.2 Kubecost:企业级可视与治理

Kubecost 在 OpenCost 之上加了:集群/命名空间/团队视图与 Drill-down、成本异常告警(某团队突增)、资源建议(结合 VPA 的降本预估)、多集群聚合与云对账、按团队隔离成本视图。起步建议:先 OpenCost(免费够用),需要多团队看板与告警再上 Kubecost。

6.3 与云账单对账

对账公式:云账单实例成本 - 分配给命名空间的成本 = 集群/系统/闲置成本。闲置成本是优化机会池:节点空转(利用率 < 30%)、系统命名空间占太多、大量没被分摊的存储/流量。目标:闲置成本占比 < 15%~20%,否则说明节点买多了/调度不均。


7. 降本优先级与 ROI

7.1 按投入产出排序

降本手段(先做投入小的):先画像(把虚高 Request 压到真实值,几乎零成本)、清理闲置(删没用 Deployment/PV,白捡)、节点弹性(CA/Karpenter 消除空转)、引入 Spot(批处理/无状态)、存储与流量治理(PV 缩容、压缩日志、减少跨区流量)、架构级(合并服务、降副本,收益大但投入大)。顺序原则:先省浪费(画像+清理)→ 再省弹性(伸缩+Spot)→ 最后才碰架构。

7.2 计算 ROI 的例子

例:某命名空间 100 个 Deployment,平均 Request 虚高 3 倍,节点月成本 20 万。画像后 Request 压到 1/3(配合弹性),按落地 30% 估算月省 6 万,一周人力成本可忽略 → ROI 极高,优先做。反例:为了省 2000 元去重构服务拆分,投入一个月 → ROI 低,往后放。

ℹ️ 降本不是"砍配置":压 Request 必须配合监控(不降 SLO)与资源余量。一次压太狠导致 OOM/CPU throttling,得不偿失。


8. 成本指标与看板

8.1 核心成本指标

用四个指标把成本做成看板:集群成本/节点成本(每月总账单)、分摊成本(按命名空间/团队/标签汇总)、闲置成本占比(节点利用率低的浪费比例)、单位成本效率(如每百万请求成本、每卡时成本)。配套信号:节点平均利用率(目标 50%+)、容器 Request 利用率 vs 实际(目标 < 2 倍)、空转节点数。

8.2 看板示例

┌──────────────────────────────────────────────┐
│ FinOps 看板(Grafana)                        │
│  本月集群成本 ¥182,000 vs 上月 ¥205,000 ▼   │
│  闲置成本占比 12%(目标 < 15%)              │
│  按团队:电商 45% / 算法 30% / 平台 25%      │
│  容器利用率:CPU 62% / 内存 71%             │
│  空转节点:3 台(估计浪费 ¥9,000/月)        │
└──────────────────────────────────────────────┘

告警建议:单团队成本环比 +20% 告警、节点利用率持续 < 30% 告警、Spot 回收率骤升告警。


9. 生产最佳实践

9.1 Checklist

□ 用 OpenCost/Kubecost 建立分摊,先知道"钱花在哪"
□ 全局做资源画像(VPA Off / KRR),把虚高 Request 压下来
□ 压 Request 时留余量,并用监控确认 SLO 不降
□ 节点池分层 + 弹性伸缩(Karpenter/Cluster Autoscaler)
□ 批处理与无状态负载换 Spot,关键服务保持按需
□ 清理闲置:删无用 Deployment/PV/命名空间
□ 设置成本告警(团队突增/空转/Spot 回收)
□ 每月做一次成本 Review,把成本指标接入团队会议

9.2 常见坑与对策

坑现象对策
Request 虚高节点买多、Pod 挤不上VPA/KRR 画像后压到真实值
压太狠OOM/CPU throttling留余量 + 监控 SLO + 分批压
只加节点不回收空转烧钱弹性伸缩 + 合并回收
Spot 混跑关键服务回收即事故Spot 只给可中断负载
成本不可分摊团队不认账按标签分摊 + 看板

小结

K8s 成本优化的本质是"让资源紧跟真实需求,让账单对应到每个团队":先用 OpenCost/Kubecost 把成本分摊清楚,再用 VPA/KRR 画像把虚高 Request 压到真实值,接着用弹性伸缩(Karpenter)与 Spot 把节点数对准实际需求,最后用看板与告警让成本持续可观测。降本的正确顺序永远是:先省浪费(画像+清理)→ 再省弹性(伸缩+Spot)→ 最后才碰架构。记住一句话:成本优化的收益来自"闲置的消除"和"精确的匹配",而不是把服务砍瘦——用数据说话,用指标验收。

继续阅读

探索更多技术文章

浏览归档,发现更多关于系统设计、工具链和工程实践的内容。

全部文章 返回首页

「云原生」更多文章

  1. 边缘与轻量 Kubernetes:K3s、KubeEdge 与资源受限环境
  2. 策略即代码:OPA Gatekeeper、Kyverno 与合规治理
  3. Kubernetes 批处理:Job、CronJob 与工作队列