刘志超 译 分布式实验室

如何更有效地利用和监测Kubernetes资源?_Java

为了在Kubernetes集群中更好的可视化资源的利用率,作者开发了Kube Eagle普罗米修斯exporter,通过使用适当的机器类型和调整应用程序的资源约束,它们能够更好地适应不同的工作负载。我创建了一个名为Kube Eagle的普罗米修斯exporter(exporter是一组程序,它们分别被用来采集物理机、中间件的信息。有Prometheus官方实现的,还有更多第三方实现的),它被证明是一个很好的工具,可以在中小型集群中获得更多集群资源的可见性。最终它帮助我节省了数百美元,通过使用适当的机器类型和调整应用程序的资源约束,使它们更好地适应我的工作负载。
在深入了解Kube Eagle的优点和特性之前,让我先解释一下用例,以及为什么我们需要更好的监控。
我负责管理多个集群,每个集群有4到50个节点。集群中有大约200个不同的微服务和应用程序,为了更有效地利用可用的硬件资源,这些部署中的大多数配置了可瞬间扩展的RAM和CPU资源。这样,如果Pod确实需要可用的资源,它们可能会占用这些资源,但它们不会阻止其他应用程序在该节点上进行调度。听起来很棒,不是吗?
尽管我们的整个集群CPU(8%)和RAM使用率(40%)相对较低,但我们经常面临逐出Pod的问题。这些Pod被逐出,因为它们试图分配比节点上可用的RAM更多的内存。当时,我们只有一个仪表板来监视Kubernetes资源,看起来如下所示:
如何更有效地利用和监测Kubernetes资源?_Java_02只有使用cAdvisor指标的Grafana仪表板
使用这样的仪表板,可以很容易地找到具有较高RAM和CPU使用率的节点,这样我就可以快速识别过度使用的节点。无论如何,真正的斗争开始于你试图寻找这一问题的根因并解决它。避免Pod被驱逐的一种选项是为所有Pod设定有保障的资源(请求和限制资源是平等的)。缺点是,这会导致更糟糕的硬件利用率。在集群范围内,我们有数百GB的内存可用,但一些节点显然耗尽了RAM,而另一些节点仍然有4-10GB的空闲RAM。
显然,Kubernetes调度程序没有调度我们的工作负载,因此它们在我们的可用资源中都是平均分配的。Kubernetes调度程序必须尊重各种配置,比如亲和规则、污染(taints)和容忍、可能限制可用节点集合的节点选择器。不过,在我的用例中,这些配置没有到位。如果是这样,则根据每个节点上请求的资源来调度Pod。(如果你想深入快速学习Kubernetes,可以报名参加我们组织的为期3天的Kubernetes实战培训,一线资深讲师带你从0开始上手Kubernetes。)
将选择具有最多未预留资源并且可以满足所请求资源条件的节点来运行该Pod。对于我们的用例,这意味着我们节点上请求的资源与实际使用不一致,这就是Kube Eagle来拯救的地方,因为它为此目的提供了更好的资源监视。
我使用的大多数Kubernetes集群只运行Node exporter和Kube State Metrics来监视集群。当Node exporter报告有关磁盘使用情况、IO统计信息、CPU和RAM使用情况的指标时,Kube State Metrics会公开有关Kubernetes对象的指标,例如请求并限制CPU/RAM资源。
我们需要将使用度量与Grafana中的资源请求和限制度量结合起来,以获得解决问题的真正有价值的信息。不幸的是,使用给定的两个工具比听起来要麻烦得多,因为标签的名称不同,而且一些度量标准缺少元数据标签来轻松地组合和聚合它们。Kube Eagle为你做了这件事,这是基于它的度量创建的建议仪表板:如何更有效地利用和监测Kubernetes资源?_Java_03
如何更有效地利用和监测Kubernetes资源?_Java_04Kube Eagle仪表板(https://grafana.com/dashboards/9871)
我们能够用我们的资源识别和解决多个问题,这最终使我们节省了大量的硬件资源:

  1. 部署微服务的开发人员不知道他们的服务实际需要多少资源(或者根本不在乎)。我们没有进行监视,以便很容易地识别配置错误的资源请求,因为这需要查看资源请求和限制的使用情况。他们现在可以使用新提供的普罗米修斯度量来监视实际使用情况,并采用他们的资源请求和限制。

  2. JVM应用程序需要尽可能多的RAM。垃圾收集器只在使用内存超过75%的情况下释放内存。因为大多数服务在RAM中都是可存储的,所以JVM总是使用它。因此,我们在所有这些Java服务上的RAM使用量比预期的要高得多。

  3. 有些应用程序的RAM请求太大,导致Kubernetes调度程序跳过所有其他应用程序的这些节点,尽管实际使用率低于其他所有节点。大型RAM请求是由开发人员意外导致的,开发人员以字节指定资源请求,并意外地添加了另一个数字。20GB内存而不是2GB内存已经被请求,没有人注意到它。应用程序有3个副本,因此有3个不同的节点受到过度分配的影响。

  4. 在采用了资源约束并用适当的请求重新安排了Pod之后,我们在所有节点之间实现了相当均衡的硬件利用率。我们注意到我们可以因此关闭几个节点,然后我们注意到我们使用的是错误的机器类型(CPU优化而不是高内存机器)。在改变机器类型后,我们可以再次排除和删除更多的节点。


小结如何更有效地利用和监测Kubernetes资源?_Java_05



集群中的可扩展资源配置提供了更有效地利用可用硬件的好处,但它也可能造成麻烦,因为Kubernetes调度程序是根据资源请求进行Pod调度的。为了在不遇到问题的情况下实现更好的容器利用率,你需要一个体面的监控解决方案。Kube Eagle(普罗米修斯exporter和它的Grafana仪表板)是为此目的而创建的,可以帮助你应对这一挑战。
项目地址:https://github.com/google-cloud-tools/kube-eagle
原文链接:https://medium.com/@martin.schneppenheim/utilizing-and-monitoring-kubernetes-cluster-resources-more-effectively-using-this-tool-df4c68ec2053