使用Kubecost管理EKS成本

介绍如何在EKS上部署Kubecost免费版,解决传统成本管理不够直观的问题,实现对各Deployment/Service成本的精细化监控和管理。

EKS动手实验合集请参考这里。

EKS 1.36 版本 @2026-09 AWS Global 区域(ap-southeast-1)实测通过,Kubecost Helm Chart 版本为 3.3.0,Amazon EBS CSI Driver 插件版本为 v1.66.0-eksbuild.1,EKS Pod Identity Agent 插件版本为 v1.3.10-eksbuild.3。

一、背景

1、EKS成本分摊的难点

EKS集群的主要费用来自EC2 Nodegroup、EBS卷、负载均衡器和数据传输。这些费用在AWS账单上是以EC2实例、EBS卷等基础设施资源为维度呈现的,而一个EC2节点上通常同时运行着多个业务团队的多个Deployment。因此,仅凭账单无法直接回答“某个Namespace或某个服务每月花费多少”这一类问题。在不使用专门工具的情况下,通常只能按业务人为划分独立的Nodegroup,或者结合成本和使用情况报告(CUR,全称是Cost and Usage Report)的明细数据进行离线分析,工作量大且粒度粗。

2、EKS提供的两种成本监控方案

本文介绍如何在EKS 1.36集群上部署Kubecost,并通过浏览器与API查看各Namespace、各工作负载对应的成本。

根据EKS官方文档,EKS提供两种成本监控方案:

  • AWS Billing split cost allocation data for Amazon EKS(EKS拆分成本分配数据):AWS账单的原生功能,在CUR中将EC2成本按Pod的CPU与内存请求拆分到Kubernetes的Namespace、工作负载等维度,无需在集群内安装任何组件,可以与Cost Categories、Cost Anomaly Detection等账单功能结合使用。
  • Kubecost:Kubernetes原生的成本监控工具,在集群内运行,以接近实时的方式按Pod、Namespace、标签等维度展示成本,并提供资源规格调整(Rightsizing)等优化建议。EKS提供AWS优化版本的Kubecost(Amazon EKS optimized Kubecost bundle),可使用现有的AWS支持计划获得支持。

两种方案的对比如下:

对比 拆分成本分配数据 Kubecost
部署位置 AWS账单侧,集群内无需安装组件 集群内部署,占用节点资源与EBS存储
数据时效 以账单周期为准,存在小时级到天级延迟 部署后约25分钟开始出数,之后持续刷新
分摊维度 Namespace、工作负载、成本分配标签 Pod、Namespace、Deployment、标签等,维度更丰富
优化建议 不提供 提供Rightsizing、闲置资源等建议
使用门槛 需在账单控制台开启并使用CUR 2.0或Data Exports 通过Helm或EKS插件安装

选择拆分成本分配数据的场景:财务部门需要与其他AWS服务统一核算、不希望在集群内增加组件。选择Kubecost的场景:开发与运维团队需要在集群内实时查看成本并获得优化建议。二者也可以组合使用,账单侧用于最终结算,Kubecost用于日常观测与优化。本文介绍Kubecost的部署。

3、Kubecost v3的主要变化

Kubecost目前的主线版本为v3,与本实验此前使用的v1.x版本相比,存在如下不兼容的变化:

  • Helm Chart的地址由oci://public.ecr.aws/kubecost/cost-analyzer变更为oci://public.ecr.aws/kubecost/kubecost;
  • 原先位于cost-analyzer-helm-chart仓库develop分支的values-eks-cost-monitoring.yaml地址已经失效(返回404),需改用kubecost/kubecost仓库中与Chart版本对应的标签路径;
  • 必须通过global.clusterId参数显式设置集群标识,否则Chart会安装失败;
  • 架构中不再内置Prometheus,改为由finops-agent、aggregator、local-store等组件采集和存储数据,Dashboard由kubecost-frontend服务提供。

下面开始安装前的准备工作。

二、安装EBS CSI插件

1、为什么需要EBS CSI

Kubecost的aggregator、local-store等组件需要通过持久卷(PV,Persistent Volume)保存数据。自Kubernetes 1.23起,树内(in-tree)的EBS卷插件已迁移到EBS CSI(Container Storage Interface)驱动,集群中如果没有安装EBS CSI驱动,PVC将一直处于Pending状态,Kubecost的Chart在安装阶段也会检查kube-system下是否存在ebs-csi-controller,缺失时直接报错。

此外,EKS 1.30及以后版本新建的集群中,原有名为gp2的StorageClass不再被标注为默认StorageClass。执行如下命令查看:

kubectl get sc

返回结果如下,可看到gp2后面没有(default)标记:

NAME   PROVISIONER             RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
gp2    kubernetes.io/aws-ebs   Delete          WaitForFirstConsumer   false                  11d

因此,本文在安装EBS CSI插件时一并开启插件自带的默认StorageClass,使Kubecost的PVC可以自动使用gp3类型的EBS卷。

2、选择插件的IAM授权方式

EBS CSI控制器需要调用EC2 API创建、挂载EBS卷,因此需要IAM权限。旧版本实验在控制台上选择Inherit from node,即直接使用节点IAM角色的权限。这种方式会使节点上所有Pod都能间接获得创建和删除EBS卷的权限,不符合最小权限原则,本文不再推荐。

当前推荐使用EKS Pod Identity为插件的服务账户ebs-csi-controller-sa单独授予AmazonEBSCSIDriverPolicy权限。EKS Pod Identity依赖集群中的eks-pod-identity-agent插件,因此需要先安装该插件。如果集群已经在其他实验中安装过,可跳过下一步。

3、安装EKS Pod Identity Agent插件

执行如下命令:

eksctl create addon --cluster eksworkshop --region ap-southeast-1 --name eks-pod-identity-agent

安装完成后执行如下命令确认状态:

aws eks describe-addon --cluster-name eksworkshop --region ap-southeast-1 \
    --addon-name eks-pod-identity-agent \
    --query 'addon.{status:status,version:addonVersion}' --output json
kubectl get ds -n kube-system eks-pod-identity-agent

返回结果如下表示安装成功:

{
    "status": "ACTIVE",
    "version": "v1.3.10-eksbuild.3"
}
NAME                     DESIRED   CURRENT   READY   UP-TO-DATE   AVAILABLE   NODE SELECTOR   AGE
eks-pod-identity-agent   3         3         3       3            3           <none>          71s

4、安装EBS CSI插件并开启默认StorageClass

编写如下eksctl配置文件,请替换其中的集群名称与区域:

apiVersion: eksctl.io/v1alpha5
kind: ClusterConfig
metadata:
  name: eksworkshop
  region: ap-southeast-1
addons:
  - name: aws-ebs-csi-driver
    version: latest
    podIdentityAssociations:
      - serviceAccountName: ebs-csi-controller-sa
        namespace: kube-system
        permissionPolicyARNs:
          - arn:aws:iam::aws:policy/service-role/AmazonEBSCSIDriverPolicy
    configurationValues: |-
      defaultStorageClass:
        enabled: true

在以上配置中,podIdentityAssociations会由eksctl通过CloudFormation创建IAM Role,并将其与kube-system下的ebs-csi-controller-sa服务账户关联;defaultStorageClass.enabled: true会由插件创建一个名为ebs-csi-default-sc的默认StorageClass,卷类型为gp3。

将以上文件保存为ebs-csi-addon.yaml,执行如下命令安装:

eksctl create addon -f ebs-csi-addon.yaml

返回结果如下:

2026-09-29 20:16:36 [ℹ]  Kubernetes version "1.36" in use by cluster "eksworkshop"
2026-09-29 20:16:37 [ℹ]  pod identity associations are set for "aws-ebs-csi-driver" addon; will use these to configure required IAM permissions
2026-09-29 20:16:38 [ℹ]  deploying stack "eksctl-eksworkshop-addon-aws-ebs-csi-driver-podidentityrole-ebs-csi-controller-sa"
2026-09-29 20:16:38 [ℹ]  waiting for CloudFormation stack "eksctl-eksworkshop-addon-aws-ebs-csi-driver-podidentityrole-ebs-csi-controller-sa"
2026-09-29 20:17:08 [ℹ]  waiting for CloudFormation stack "eksctl-eksworkshop-addon-aws-ebs-csi-driver-podidentityrole-ebs-csi-controller-sa"
2026-09-29 20:17:09 [ℹ]  creating addon: aws-ebs-csi-driver

执行如下命令确认插件状态与Pod Identity关联:

aws eks describe-addon --cluster-name eksworkshop --region ap-southeast-1 \
    --addon-name aws-ebs-csi-driver \
    --query 'addon.{status:status,version:addonVersion,pia:podIdentityAssociations}' --output json

返回结果如下:

{
    "status": "ACTIVE",
    "version": "v1.66.0-eksbuild.1",
    "pia": [
        "arn:aws:eks:ap-southeast-1:133129065110:podidentityassociation/eksworkshop/a-gkfypmfweivuqxfoc"
    ]
}

再次查看StorageClass与EBS CSI的Pod:

kubectl get sc
kubectl get pods -n kube-system -l app.kubernetes.io/name=aws-ebs-csi-driver

返回结果如下,可看到新增的ebs-csi-default-sc已成为默认StorageClass:

NAME                           PROVISIONER             RECLAIMPOLICY   VOLUMEBINDINGMODE      ALLOWVOLUMEEXPANSION   AGE
ebs-csi-default-sc (default)   ebs.csi.aws.com         Delete          WaitForFirstConsumer   true                   46s
gp2                            kubernetes.io/aws-ebs   Delete          WaitForFirstConsumer   false                  11d

NAME                                 READY   STATUS    RESTARTS   AGE
ebs-csi-controller-8d7797dc5-hd6w9   6/6     Running   0          49s
ebs-csi-controller-8d7797dc5-j59vj   6/6     Running   0          49s
ebs-csi-node-bqsh9                   3/3     Running   0          50s
ebs-csi-node-ht98g                   3/3     Running   0          49s
ebs-csi-node-nv8hk                   3/3     Running   0          49s

如果希望通过控制台安装,可进入EKS集群的Add-ons标签页,点击Get more add-ons,选中Amazon EBS CSI Driver,在IAM授权位置选择EKS Pod Identity并由向导创建推荐的IAM Role,在Optional configuration settings中填写{"defaultStorageClass":{"enabled":true}},效果与以上命令一致。

至此EBS CSI部署完成。接下来安装Kubecost。

三、使用Helm安装Kubecost

1、在开发者本机上安装helm

在MacOS下执行如下命令:

brew install helm

在Windows下执行如下命令:

choco install kubernetes-helm

本文使用的Helm版本为v4.3.0,Kubecost要求Helm 3.9及以上版本。

2、查询Kubecost的最新版本

Kubecost Chart发布在ECR Public上。可以在ECR Public Gallery上查看全部版本。截至本文编写时,最新版本为3.3.0。EKS插件市场中的kubecost_kubecost插件版本略滞后于Helm Chart,本文编写时为v3.2.4-eksbuild.1。

本文在安装命令中显式指定版本号,以便安装结果可重复。values文件也使用与Chart版本号一致的标签路径,避免上游分支变动导致配置不一致。

3、安装Kubecost

执行如下命令,请将global.clusterId替换为实际的集群名称:

helm upgrade -i kubecost oci://public.ecr.aws/kubecost/kubecost --version 3.3.0 \
    --namespace kubecost --create-namespace \
    --set global.clusterId=eksworkshop \
    -f https://raw.githubusercontent.com/kubecost/kubecost/v3.3.0/kubecost/values-eks-cost-monitoring.yaml

其中values-eks-cost-monitoring.yaml将全部镜像的仓库地址设置为public.ecr.aws,即使用ECR Public上的AWS优化版本镜像,而Chart默认使用的镜像仓库是icr.io。

返回结果如下:

Release "kubecost" does not exist. Installing it now.
Pulled: public.ecr.aws/kubecost/kubecost:3.3.0
Digest: sha256:c708fc8565c68b2494c0b0cd81473365ec0fc0f53491a2e8c65635616c23f7bc
NAME: kubecost
LAST DEPLOYED: Tue Sep 29 20:18:40 2026
NAMESPACE: kubecost
STATUS: deployed
REVISION: 1
DESCRIPTION: Install complete
NOTES:
================================================================================
KUBECOST INSTALLATION SUCCESSFUL
================================================================================
Kubecost 3.3.0 has been successfully installed.
IMPORTANT: Kubecost 3.x is a major upgrade with breaking changes and a new 
architecture. Please review the release notes for migration details:
https://github.com/kubecost/kubecost/releases/tag/v3.0.0
QUICK START GUIDE
-----------------
1. Wait for pods to be Ready:
   kubectl get pods --namespace kubecost
2. Enable port-forwarding:
   kubectl port-forward --namespace kubecost svc/kubecost-frontend 9090
3. Open your browser and navigate to:
   http://localhost:9090
Note: Allow 25 minutes for Kubecost to gather metrics. A progress indicator 
will appear at the top of the UI.
TROUBLESHOOTING
---------------
Having installation issues? View our Troubleshooting Guide:
https://www.ibm.com/docs/en/kubecost/self-hosted/3.x?topic=troubleshoot-install
Copyright IBM Corp. 2019-2026

安装过程中需要注意如下问题:

  • 如果未设置global.clusterId,Chart会报错In Kubecost 3.0, .Values.global.clusterId is required to be set并中止安装。
  • 如果集群中没有EBS CSI驱动,Chart会报错MISSING EBS-CSI DRIVER WHICH IS REQUIRED ON EKS v1.23+ TO MANAGE PERSISTENT VOLUMES。
  • 在本机的Docker配置文件~/.docker/config.json中配置了凭证助手(credsStore)的情况下,Helm访问OCI仓库时可能长时间无响应。此时可在命令中追加--registry-config <一个内容为{}的空JSON文件>参数绕过本机凭证助手,ECR Public支持匿名拉取。

4、查看Kubecost运行状态

执行如下命令:

kubectl get pods -n kubecost

返回如下结果表示启动正常:

NAME                                           READY   STATUS    RESTARTS   AGE
kubecost-aggregator-0                          1/1     Running   0          114s
kubecost-cloud-cost-776fb9d655-kzjmr           1/1     Running   0          115s
kubecost-cluster-controller-6984d69746-gshmt   1/1     Running   0          115s
kubecost-finopsagent-56f55d7d48-rkrl5          1/1     Running   0          115s
kubecost-forecasting-86b565964b-57lrc          1/1     Running   0          115s
kubecost-frontend-7cff49bddd-q9b49             1/1     Running   0          115s
kubecost-local-store-544f7cc689-vbbg2          1/1     Running   0          114s
kubecost-mcp-7b6b4ccc74-7f64f                  1/1     Running   0          115s
kubecost-network-costs-nljsx                   1/1     Running   0          115s
kubecost-network-costs-ppzpm                   1/1     Running   0          115s
kubecost-network-costs-q5bjl                   1/1     Running   0          115s

其中kubecost-network-costs以DaemonSet形式运行在每个节点上,用于统计网络流量成本;其余组件以Deployment或StatefulSet形式运行。本文环境的集群安装过实验三的CloudWatch Observability插件,该插件会为新Pod自动注入4个OpenTelemetry自动埋点的Init容器,因此在启动过程中会看到Init:1/4等状态,这属于正常现象。

执行如下命令查看Kubecost创建的PVC:

kubectl get pvc -n kubecost

返回结果如下:

NAME                                          STATUS   VOLUME                                     CAPACITY   ACCESS MODES   STORAGECLASS         VOLUMEATTRIBUTESCLASS   AGE
aggregator-db-storage-kubecost-aggregator-0   Bound    pvc-7510398a-00ec-4d80-ba1d-3abf5d9bde58   128Gi      RWO            ebs-csi-default-sc   <unset>                 21s
kubecost-cloud-cost-persistent-configs        Bound    pvc-1ed20d3e-4505-42a9-84fd-245d5ef98cf3   1Gi        RWO            ebs-csi-default-sc   <unset>                 23s
kubecost-local-store                          Bound    pvc-b329d49f-bdbf-4131-8551-7c5441ec46b0   32Gi       RWO            ebs-csi-default-sc   <unset>                 23s
persistent-configs-kubecost-aggregator-0      Bound    pvc-3928857e-6c52-4543-b211-145e5a0cf635   1Gi        RWO            ebs-csi-default-sc   <unset>                 21s

注意:Kubecost默认会创建总计约162GiB的gp3卷,其中aggregator的数据库卷为128GiB,会产生持续的EBS费用。实验环境可以在安装时通过--set aggregator.aggregatorDbStorage.storageRequest=32Gi等参数调小容量;实验结束后,请按第五章的步骤删除Kubecost及其PVC。

至此Kubecost安装完成。下面访问Kubecost的Dashboard。

四、访问Kubecost

1、设置端口转发在本机查看

Kubecost v3的Dashboard由kubecost-frontend服务提供,旧版本命令中的deployment/kubecost-cost-analyzer已不存在。执行如下命令进行端口转发:

kubectl port-forward --namespace kubecost svc/kubecost-frontend 9090

返回结果如下:

Forwarding from 127.0.0.1:9090 -> 9090
Forwarding from [::1]:9090 -> 9090

打开本机浏览器,访问http://localhost:9090/查看网页。Kubecost首次启动后需要约25分钟收集指标,在此期间页面顶部会显示数据收集进度,部分页面没有数据属于正常现象。

端口转发只在本机监听127.0.0.1,适用于实验与临时查看。Kubecost的Dashboard默认没有身份认证,生产环境不应将其直接通过公网负载均衡器暴露,而应通过Ingress结合身份认证(例如ALB结合Amazon Cognito)与HTTPS加密的方式对内提供访问。

2、通过API查询成本数据

除浏览器之外,Kubecost也提供HTTP API,便于将成本数据接入其他系统。保持端口转发不中断,在另一个终端窗口执行如下命令,查询最近1小时按Namespace汇总的成本:

curl -s 'http://localhost:9090/model/allocation?window=1h&aggregate=namespace' \
  | jq -r '.data[0] | to_entries[] | [.key, (.value.totalCost*1000|round/1000)] | @tsv'

在数据收集完成之前,接口返回{"code":200,"data":[{}]},即数据为空。本文环境在安装约20分钟后开始返回数据,结果如下(单位为美元):

__idle__	0.152
amazon-cloudwatch	0.006
bigimage	0.002
default	0.003
kube-system	0.007
kubecost	0.011
kubernetes-dashboard	0
mydemo	0
phpdemo	0

其中__idle__表示节点上未被任何Pod请求(requests)占用的闲置资源成本。本文环境为3台t3.2xlarge节点、业务负载较轻,因此闲置成本占比最高,这正是Kubecost用于发现资源浪费、指导调整Nodegroup规格的依据。将aggregate参数改为controller、pod或label:<标签名>,即可按Deployment、Pod或标签维度汇总。

下面介绍清理步骤。

五、清理环境

实验完成后,执行如下命令删除Kubecost。由于Chart为部分PVC添加了helm.sh/resource-policy: keep注解,helm uninstall不会删除这些PVC,需要随Namespace一并删除:

helm uninstall kubecost --namespace kubecost
kubectl delete namespace kubecost

删除Namespace后,EBS CSI会根据StorageClass的Delete回收策略自动删除对应的EBS卷。EBS CSI插件与Pod Identity Agent插件可以保留,供后续使用持久卷的实验继续使用。

六、小结

EKS 1.36环境下部署Kubecost,需要先以EKS插件方式安装EBS CSI驱动,并解决新版本集群没有默认StorageClass的问题,本文通过插件自带的defaultStorageClass参数一步完成。EBS CSI的IAM授权推荐使用EKS Pod Identity,而不是继承节点角色的权限。Kubecost v3在Chart地址、values文件路径、必填参数与服务名称上均与v1.x不兼容,按照旧版本文档的命令无法完成安装,需要使用本文给出的新命令。

对于需要与账单统一核算的场景,建议同时开启AWS账单的EKS拆分成本分配数据功能,以账单数据作为最终结算依据,以Kubecost作为日常观测与优化工具。

参考文档

Monitor and optimize Amazon EKS cluster costs

https://docs.aws.amazon.com/eks/latest/userguide/cost-monitoring.html

Install Kubecost(Amazon EKS用户指南)

https://docs.aws.amazon.com/eks/latest/userguide/cost-monitoring-kubecost.html

Understanding split cost allocation data

https://docs.aws.amazon.com/cur/latest/userguide/split-cost-allocation-data.html

Store Kubernetes volumes with Amazon EBS

https://docs.aws.amazon.com/eks/latest/userguide/ebs-csi.html

Learn how EKS Pod Identity grants pods access to AWS services

https://docs.aws.amazon.com/eks/latest/userguide/pod-identities.html

Kubecost 3.x Amazon EKS Integration(IBM文档)

https://www.ibm.com/docs/en/kubecost/self-hosted/3.x?topic=installations-amazon-eks-integration

Kubecost v3.0.0 Release Notes

https://github.com/kubecost/kubecost/releases/tag/v3.0.0


最后修改于 2026-09-29