忽视Kubernetes资源管理会让你身陷险境

无所事事、一刀切和蛮力是三种常见的但失败的 Kubernetes 资源大规模管理策略。

译自 Neglect Kubernetes Resource Management at Your Peril,作者 Rafael Brito。

2016 年,我作为一家大型银行的平台工程经理,为数百名用户开放了第一个 Kubernetes 集群,当时我借用了“良性忽视”这个词。

这种 据称 良性的忽视是关于管理 Kubernetes 资源原语的。虽然我理解 迁移到 Kubernetes 允许我们限制每个容器使用的最小和最大资源,这是我们在传统网格计算系统中无法做到的,但它也带来了许多新的挑战。首先,我需要确定为这些约束设置适当的值。随后,我需要教育用户如何以及为什么要使用它们。

我决定先设置一些宽松的默认值,并希望“Kubernetes 无形之手”能神奇地处理计算资源,直到有人提出一个更有效的解决方案。我的计划只用了几天就失败了,用户抱怨由于资源不足,他们无法调度 Pod。与此同时,内部虚拟化团队打电话给我,对整个集群在虚拟化层只有 15% 的 CPU 利用率感到困惑,但数百名用户却无法访问可用资源。

这就是我了解到我的忽视远非良性的方式。我的 Kubernetes 之旅一开始就遇到了困难。

为什么需要管理 Kubernetes 资源

为了避免在我的 Kubernetes 推出过程中出现广泛的问题,需要对管理 Kubernetes 资源 采取一种细致入微的方法。具体来说,我需要一种不同的策略来管理 Kubernetes 提供的用于限制资源的两个关键设置。

在 Kubernetes 配置中,请求用于设置容器保证访问的最小资源,而限制则限制容器在一个节点上可以消耗的最大资源。它们共同允许用户隔离 CPU 和内存。虽然这些概念上很简单,但找到最佳值可能极具挑战性——尤其是在规模化的情况下。

我在 2016 年的经历揭示了一些由于没有有效管理资源 请求和限制 而导致的主要问题领域。第一个是可靠性差和性能不可预测。当工作负载请求的资源太少时,它们就会供应不足,导致节点上的资源争用(这会导致 CPU 节流、内存不足杀死和 Pod 驱逐)。第二个是云成本高。当工作负载请求的资源超过其需求时,它们就会供应过度,导致节点利用率低,这会导致云账单比必要高出两到三倍。

随着我沿着现在看来是典型的资源管理旅程前进,我发现了一个第三个核心问题领域:让工程团队不堪重负。在规模化的情况下,手动调整资源会很快让开发人员和平台团队不堪重负。

以这种艰难的方式学习是一段混乱的经历。让我们更详细地了解这些挑战在我作为 平台工程 经理在 Kubernetes 采用初期是如何发生的。

第 1 阶段:资源管理的“不作为”解决方案

Kubernetes 资源管理 旅程中,人们通常从根本上不设置请求和限制开始。这会成为一个问题,因为当工作负载没有足够的资源时,应用程序会受到可靠性差、性能不可预测或中断的影响。

当资源请求过低或根本没有设置时,Kubernetes 调度程序会将 Pod 过密地放置在节点上,阻止每个 Pod 获取其所需的 CPU 或内存资源。我已经从网格计算的经验中吸取了教训,这也是我被选中领导 Kubernetes 实施的原因之一。我知道无法正确分配 CPU 和内存会导致严重的生产问题。

由于网格计算平台无法为单个工作负载隔离 CPU 资源,我们经常遇到停机、处理延迟和其他重大性能问题。每天运行数百万个任务,影响非常大。但对内存使用量的缺乏限制却更糟。随着时间的推移,我们经历了滚雪球效应,内存泄漏会导致节点宕机,将所有其他任务发送到剩余的节点,这些节点也存在内存泄漏。有一段时间,由于缺乏隔离,我们每月都会在网格上遇到停机,导致内存泄漏和/或失控进程。

由于我多次被这些网格停机困扰,我有效地跳过了资源管理旅程的这一阶段,并在“第一天”设置了请求和限制,但大多数人并没有从一开始就意识到这一点。

阶段 2:‘一刀切’解决方案

了解未设置请求和限制的性能影响后,我采取了一种一刀切的方法。我选择设置一个慷慨的默认资源配额(每个命名空间占整个集群容量的 3%),并开始为用户提供服务。

虽然我们在短短几天内成功配置了 120 个命名空间,但我们已经为用户提供了高达我们拥有资源的 360% 的资源(仅有 10% 的 CPU 利用率和 30% 的内存)。如果我们当时在生产环境中运行,我们的集群成本将在几天内增加三倍。

当我发布第一个集群时,我天真地认为,默认设置慷慨的请求和限制将提供平稳的入职体验。不久之后,开发人员将了解 pod 使用情况并在第二次通过时对其进行微调。我错了。

开发人员将慷慨的默认值视为理所当然,从未回头。如果被要求选择更合适的资源级别,他们本能地选择了工作负载在虚拟机 (VM) 上运行时所需的资源级别,这通常远高于所需级别。成本也更高,但开发人员的首要任务是性能。他们没有动力避免过度配置,这就是它如此普遍的原因。很明显,我需要找到另一种解决方案。

阶段 3:‘蛮力’解决方案

在 Kubernetes 首次推出后的几周内,一个循环场景上演了。用户抱怨他们的 pod 由于缺乏集群资源而处于挂起状态。我们减少了默认请求和限制,并重新启动了所有工作负载以使用新值,这非常具有破坏性。在此过程中,一些正在运行的 pod 由于缺乏集群资源而暂时无法调度。

虽然释放集群资源是有益的,但某些工作负载无法使用新的默认请求和限制值启动。这导致了通过匆忙添加自定义请求和限制值来修复它们的紧急情况。同时,用户打电话问我发生了什么事。真是乱七八糟!

与此同时,更多应用程序和用户被接入,因为我们现在有了资源,但我们很快又回到了起点,缺乏集群资源,因此用户无法调度 pod。最终,我将默认请求和限制设置为非常小的值,以激励(或基本上强迫)开发人员部署他们的 CPU 和内存请求

这种蛮力解决方案在很多方面都存在缺陷。手动优化请求本身就是一项繁琐的任务,但更令人痛苦的是,你不能只设置它们然后就忘记它们——它们需要持续关注。监控 pod 上的资源消耗以根据应用程序使用情况重新配置设置至关重要。一个持续的调整-监控-调整循环可以确保可靠性和性能,同时 控制云成本,但这对开发人员来说意味着大量的手动工作。就像被困在一个他们永远无法摆脱的仓鼠轮上。

开发人员并不是唯一感到痛苦的人。在这个阶段,许多用户来找我寻求有关设置请求和限制的指导,他们期望我的平台工程团队单独对每个应用程序进行故障排除。这变成了一系列乏味的对话,在这些对话中,平台工程师向开发人员询问了一些关于他们的应用程序是如何构建的以及它如何消耗资源的常识问题。

更复杂的是,一些问题非常复杂,解决它们需要多学科技能——将平台工程师转变为混合基础设施站点可靠性工程师 (SRE)、软件工程师和 CI/CD 专家。我可以看到,随着时间的推移,这种影响将导致平台团队构建广泛的工具来支持这些工作,从而导致已经人手不足的团队持续的开发和运营负担。

虽然这种蛮力解决方案有点用,但它不科学,而且需要大量的体力劳动,这在规模化时行不通。我知道我们需要一个更自动化的解决方案,但当时它并不存在。

最终解决方案:机器学习和自动化

几年后,我终于找到了一个精确设置所有 Pod 请求和限制的解决方案,而无需“猜测”、“手动劳动”或复杂的运营负担。当我被邀请帮助构建一个平台来发现、聚合和编写指标以供用于自动应用 Kubernetes 的机器学习使用时,我立即认识到了它的价值。

通过持续计算并自动应用最佳的资源请求和限制组合,像 StormForge Optimize Live 这样的工具可以帮助平台团队避免性能下降、停机、高云成本和糟糕的开发人员体验。

忽视 Kubernetes 资源管理不是你可以负担得起的选择。现在,你不再 需要 做出这个选择。看看如何让机器学习和自动化为你完成它,免费试用 Optimize Live 或在我们的沙盒环境 中玩一玩。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注