深色模式
成本优化与 FinOps 工具
面向需要回答"我们的 K8s 到底花了多少钱、能省多少"的工程师与管理者。覆盖成本构成、计量方法、工具选型与落地步骤。
适用版本与前提
- Kubernetes:v1.28+
- 前提:能获取云账单或节点成本、集群内已装 Prometheus(多数工具依赖)
- 本文讨论方法论与工具选型,不提供具体单价(各云随时变动)
背景与问题
K8s 成本失控的典型原因:
- requests 与实际用量严重脱节:业务为了"保险"把 requests 设得很大,调度器据此装箱,节点被大量预留但实际空转。
- 成本不可见:账单是按节点/云资源出的,没人知道是哪个团队、哪个服务的哪部分。
- 无人负责:没有把成本指标纳入团队看板,优化自然不会发生。
FinOps 的核心不是"砍资源",而是让成本可见、可归属、可决策。
核心概念
| 概念 | 含义 |
|---|---|
| requests | 调度预留量,决定装箱密度与节点需求 |
| 实际用量(usage) | 容器真实消耗的 CPU/内存 |
| 闲置(idle / slack) | requests 与实际用量之差,是最大浪费来源 |
| 分摊(showback/chargeback) | 把集群总成本按命名空间/标签分摊到团队 |
| 单位成本(unit cost) | 每请求/每租户/每笔订单的成本,用于业务决策 |
生产实践
1. 先测量:找出 requests 与用量的差距
bash
# 找出 requests 与实际用量差距最大的工作负载(需 metrics)
kubectl top pods -A --sort-by=memory | head -20
kubectl top pods -A --sort-by=cpu | head -201
2
3
2
3
用 PromQL 计算闲置率(示例):
promql
# CPU 使用率(实际 / requests)
sum(rate(container_cpu_usage_seconds_total{container!="",pod!=""}[5m])) by (namespace,pod)
/
sum(kube_pod_container_resource_requests{resource="cpu"}) by (namespace,pod)1
2
3
4
2
3
4
建议
优先治理闲置率高且副本数多的工作负载:同样的闲置率下,副本越多浪费的绝对值越大。这是投入产出比最高的切入点。
2. RightSizing:把 requests 调到合理值
yaml
resources:
requests:
cpu: "250m" # 贴近 P95 实际用量,而非峰值
memory: "256Mi"
limits:
cpu: "1"
memory: "512Mi"1
2
3
4
5
6
7
2
3
4
5
6
7
注意
不要把 requests 压到平均用量。requests 过低会导致节点超卖,在流量高峰时引发 CPU 争抢与驱逐。合理做法是贴近 P95 用量并保留安全边界。
3. 用工具做可视化与分摊
常见开源/商业方案(选型前请自行评估当前状态与兼容性):
| 工具 | 定位 |
|---|---|
| OpenCost | 开源成本计量标准,CNCF 孵化项目,可做基础分摊 |
| Kubecost | 基于 OpenCost 的商业产品,功能更完整 |
| kubectl-cost | 命令行快速查询(krew 插件) |
| 云厂商成本中心 | 按节点/标签出账,粒度较粗 |
bash
# 用 kubectl-cost 快速查看(需先在集群部署成本模型)
kubectl cost namespace --window 7d
kubectl cost deployment -n prod --window 7d1
2
3
2
3
未实测
上述工具的安装与数据源配置(Prometheus 地址、云账单密钥)因环境而异,本文不给出具体部署清单;请以各自官方文档为准并在测试集群验证后再上生产。
4. 结构性降本手段
- 弹性伸缩:HPA + Cluster Autoscaler 让资源随负载波动,削掉常态浪费。
- 节点形态:常规负载用预留/包年,可中断负载用 Spot(前提:应用能容忍中断,且有 PDB 与多副本)。
- 存储分级:冷数据下沉到低频/归档存储;清理无主 PV(Released 状态)与旧快照。
- 闲置资源清理:长期无流量的 Service/LoadBalancer、废弃命名空间、孤立的云盘。
bash
# 清理无主 PV(Released 状态往往是 PVC 删除后遗留)[危险]
kubectl get pv | grep Released
# 确认无人使用后再删除,并先备份数据1
2
3
2
3
生产危险
删除 PV 会销毁底层云盘数据。执行前必须确认该卷确属废弃、已完成备份,并在变更单中记录。
验证
任何成本优化都要能证明有效:
text
优化前(7 天窗口):命名空间 prod 分配成本 X,平均 CPU 使用率 18%
优化后(7 天窗口):命名空间 prod 分配成本 Y,平均 CPU 使用率 42%
业务 SLO:错误率与时延未劣化(必须同时验证!)1
2
3
2
3
注意
只看成本下降不看 SLO 的优化是危险的。降本必须以"业务指标不劣化"为前置条件,否则省的云钱会以故障损失的形式加倍还回来。
回滚与清理
bash
# requests 调整可回滚
kubectl set resources deployment/web -n prod --requests=cpu=1,memory=1Gi
kubectl rollout status deployment/web -n prod
# 弹性伸缩若导致抖动,调保守(提高 minReplicas / 延长 stabilizationWindow)1
2
3
4
5
2
3
4
5
故障排查
| 现象 | 定位 |
|---|---|
| 成本工具显示 0 或异常 | Prometheus 数据源未配置/指标缺失(如 kube-state-metrics 未装) |
| 分摊结果与账单对不上 | 节点成本模型未包含存储/网络/托管控制面费用 |
| 优化后时延上升 | requests 压太狠导致 CPU 争抢:查 throttling(见排障性能篇) |
| Spot 实例频繁被回收 | 未配置 PDB/多副本,或负载不适合 Spot |
安全与合规
- 成本工具需要云账单只读密钥与集群指标读权限,属敏感凭证,需最小权限 + 密钥轮换。
- 成本数据含业务规模信息,报表访问需做权限控制。
- 分摊数据用于内部结算时,口径需与各团队事先对齐,避免争议。
常见坑
- 只看节点数不看 requests:节点数不变不代表没有浪费,浪费藏在 requests 里。
- 一次性清零优化:降本后业务增长,资源会重新膨胀,需持续运营而非一次性项目。
- 把 limits 当 requests 优化对象:真正决定成本的是 requests(影响装箱),不是 limits。
- 忽略隐性成本:跨 AZ 流量、LoadBalancer、快照、日志存储往往占比不低。
参考资料
- OpenCost 官方文档,访问日期:2026-10-09。
- FinOps Foundation 文档,访问日期:2026-10-09。
- Kubernetes 官方文档:资源管理,访问日期:2026-10-09。
- CNCF FinOps 相关项目,访问日期:2026-10-09。