亚马逊AWS官方博客

如何使用 Kubecost 跟踪多租户 Amazon EKS 集群中的运营成本

Original URL: https://amazonaws-china.com/cn/blogs/containers/how-to-track-costs-in-multi-tenant-amazon-eks-clusters-using-kubecost/

 

当前,众多AWS客户使用Amazon Elastic Kubernetes Service (Amazon EKS)操作自己的多租户Kubernetes集群,将归属于各个不同团队或项目的工作负载运行在这套共享集群当中。客户也对Kubernetes的良好表现赞赏有加,包括以集中方式管理工作负载,并协助管理员通过单一API创建、更新、扩展并保护这些工作负载等。在本文中,我们将探讨几种用于拆分EKS集群运营成本的可行选项。

在交流当中,客户着重强调了对EKS集群中各租户进行成本分摊的重要意义。我们也一直在努力构建一种可在多租户Kubernetes环境中实现成本跟踪与分配的原生方法。当前,大家可以通过以下几种选项按租户分配运营成本:

  • 硬多租户 — 在专用的AWS账户中运行单独EKS集群。
  • 软多租户 — 在共享EKS集群中运行多个节点组。
  • 基于资源消耗量的开支核算 — 通过资源消耗量计算共享EKS集群中产生的成本。

硬多租户

在独立AWS账户中运行工作负载,可以说是实现成本跟踪的最简单方法。通过为专用账户中的各个租户创建一个独立的EKS集群,大家可以轻松确定集群产生的成本及其依赖项,这就回避了额外运行报告以确定各租户开支情况的问题。

但是,这种方式要求我们维护多个EKS集群,可能会增加您的AWS支出,并导致网络架构复杂化。如果集群中的服务需要与运行在其他账户内的服务进行通信,则需要在不同账户之间建立连接。如此一来,大家不仅需要为多个EKS控制平面付费,而且每当有流量经由VPC边界时,还会产生对应的网络传输费用。

最后,大家还会失去共享集群带来的效率优势:您需要在各个集群中运行用于监控、日志记录以及联网(例如服务网格)的共享组件。出于这些考虑,除非您高度依赖于分割明确的账单(除了当前工作负载产生的费用之外,不再包含任何其他支出),否则硬多租户选项可能并不适用。

软多租户

另一种实现成本划分的方法,是在单一共享集群之上为每个租户分配对应的专用节点组。您可以使用Kubernetes功能(例如节点选择器与节点亲和)来指示Kubernetes Scheduler通过各专用节点组运行租户工作负载。您也可以使用标识符(例如产品名称或团队名称)标记节点组中的EC2实例,并使用标签进行成本划分。

这种方法的缺点在于,各个节点组中可能存在未使用的冗余容量,而且您可能无法充分发挥密集打包集群的成本效益优势。

使用这种方法时,您仍然需要对共享资源进行成本划分,例如EKS控制平面、共享集群层级内各项服务(用于日志记录、监控、治理等)、弹性负载均衡(ELB)、NAT网关以及网络传输费用等。

基于资源消耗量的开支核算

在多租户Kubernetes集群当中,最为高效的成本跟踪方法就是基于工作负载消耗的实际资源量,对已发生成本进行核算。这种模式使您得以最大程度利用EC2实例资源,让不同工作负载得以共享节点,从而增加节点上的容器运行密度。

但是,按工作负载或命名空间计算成本无疑是一项艰巨的任务。要确定一组Pod所使用的资源,大家需要汇总特定时间段内各类计算资源的使用情况(包括实际使用或者预留的CPU、内存与磁盘容量),并据此得出实际运营成本。麻烦在于,容器通常生命周期较短且有可能频繁扩展,因此资源的实际使用量会随着时间推移而有所波动。换句话说,我们无法简单将单日内的资源使用量乘以三十,来估算月度账单的实际数额。要了解工作负载的成本划分,我们需要汇总一定时间范围内消耗或者保留的所有资源,并根据资源成本及使用期限评估相关费用。道理似乎简单,但实际执行起来却是困难重重。

Kubecost是一款专为成本跟踪问题而生的工具,可帮助用户根据资源使用情况对Kubernetes集群成本进行划分。遵循多租户最佳实践,您可以为每位租户创建一个命名空间,并使用Kubecost确定各租户的成本责任。此外,它还允许您按服务、部署、命名空间、标签、Pod、容器、团队以及产品整理出开支明细。

使用Kubecost,您可以跟踪租户支出,而无需创建单独的集群、或按工作节点划分工作负载。Kubecost也为多租户Kubernetes集群中的成本追溯提供一种易于实现且经济高效的方式。

关于Kubecost

Kubecost是Stackwatch开发的一种开放工具,用于提供成本监控与容量管理解决方案。其主要用例,在于实现Kubernetes集群的整体成本可见性。Kubecost使用三项指标来确定工作负载的对应成本:

  • 处于运行状态的时间
  • 消耗或保留的资源量
  • 消息或保留的资源的计费结果

Kubecost的开源版本将计费结果的存储周期限定为15天。如果需要将指标保留15天以上,您必须升级至付费版本。

Prometheus

Kubecost的默认安装选项中包含经过优化的Prometheus服务器,其中仅包含Kubecost需要使用的指标。与标准Prometheus部署相比,此优化版本将保留的指标量减少了70%至90%。当然,您也可以根据需求选择使用现有Prometheus安装。

使用Kubecost

Kubecost运行在您的集群之内。大家可以根据以下操作步骤完成安装流程。

为Kubecoast各组件创建命名空间:

kubectl create namespace kubecost

我们推荐您使用Helm安装Kubecost。如果您还没有安装Helm,请参阅在Amazon EKS上使用Helm。如果您不打算选择Helm,Kubecost还提供其他多种安装方法。本示例中使用Helm 3进行Kubecost安装。

添加Kubecost Helm repo:

helm repo add kubecost https://kubecost.github.io/cost-analyzer/

在继续之前,您需要访问kubecost.com/install以获取唯一令牌。在安装过程中,您将需要输入此令牌。

安装Kubecost:

helm install kubecost kubecost/cost-analyzer \
    --namespace kubecost \
    --set kubecostToken="<Your kubecostToken>"

 

您可以在此Helm Chart中使用自定义值。

如果您的集群已经安装有Prometheus,则可使用自定义Helm Chart以跳过kube-state-metricsnode-exporter的安装步骤。感兴趣的朋友可以点击此处,了解将自定义Prometheus与Kubecost结合使用的更多详细信息。

helm install kubecost kubecost/cost-analyzer \
    --namespace kubecost \
    --set kubecostToken="<Your kubecostToken>"

 

在默认情况下,Kubecost使用AWS公开定价计算集群(包括控制平面与数据平面)的平均成本。Kubecost允许您按照多种维度(例如命名空间、服务、部署等)对成本进行划定与切分。此外,您也可以通过附加IAM策略并授予对“成本与使用报告(Cost and Usage Report)”的访问权限,使Kubecost得以正确反映预留实例与Savings Plans的实际费率。

Kubecost仪表板

Kubecost提供一套Web仪表板,您可以通过kubectl port-forward、入口或负载均衡器进行访问。本教程将使用具有基本身份验证机制的Ingress入口。付费版本的Kubecost还支持使用SSO/SAML对指向仪表板的访问活动做出限制,同时提供不同层级的访问选项。例如,您可以强制要求特定团队的查看范围与其职能保持统一。

您可以使用前一种方法通过设备访问Kubecost仪表板:

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

 

此时,访问http://localhost:9090即可查看仪表板信息。

安装NGINX Ingress

您可以使用NGINX Ingress为那些无法访问kubectl的用户开放Kubecost仪表板。

安装NGINX Ingres控制器:

# Add Helm stable repo
helm repo add stable https://kubernetes-charts.storage.googleapis.com

# Install nginx-ingress 
helm install example-ingress stable/nginx-ingress -n kubecost

 

在示例中,我们还没有可用于Kubecost仪表板的注册域,因此需要在Ingress规范中更改主机以匹配ELB DNS名称。

导出NGINX Ingress ELB的DNS名称:

export ELB=$(kubectl get svc -n kubecost example-ingress-nginx-ingress-controller \
    -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')

 

创建一个Ingress:

echo "
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/auth-realm: Authentication Required - ok
    nginx.ingress.kubernetes.io/auth-secret: kubecost-auth
    nginx.ingress.kubernetes.io/auth-type: basic
  labels:
    app: cost-analyzer
    app.kubernetes.io/instance: kubecost
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: cost-analyzer
    helm.sh/chart: cost-analyzer-1.60.1
  name: kubecost-cost-analyzer
  namespace: kubecost
spec:
  rules:
  - host: $ELB
    http:
      paths:
      - backend:
          serviceName: kubecost-cost-analyzer
          servicePort: 9090
        path: /
" | kubectl apply -f -

 

在这里,我们将使用基础身份验证以限制指向仪表板的访问。首先创建一个密码文件:

htpasswd -c auth kubecost-admin
New password:
Re-type new password:
Adding password for user kubecost-admin

 

使用此密码文件创建一条secret:

kubectl create secret generic \
    kubecost-auth \
    --from-file auth \
    -n kubecost

 

最终入口配置应如下所示(已删除输出结果中的部分敏感行):

kubectl get ingresses. kubecost-cost-analyzer -o yaml -Kubecost provides a web dashboard that you can access either through kubectl port-forward or you can use an ingress or a load balancer to expose it outside the cluster. An ingress with basic authentication is used in this tutorial. The paid version of Kubecost also supports restricting access to the dashboard using SSO/SAML (http://docs.kubecost.com/user-management.html)and providing varying level of access.n kubecost

apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  annotations:
    nginx.ingress.kubernetes.io/auth-realm: Authentication Required - ok
    nginx.ingress.kubernetes.io/auth-secret: kubecost-auth
    nginx.ingress.kubernetes.io/auth-type: basic
  labels:
    app: cost-analyzer
    app.kubernetes.io/instance: kubecost
    app.kubernetes.io/managed-by: Helm
    app.kubernetes.io/name: cost-analyzer
    helm.sh/chart: cost-analyzer-1.60.1
  name: kubecost-cost-analyzer
  namespace: kubecost
spec:
  rules:
  - host: aa777bde02780402173825f8fb4c6c6-1099488085.us-west-2.elb.amazonaws.com
    http:
      paths:
      - backend:
          serviceName: kubecost-cost-analyzer
          servicePort: 9090
        path: /
status:
  loadBalancer:
    ingress:
    - ip: 192.168.130.94

 

现在,您可以使用Ingress访问Kubecost仪表板了。您也可以通过访问ELB地址直接查看仪表板内容,该地址获取方式如下:

echo https://$ELB

 

系统将提示您接受证书,具体方式视您使用的浏览器而定。

Kubecost仪表板可帮助您按命名空间等维度,深度剖析每月资源运行率,同时支持以CSV格式导出报告结果。

您可以运行报告以查看共享集群中各项服务产生的费用。Kubecost还支持报告保存功能,您可以随时访问常用报告以实现成本溯源。

成本优化建议

Kubecost还提供一系列成本节约选项。它能够帮助大家查找未使用的存储卷、过渡配置的副本或者已被遗弃的工作负载。您可在Savings下查看被遗弃的工作负载,了解哪些Pod从未接收过任何有意义流量(meaningful traffic)。您也可以调整流量阈值与持续时间,借此找出使用度较低的Pod。

Kubecost使用AWS竞价实例数据馈送提供准确的竞价资源定价,大家能够据此随时调整Pod大小。Kubecost还跟踪已声明的容器requests,并根据使用情况提供优化建议。随附的Grafana仪表板,则可向您展示集群中各类资源的实际利用率。

集群大小调整

Kubecost会根据Kubernetes原生指标提供正确的大小调整建议,其中具体涉及两项主要输入:其一,您自己对集群上所运行的工作类型做出的描述(例如开发、生产、高可用性等);其二,检测各项工作负载的历史资源需求“态势”(以Kubecost指标衡量),而后结合不同的启发式或合并策略满足集群运行要求。

总结

在本文中,我们挖地 如何在共享EKS环境中使用Kubecost跟踪成本。如果您选择硬多租户机制,则可以使用各个集群内的不同Kubecost实例对工作负载分别进行成本跟踪。此外,您也可以升级至Kubecost付费版本,通过单一仪表板对多个集群进行成本可视化与资源使用跟踪。

EKS项目经理Nathan Taber表示,“客户应该将多租户方案视为在运营便捷性与强大控制力之间求取平衡的重要工具。一方面,在单一集群上运营大量工作负载当然非常简单,但却较难审计与控制;另一方面,只在每个账户中使用一套集群虽然易于审计与控制,但一旦集群数量过多,则会迅速提升运营复杂性。正确的决定,取决于您需要运行的集群数量、实际组织结构以及您选择的多集群/账户管理工具。”无论选择哪种模式,大家都可以使用Kubecost以了解、划分并降低成本。目前,Kubecost已经正式登陆 AWS Marketplace

扩展阅读

Other options for Kubernetes cost allocation include Spot.io’s OceanCloudability, and YotascaleEKS Workshop also has a module that includes an Ocean walkthrough.

Kubernetes提供的其他成本划分选项还包括Spot.io OceanCloudability以及YotascaleEKS Workshop中还提供一套包含Ocean演练示例的模块

 

本篇作者

Re Alvarez-Parmar

Re Alvarez-Parmar是Amazon Web Services公司容器专业解决方案架构师。他帮助客户使用AWS容器服务设计出可扩展且高度安全的应用程序。他现居纽约,您可以通过@realz在Twitter上关注他