5 个方法,快速降低公有云中 K8S 集群成本!
技术
作者:Dmytro Dyachuk
译者:夏天
2018-06-07 02:45

针对在云中运行 Kubernetes 的不同公司,我做了一些调研并总结了关于如何降低成本的经验。接下来,我将介绍 5 个可能导致成本超支的问题以及解决这些问题的方法。

Pod 过大

对于 Pod 的设置进行限制和请求,通常的做法是使用标准模板。如果请求可以描述在节点上调度 Pod 的 CPU 和内存的最低要求,那么限制就可以描述 Pod 在该节点上能消耗的最大 CPU 和内存量。
大多数时候,工程师们都会通过“猜测”来设定初始极限,然后将其翻倍来保证安全。他们通常会作出这样的“承诺”:在知道更多信息以后就会马上作出改变。可是,你懂的,这个“以后”从来没有发生过......一直这样做的结果是,随着时间的推移,整个集群的占用空间会逐渐膨胀,然后超过集群内运行的实际服务需求。试想一下,如果每个容器只使用分配容量的 50%,并且集群资源始终占据 80%,那就意味着集群的 40% 容量被分配出去但不被使用或者就是被浪费了。针对这种情况,其实我们可以有一些不同的应对方法。

你可以做的第一件,也是最简单的事情就是使用 Grafana 和 Prometheus 进行监控,并定期检查每个 Pod 的 CPU 和内存利用率。然后,利用每个 Pod 中 99% 的 CPU 和内存决定新的、更优质的限制。
使用 Vertical Pod Auto-scaler (VPA) 是解决这个问题的另一种方法。 VPA 可以自动化实现工程师们的“承诺”(上文中“在知道更多信息以后就会马上作出改变”)。它通过监控 Pod 的 CPU 和内存利用率来终止 Pod,并利用新的限制重新启动 Pod 来对限制进行相应的调整。VPA 胜任两个工作:如果 Pod 过大,VPA 会根据观察到的内存利用率缩小 Pod。如果由于分配的内存不足导致 Pod 被 OOM 杀死,VPA 将以较大的内存限制重启 Pod 。VPA 在处理 CPU 供应不足的问题时也使用类似方法,即通过中断预算以避免不断重新启动。

另一种处理这种情况的方式,是在不调整 Pod 大小的情况下使用 Horizontal Pod Auto-scaler (HPA)。在不调整 Pod 大小的情况下,与把对 CPU 和内存的需求与访问这些 Pod 的流量相关联相比,直接增加 Pod 数量可能更容易一些。其实这正是 HPA 的工作。HPA 可以被 CPU、内存使用率或使用自定义应用程序指标触发。有关使用自定义指标设置 HPA 的具体信息,请参阅 Mark Luksa 撰写博客文章[1]。

错误节点规模和类型

越小的节点越需要占用较多的相对操作系统空间,同时还会增加管理开销。节点越小,资源搁置数量就越多。因为要调度的 Pod 太大不能声明,所以这里说的搁置资源,就是那些空闲但没有被分配给任何一个 Pod 的 CPU 或内存。在下一篇文章中,我会深入探讨集群最大利用率的问题。

这里有一个简单的图表可以显示搁置资源的百分比与节点容量的关系。服务器容量可以通过其可容纳的 pod 数量来衡量。如你所见,如果 Pod 的大小接近节点(服务器)的大小,那么搁置资源的百分比就会变得更高。由此我们可以得到这样一个经验:如果节点可容纳 10 个 Pod,那么由于搁浅资源造成的损失仅为 5%。

我调研的大多数公司都提到,他们都会在 M 型实例上运行他们的 workload。或者,你也可以使用具有较高 CPU 与内存比率的 C 型实例。

那么究竟哪种实例类型更适合使用?从正式的角度来看,这是一个简单的动态编程问题。我已经安装了 Google 表格计算器(Google Sheet calculator)——请检查“Instance types (实例类型)”选项卡。这个计算器可以根据搁置资源和操作系统开销的百分比,以及 pod 大小和数量估算每月的 EC2 帐单。你可以通过复制文档更新你计划运行的 Pod 数量以及每个 Pod 的平均大小,这个计算器会帮你找到最便宜的实例大小和类型。

错误的实例类别

On-demand Instance、Reserved Instance或 Spot Instances 哪个最好? 其中,On-demand Instance 的价格是最贵的,在灵活性和可靠性方面它的表现也是最好的。Reserved Instances 在定价和灵活性之间做了折中。Spot Instances 取了节点可靠性与定价之间的折中。我认为,最简单的选择原则应该是定期(例如每季度)修改实例分配,如果你的机队规模在一段时间内都没有改变,那就从 On-demand Instance 切换到 Reserved Instances 吧。


在上面的图表中,我将这个过程可视化并且与一个逐渐增长但波动的 workload 例子结合起来。这个算法让你既可以享受使用 Reserved Instances 带来的成本降低,同时也保留了使用 On-demand Instances 的灵活性。

超额提供的存储

通常,大家都很少考虑挂载到节点的 volume 的大小。AWS 主要提供两种类型的存储:本地存储和 EBS 存储。后者又分成不同的类别:GP,IO1,ST1 和 SC1。虽然本地存储免费提供选定的实例列表,但 EBS 存储占成本比重的 20-40%。通过研究分配的 EBS 数量与使用率,可以发现多达 50% 的 volume 实际上(> 60%)是超额提供的。

最简单的补救方法就是检查 volume 大小,将其与分配的大小进行比较,然后再重新调整大小。最重要的一步是要考虑 volume 和 IOPS 需求的增长。我已经制作了一个简单的电子表格,展示了应该怎么做[ Google文档 ][2]。

通过 AWS API,可以确定增加 volume 的大小。但缩小规模并不那么简单。最近,我看到了 Andrew Trott 展示了缩小 EBS  volume 的简单步骤的文章[3]。通过一些脚本,这个过程可以实现完全自动化。

如果你想完全消除 EBS 成本,可以考虑使用 Rook。只需选择一些具有本地 SSD 存储的实例,Rook 就会推出 Ceph。Ceph 是一个分布式存储系统。它将来自多个服务器的本地存储联合起来,并以预分配 volumes 形式提供给 Pod。

丢失和遗弃的资源

配置脚本中的 bug、错误配置和人为错误可能会导致大量资源丢失。这包括可以使用的几乎所有资源类型,例如不属于任何集群的实例,不属于任何服务的 Pod 和 Deployment,公共 IP,ELB,挂载的 EBS volume,备份等等。处理这种情况非常简单,但可能需要引入一些组织规则。以下是这些规则可能的例子:

  • 每个资源都有一个所有者; 所有者可以使用标签声明。很多组织都在努力获得云资源的所有权。我的下一个建议可能有点苛刻,那就是你可以引入一个脚本来删除所有没有所有者的资源。通常,一旦实施了这样的规则,你会立即发现这些资源的所有者。
  • 定期检查利用率。零流量的资源自动进入驱逐清单。
  • 联系每一个驱逐清单上的资源拥有者,并声明该资源的业务环境。有时候,这些资源可能在开发中的关键系统的一部分。

从我的专业经验来看,驱逐清单上的资源可能占使用资源总量的 30-40%。这些在清单上的项目,有 95% 不会带来任何商业价值。所以即使这个工作听起来很复杂,但是一旦完成你就会努力是非常值得。

总结

Kubernetes 允许在同一节点上共同分配应用程序,这可以显著缩减 AWS 成本。然而,实例的大小不正确,volume,实例和资源丢失可能会导致 Kubernetes 集群成本的增加。简单的收集指标和云账单的调查以及一些电子表格可以帮助你将总成本减少 30-50%。在文中,我已经分享了一个简单的计算器,它可以帮助你找到最适合的实例大小,搁置资源的开销,并能够使用线性回归进行 IOPS(Input/Output Operations Per Second)和规模设计的模板。希望我的建议可以帮助到你。

原文链接:https://medium.com/@dyachuk/why-do-kubernetes-clusters-in-aws-cost-more-than-they-should-fa510c1964c6

参考文献:[1]https://medium.com/@marko.luksa/kubernetes-autoscaling-based-on-custom-metrics-without-using-a-host-port-b783ed6241ac[2]https://docs.google.com/spreadsheets/d/e/2PACX-1vSho3u3KVf5_bbaOiDU1IQrbuYrwQOTG3vG1tqsYZx7u5VqIqt58Ega5JZsquL3F7-tZXWWk75SX2sg/pubhtml?gid=0&single=true[3]https://medium.com/@andtrott/how-to-downsize-a-root-ebs-volume-on-aws-ec2-amazon-linux-727c00148f61

76 comCount 0