其他分享
首页 > 其他分享> > FinOps for Kubernetes - 如何拆分 Kubernetes 成本

FinOps for Kubernetes - 如何拆分 Kubernetes 成本

作者:互联网

本文独立博客阅读地址:https://thiscute.world/posts/finops-for-kubernetes/

目录

FinOps 是一种不断发展的云财务管理学科和文化实践,通过帮助工程、财务、技术和业务团队在数据驱动的预算分配上进行协作,使成本预算能够产生最大的业务价值。

云计算成本管控

随着越来越多的企业上云,云计算的成本管控也越来越受关注。在讨论 Kubernetes 成本之前,先简单聊下如何管控云计算成本,有一个新名词被用于形容这项工作——FinOps.

传统的数据中心的成本是比较固定的,所有的成本变动通常都伴随着硬件更替。
而在云上环境就很不一样了,由于云服务的按量收费特性,以及五花八门的计费规则,开发人员稍有不慎,云成本就可能会出现意料之外的变化。另一方面由于计费的复杂性,业务扩容对成本的影响也变得难以预测。

目前的主流云服务商(AWS/GCP/Alicloud/...)基本都提供基于资源标签的成本查询方法,也支持将成本导出并使用 SQL 进行细致分析。
因此其实要做到快速高效的云成本分析与管控,主要就涉及到如下几个点:

但是也存在许多特殊的云上资源,云服务商目前并未提供良好的成本分析手段,Kubernetes 集群成本就是其中之一。

Kubernetes 成本分析的难点

目前许多企业应该都面临着这样的场景:所有的服务都运行在一或多个 Kubernetes 集群上,其中包含多条业务线、多个产品、多个业务团队的服务,甚至除了业务服务,可能还包含 CICD、数据分析、机器学习等多种其他工作负载。而这些 Kubernetes 集群通常都由一个独立的 SRE 部门管理。

但是 Kubernetes 集群本身并不提供成本拆分的能力,我们只能查到集群的整体成本、每个节点组的成本等这样粗粒度的成本信息,缺乏细粒度的成本分析能力。
此外,Kubernetes 集群是一个非常动态的运行环境,其节点的数量、节点规格、Pod 所在的节点/Zone/Region,都可能会随着时间动态变动,这为成本分析带来了更大的困难。

这就导致我们很难回答这些问题:每条业务线、每个产品、每个业务团队、或者每个服务分别花了多少钱?是否存在资源浪费?有何优化手段

而 FinOps for Kubernetes,就是通过工程化分析、可视化成本分析等手段,来回答这些成本问题,分析与管控 Kubernetes 的成本。

接下来我会先介绍下云上 Kubernetes 成本分析的思路与手段,最后再介绍如何使用 Kubecost 分析 Kubernetes 集群的成本。

要做好 Kubernetes 成本工作,有如下三个要点:

Kubernetes 成本的构成

以 AWS EKS 为例,它的成本有这些组成部分:

总结下,其实就是三部分成本:计算、存储、网络。其中计算与存储成本是相对固定的,而网络成本就比较动态,跟是否跨区、是否通过 NAT 等诸多因素有关。

Kubernetes 资源分配的方式

Kubernetes 提供了三种资源分配的方式,即服务质量 QoS,不同的分配方式,成本的计算难度也有区别:

最佳实践

要做到统一分析、拆分 Kubernetes 与其他云资源的成本,如下是一些最佳实践:

成本优化实践:

多云环境

上述讨论的绝大部分策略,都适用于多云环境。在这种涉及多个云服务提供商的场景,最重要的一点是:搭建平台无关的成本分析与管控平台。而其核心仍然是文章最前面提到的两点,只需要补充两个字 一致

这样就可以把不同云服务商的数据转换成统一的格式,然后在自有的成本平台上进行统一的分析了。

搭建一个这样的成本分析平台其实并不难,许多大公司都是这么干的,小公司也可以从一个最小的平台开始做起,再慢慢完善功能。

以我现有的经验看,其实主要就包含这么几个部分:

Kubernetes 成本分析

前面讨论的内容都很「虚」,下面来点更「务实」的:Kubernetes 成本分析实战。

目前据我所知,主要有如下两个相关的开源工具:

其中 kubecost 是最成熟的一个,我们接下来以 kubecost 为例介绍下如何分析 Kubernetes 成本。

安装 kubecost

kubecost 有两种推荐的安装方法:

开源的 cost-model 直接使用此配置文件即可部署:https://github.com/kubecost/cost-model/blob/master/kubernetes/exporter/exporter.yaml

而如果要部署带 UI 的商业版,需要首先访问 https://www.kubecost.com/install#show-instructions 获取到 kubecostToken,然后使用 helm 进行部署。

首先下载并编辑 values.yaml 配置文件:https://github.com/kubecost/cost-analyzer-helm-chart/blob/develop/cost-analyzer/values.yaml

然后部署:

kubectl create namespace kubecost
helm repo add kubecost https://kubecost.github.io/cost-analyzer/
helm install kubecost kubecost/cost-analyzer -n kubecost -f kubecost-values.yaml

通过 port-forward 访问:

kubectl port-forward --namespace kubecost deployment/kubecost-cost-analyzer 9090

现在访问 http://localhost:9090 就能进入 Kubecost 的 UI 面板,其中最主要的就是 Allocation 成本拆分功能。

kubecost 的成本统计原理

1. CPU/RAM/GPU/Storage 成本分析

Kubecost 通过 AWS/GCP 等云服务商 API 动态获取各 region/zone 的上述四项资源的每小时成本:CPU-hour, GPU-hour, Storage Gb-hour 与 RAM Gb-hour,或者通过 json 文件静态配置这几项资源的成本。
OD 按需实例的资源价格通常比较固定,而 AWS Spot 实例的成本波动会比较大,可以通过 SpotCPU/SpotRAM 这两个参数来设置 spot 的默认价格,也可以为 kubecost 提供权限使它动态获取这两项资源的价格。

kubecost 根据每个容器的资源请求 requests 以及资源用量监控进行成本分配,对于未配置 requests 的资源将仅按实际用量监控进行成本分配。

kubecost 的成本统计粒度为 container,而 deployment/service/namespace/label 只是按不同的维度进行成本聚合而已。

2. 网络成本的分析

https://github.com/kubecost/docs/blob/b7e9d25994ce3df6b3936a06023588f2249554e5/network-allocation.md

对提供线上服务的云上 Kubernetes 集群而言,网络成本很可能等于甚至超过计算成本。这里面最贵的,是跨区/跨域传输的流量成本,以及 NAT 网关成本。
使用单个可用区风险比较高,资源池也可能不够用,因此我们通常会使用多个可用区,这就导致跨区流量成本激增。

kubecost 也支持使用 Pod network 监控指标对整个集群的流量成本进行拆分,kubecost 会部署一个绑定 hostNetwork 的 daemonset 来采集需要的网络指标,提供给 prometheus 拉取,再进行进一步的分析。

kubecost 将网络流量分成如下几类:

更多的待研究,看 kubecost 官方文档吧。

另外还看到 kubecost 有忽略 s3 流量(因为不收费)的 issue: https://github.com/kubecost/cost-model/issues/517

kubecost API

https://github.com/kubecost/docs/blob/b7e9d25994ce3df6b3936a06023588f2249554e5/apis.md

查询成本拆分结果的 API 示例:

import requests
resp = requests.get("http://localhost:9090/model/allocation", params={
  "window": "2022-05-05T00:00:00Z,2022-05-06T00:00:00Z",
  "aggregate": "namespace,label:app",  # 以这几个纬度进行成本聚合
  "external": True,     # 拆分集群外部的成本(比如 s3/rds/es 等),需要通过其他手段提供外部资源的成本
  "accumulate": True,   # 累加指定 window 的所有成本
  "shareIdle": False,   # 将空闲成本拆分到所有资源上
  "idleByNode": False,  # 基于节点进行空闲资源的统计
  "shareTenancyCosts": True,  # 在集群的多个租户之间共享集群管理成本、节点数据卷成本。这部分成本将被添加到 `sharedCost` 字段中
  "shareNamespaces": "kube-system,kubecost,istio-system,monitoring",  # 将这些名字空间的成本设为共享成本
  "shareLabels": "",
  "shareCost": None,
  "shareSplit": "weighted",  # 共享成本的拆分方法,weight 加权拆分,even 均分
})

resp_json = resp.json()
print(resp_json['code'])

result = resp_json['data']
print(result[0])

查询结果中有这几种特殊成本类别:

此外如果使用 kubecost 可视化面板,可能还会看到一个 other 类别,这是为了方便可视化,把成本太低的一些指标聚合展示了。

进阶用法

参考

标签:Kubernetes,FinOps,标签,资源,拆分,kubecost,成本
来源: https://www.cnblogs.com/kirito-c/p/finops-for-kubernetes.html