Kubernetes:通过消除CPU限制来加速您的服务

早在2016年,我们在Buffer切换到Kubernetes,现在大约60个节点(在AWS上)和1,500个容器正在运行kop的k8s集群中工作尽管如此,我们还是通过反复试验改用微服务,即使在使用k8s几年后,我们仍然面临新的问题。在这篇文章中,我们将讨论处理器限制:为什么我们认为它们是一个很好的实践,以及为什么它们最终并没有那么好。



CPU限制和节流



与许多其他Kubernetes用户一样,Google强烈建议您调整CPU限制。如果没有此配置,则节点中的容器将占用所有处理器的能力,这又将导致重要的Kubernetes进程(例如kubelet)停止响应请求。因此,设置CPU限制是保护节点的好方法。



处理器限制将容器设置为可以在特定时间段内使用的最长处理器时间(默认为100毫秒),并且容器永远不会超过此限制。 Kubernetes使用特殊工具CFS Quota限制容器并防止其超出限制。但是,最终,这种人工处理器会限制性能降低并增加容器的响应时间。



如果不设置CPU限制会怎样?



不幸的是,我们自己不得不处理这个问题。每个节点都有一个负责管理容器的进程kubelet,并且它已停止响应请求。发生这种情况时,该节点将进入状态NotReady,并且来自该节点的容器将被重定向到其他位置,并且将在新节点上产生相同的问题。温和地说,这不是理想的情况。



出现节流和响应问题



跟踪容器的关键指标是trottling容器已被限制多少次。我们感兴趣地注意到某些容器中存在节流,无论处理器上的负载是否最大。例如,让我们看一下我们的主要API之一:







如下所示,我们将限制设置为800m(核心的0.8或80%),并且峰值最大为200m(核心的20%)。在限制服务之前,我们似乎仍然有很多处理器能力,但是...





您可能已经注意到,即使处理器上的负载低于指定的限制-低得多-节流仍然有效。



面对这样,我们很快(一个发现了很多资源,在GitHub上的问题,一个上zadano介绍,一对OMIO后)由于节流关于服务的性能和响应时间的下降。



为什么在CPU使用率较低的情况下会出现节流?简短的版本是这样的:“ Linux内核中存在一个错误,该错误会触发对具有指定处理器限制的容器进行不必要的限制。” 如果您对问题的性质感兴趣,可以阅读演示文稿(视频文本 变体)由Dave Chiluk撰写。



删除处理器限制(非常谨慎)



经过长时间的讨论,我们决定从所有直接或间接影响用户关键功能的服务中删除处理器限制。



由于我们高度重视集群的稳定性,因此决定很困难。过去,我们已经对集群的不稳定进行了试验,然后这些服务消耗了太多资源并减慢了整个节点的工作。现在,一切都有些不同:我们对集群的期望有了清晰的了解,并且对实施计划的变更有很好的策略。





在紧迫问题上的商务往来。



删除限制时如何保护您的节点?



隔离“无限”服务:



过去,我们已经看到一些节点进入状态notReady,主要是由于服务消耗了太多资源。



我们决定将此类服务放置在单独的(“标记”)节点中,以免它们干扰“链接”的服务。结果,通过标记一些节点并向不相关的服务添加容忍参数,我们获得了对群集的更多控制,并且使我们更容易识别节点问题。要自己执行类似的流程,您可以熟悉文档







分配正确的处理器和内存请求:



最重要的是,我们担心该进程会消耗太多资源,并且该节点将停止响应请求。从现在开始(由于使用了Datadog),我们可以清楚地观察到集群上的所有服务,因此我分析了我们计划指定为“无关”的服务运行了几个月。我仅将最大CPU利用率设置为20%的余量,因此在k8s尝试将其他服务分配给节点的情况下在节点中分配了空间。







从图中可以看到,最大处理器负载已达到242mCPU内核(0.242处理器内核)。对于处理器请求,只需取一个比该值稍大的数字即可。请注意,由于服务是以用户为中心的,因此负载峰值与流量一致。



对内存使用和查询执行相同的操作,瞧-一切就绪!为了提高安全性,您可以添加吊舱的水平自动缩放。因此,每当资源负载很高时,自动缩放都会创建新的Pod,而kubernetes会将它们分配到具有可用空间的节点上。如果群集本身没有剩余空间,则可以设置警报或通过自动缩放配置新节点的添加。



在缺点中,值得注意的是,我们已经失去了“容器密度”,即 一个节点中工作的容器数。在低流量密度下,我们可能还会有很多“沉迷”,您也有可能会达到较高的处理器负载,但是节点自动扩展应该可以帮助后者。



结果



我很高兴在过去的几周内发布了这些出色的实验结果,我们已经注意到所有修改后的服务在响应方面都







取得了显着改善:我们在主页(buffer.com上取得了最佳效果,该服务被加速了22倍!







Linux内核错误是否已修复?



是的,该错误已得到修复,并且此修复程序已添加到发行版4.19和更高版本的内核中



但是,虽然 2020年9月2日阅读了github上的kubernetes问题但我们仍然遇到一些带有类似错误的Linux项目参考。我相信某些Linux发行版仍然存在此bug,目前正在修复。



如果您的发行版版本低于4.19,建议您更新到最新版本,但是无论如何,您都应尝试删除处理器限制,并查看节流是否仍然存在。在下面可以找到管理Kubernetes服务和Linux发行版的不完整列表:





如果修复程序解决了节流问题,该怎么办?



我不确定问题是否已经完全解决。当我们使用固定的内核版本时,我将测试集群并更新文章。如果有人已经更新,我想感兴趣地查看您的结果。



结论



  • 如果您在Linux下使用Docker容器(与Kubernetes,Mesos,Swarm或其他无关紧要),您的容器可能会由于节流而损失性能。
  • 尝试更新到发行版的最新版本,以希望该错误已得到修复;
  • 消除处理器限制将解决问题,但这是一种危险的技术,应格外小心(最好先更新内核并比较结果);
  • 如果您取消了处理器限制,请仔细监视处理器和内存使用情况,并确保处理器资源超过消耗量;
  • 一个安全的选择是在硬件负载高的情况下自动缩放Pod以创建新Pod,以便kubernetes将其分配给空闲节点。


希望本文有助于您提高容器系统的性能。



PS在这里,作者与读者和评论员保持通信(英语)。




All Articles