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

回到 2016 年,我们在 Buffer 切换到 Kubernetes,现在大约 60 个节点(在 AWS 上)和 1500 个容器正在我们的 k8s 集群上运行,由 考普斯。 然而,我们通过反复试验转向微服务,即使在使用 k8s 几年之后,我们仍然面临新的问题。 在这篇文章中我们将讨论 处理器限制:为什么我们认为它们是好的实践以及为什么它们最终不是那么好。

处理器限制和限制

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

处理器限制将容器设置为在特定时间段内可以使用的最大 CPU 时间(默认为 100 毫秒),并且容器永远不会超过此限制。 在 Kubernetes 中 节流 容器并防止其超出限制,使用专用工具 粮安委配额,但这些人为的 CPU 限制最终会损害性能并增加容器的响应时间。

如果我们不设置处理器限制会发生什么?

不幸的是,我们自己也不得不面对这个问题。 每个节点都有一个进程负责管理容器 kubelet,然后他停止响应请求。 当这种情况发生时,节点将进入状态 NotReady,并且其中的容器将被重定向到其他地方,并在新节点上产生相同的问题。 至少可以说,这不是一个理想的情况。

节流问题的表现及响应

集装箱跟踪的关键指标是 trottling,它显示您的容器已被限制的次数。 我们感兴趣地注意到某些容器中存在节流,无论处理器负载是否极端。 作为示例,让我们看一下我们的主要 API 之一:

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

如下所示,我们将限制设置为 800m (0.8或80%核心),并且峰值最好达到 200m (20% 核心)。 看起来在限制服务之前我们仍然有足够的处理器能力,但是......

Kubernetes:通过消除 CPU 限制来加速您的服务
您可能已经注意到,即使处理器负载低于指定限制(明显低于限制),仍然会发生限制。

面对这个,我们很快发现了几个资源(github上的问题, 扎达诺的介绍, 在 omio 上发帖)关于由于限制导致的服务性能和响应时间下降。

为什么我们会在低 CPU 负载时​​看到节流? 简短的版本是:“Linux 内核中存在一个错误,会导致对具有指定处理器限制的容器进行不必要的限制。” 如果您对问题的本质感兴趣,可以阅读演示文稿(视频 и 文本 选项)戴夫·奇鲁克(Dave Chiluk)。

消除 CPU 限制(极其谨慎)

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

这个决定并不容易,因为我们非常重视集群的稳定性。 过去,我们已经尝试过我们的集群不稳定,然后服务消耗了太多资源并减慢了整个节点的工作速度。 现在一切都有些不同了:我们清楚地了解了我们对集群的期望,以及实施计划变更的良好策略。

Kubernetes:通过消除 CPU 限制来加速您的服务
关于紧迫问题的商业信函。

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

隔离“不受限制”的服务:

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

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

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

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

我们最担心的是该过程会消耗太多资源并且节点将停止响应请求。 从现在开始(感谢 Datadog),我们可以清楚地监控集群上的所有服务,我分析了我们计划指定为“不相关”的服务的几个月运行情况。 我只是将最大 CPU 使用率设置为 20%,从而在节点中分配空间,以防 k8s 尝试将其他服务分配给该节点。

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

如图所示,处理器的最大负载已达到 242m CPU 核心(0.242 个处理器核心)。 对于处理器请求,取比该值稍大的数字就足够了。 请注意,由于服务以用户为中心,峰值负载值与流量一致。

对内存使用和查询执行相同的操作,瞧 - 您已全部设置完毕! 为了提高安全性,您可以添加水平 Pod 自动缩放。 因此,每次资源负载较高时,自动缩放都会创建新的 pod,kubernetes 会将它们分发到有可用空间的节点。 如果集群本身没有剩余空间,您可以为自己设置警报或通过自动缩放配置添加新节点。

在缺点中,值得注意的是我们输给了“集装箱密度“, IE。 一个节点上运行的容器数量。 在低流量密度下我们也可能有很多“放松”,并且您也有可能达到高处理器负载,但自动缩放节点应该有助于后者。

结果

我很高兴发布过去几周实验的出色结果;我们已经看到所有修改后的服务的响应有了显着改进:

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

我们在主页上取得了最好的成绩(buffer.com),服务加速 二十二次!

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

Linux内核bug修复了吗?

是的, 该错误已被修复,并且修复已添加到内核中 发行版本 4.19 及更高版本。

然而,读完后 github上的kubernetes问题 2020 年 XNUMX 月 XNUMX 日 我们仍然会提到一些具有类似 bug 的 Linux 项目。 我相信一些 Linux 发行版仍然存在这个错误,并且正在努力修复它。

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

  • Debian:修复集成到最新版本的发行版中, 克星,而且看起来很新鲜(今年八月2020)。 某些以前的版本也可能已修复。
  • Ubuntu:修复已集成到最新版本 Ubuntu Fossa 20.04
  • EKS 已修复 在12月的2019中。 如果您的版本低于此版本,您应该更新 AMI。
  • 科普斯: 2020年XNUMX月起 у kops 1.18+ 主要主机映像将是 Ubuntu 20.04。 如果您的 kops 版本较旧,您可能需要等待修复。 我们自己现在也在等待。
  • GKE(Google Cloud):修复集成 在2020年XNUMX月,但是节流存在问题 仍然被观察到.

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

我不确定问题是否已完全解决。 当我们到达包含修复程序的内核版本时,我将测试集群并更新帖子。 如果有人已经更新,我有兴趣阅读您的结果。

结论

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

我希望这篇文章可以帮助您提高容器系统的性能。

PS 这是 作者与读者和评论员通信(英文)。


来源: habr.com

添加评论