页面加载中,请稍候
来源:开源Linux发布时间:2023-05-111068浏览
询问 AI
Limits 和 Requests 并不是 CPU 管理的灵丹妙药,在某些情况下,其他替代方案可能是更好的选择
在这篇博文中,您将了解到:
Requests 在 Kubernetes 中有两个目的:
首先,它们告诉 Kubernetes 需要多少 CPU 可用。然后它会过滤掉任何没有足够的 Requests 资源来完成调度的节点。
如果没有足够的 Requests CPU/内存,则 Pod 将处于未调度状态,直到有满足 Requests 的资源。

一旦确定了在哪个节点上运行 Pod(在预选阶段幸存下来,然后得分最高的节点),它就会设置 Linux CPU shares 以大致与 mCPU 指标保持一致。CPU Shares 是 Linux 控制组 cgroups 功能[3]。
通常,cpu_shares 可以是任意数字,Linux 使用每个 cgroup 的 shares 数与所有 shares 总数之间的比率来确定在 CPU 上应该调度哪个进程的优先级。例如,如果一个进程有 1,000 个 shares,所有 shares 的总和为 3,000,则它将获得总时间的三分之一。就 Kubernetes 而言:
由于设置 CPU request 是可选的,如果不设置会怎样?
如果不指定 CPU request:

还要注意,如果您没有在 Pod 上设置 Request,则会将其作为 BestEffort 服务质量(QoS),并使其最有可能从节点中被逐出。
因此,设置一个足够高的 Request 来代表容器满足需求(可用性、性能/延迟等)所需的最小值是非常重要的。

此外,假设您的应用程序是无状态的,从可用性的角度来看,向外扩展(将 Pod 分布在更多的节点上)而不是向上扩展通常是有意义的。这也意味着在调度时,更小的 pod 更容易安装到您的节点上,从而更有效地利用我们的资源。
除了请求,Kubernetes 也有 CPU 限制。限制是您的应用程序可以使用的最大资源量,但不能保证,因为它们取决于可用资源。
虽然您可以将请求视为确保容器至少具有该数量/比例的 CPU 时间,但限制却确保容器的 CPU 时间不能超过该数量。
虽然这可以保护系统上的其他工作负载免于与受限容器竞争,但它也会严重影响受限容器的性能。限制工作的方式也不直观,用户经常错误配置它们。
requests 使用 Linux cgroup CPU shares,而 limits 则使用 cgroup CPU quotas。
这些有两个主要组成部分:

如果这是一个单线程应用程序(一次只能在一个 CPU 核心上运行),那么这就很直观了。如果您将限制设置为 1 个 CPU,那么每 100 毫秒就会获得 100 毫秒的 CPU 时间,或者全部时间。问题是当我们有一个多线程应用程序可以同时在多个 cpu 上运行时。
如果您有两个线程,那么您可以在最短的 50ms 内消耗一个 CPU 周期(100ms)。10 个线程可以在 10 毫秒内消耗 1 个 CPU 周期,这样我们每 100 毫秒就会节流 90 毫秒,也就是 90%的时间!这通常会导致比没有节流的单个线程更差的性能。
另一个重要的考虑是,一些应用程序或语言/运行时将看到 Node 中的核心数量,并假设它可以使用所有的核心,而不管它的请求或限制。假设我们的 Kubernetes 节点/集群/环境在我们拥有的内核数量上不一致。在这种情况下,相同的 Limit 可能导致节点之间的不同行为,因为它们将运行不同数量的线程来对应不同数量的 core。
所以,你需要:
除非语言/运行时知道查看我们的 cgroup 并自动适应你的 Limit。
Node 是单线程的(除非你使用 worker_threads),所以如果没有它们,你的代码就不能使用一个以上的 CPU 内核。这使得它成为 Kubernetes 上扩展到更多 pod 的良好候选,而不是扩展单个 pod。
像 Node.js 一样,解释性 Python 通常是单线程的,除了一些例外(使用多处理库,C/c++扩展等),不应该使用多个 CPU。这使得它成为一个很好的候选,就像 Node.js 一样,可以扩展到 Kubernetes 上的更多 pod,而不是扩展单个 pod。
注意,如果使用它,多处理库假定 Node 的物理内核数是默认情况下应该运行的线程数。目前似乎没有办法影响这种行为,除了在代码中设置它,而不是采用默认池大小。目前 GitHub 上有一个未解决的问题[4]。
Java 虚拟机 (JVM) 现在提供自动容器/cgroup 检测支持,这允许它确定在 Docker 容器中运行的 Java 进程可用的内存量和处理器数量。它使用此信息来分配系统资源。此支持仅适用于 Linux x64 平台。如果支持,则默认启用容器支持。如果不支持,您可以使用 -XX:ActiveProcessorCount=X 手动指定 CPU 限制的核心数[5]。
与 Java 一样,提供了自动容器/cgroup 检测支持[6]。
为容器设置 GOMAXPROCS 环境变量[7]以匹配任何 CPU 限制。或者使用 automaxprocs 包[8] 根据 Uber 的容器限制自动设置。
也许您可以避免所有这些,只使用请求,因为它们讨论的是总 CPU 的比例,而不是像限制那样的 CPU 时间,因此在概念上更有意义。
限制的主要目的是确保特定的容器只能获得节点的特定份额。如果您的节点数量是相当固定的,可能是因为这是一个内部部署的数据中心,在接下来的几个月/几年里使用的裸金属节点数量是固定的,那么它们可能是维护整个多租户系统/环境的稳定性和公平性不得不接受的事。
然而,在云计算中,我们拥有的节点数量实际上是无限的,除了它们的成本。他们可以快速地提供和取消供应。这种弹性和灵活性是许多客户首先在云中运行这些工作负载的重要原因!
同样,需要多少节点直接取决于需要多少 pod 和它们的大小。需要的 pod 数量可以自动/动态地缩放,以响应在任何给定时间内要完成的工作量(请求的数量、队列中的项目数量等)。
我们可以做很多事情来节省成本,但是以一种损害其性能甚至可用性的方式限制工作负载应该是最后的手段。

让我们假设工作量增加(这会因工作负载而异,可能是请求/秒、队列中的工作量、响应的延迟等)。首先,Horizontal Pod Autoscaler (HPA) 会自动添加另一个 Pod,但没有足够的节点容量来调度它。Kubernetes Cluster Autoscaler 看到这个 Pending Pod,然后添加一个节点。
随后,工作日结束,由于要做的工作较少,HPA 缩减了几个 Pods。集群自动缩放器有足够的空闲容量来缩小一些节点,并且仍然适合所有运行的节点。因此,它排空并终止一些节点,以便为现在正在运行的较少的 Pods 调整环境的大小。
在这种情况下,我们不需要限制,只需要设置准确的请求(这样可以保证每个系统通过 CPU 共享运行所需的最小值)和集群自动定标器。这将确保不会对工作负载进行不必要的节流,并确保我们在任何给定时间都具有适当的容量。
现在您更好地了解了 Kubernetes CPU 限制,是时候检查您的工作负载并适当地配置它们了。
这通常意味着确保运行的并发线程数符合限制(尽管某些语言/运行时,如 Java 和 C# 现在可以为您做到这一点)。
而且,有时,这意味着根本不使用它们,而是依靠 Requests 和 Horizontal Pod Autoscaler (HPA) 的组合来确保您始终有足够的容量以更动态(和更少的节流)方式运行。
作者:JASON UMIKER
出处:https://sysdig.com/blog/kubernetes-cpu-requests-limits-autoscaling/
Kubernetes 限制和请求的基础知识: https://sysdig.com/blog/kubernetes-limits-requests/
[2]内存不足终止和 CPU 节流: https://sysdig.com/blog/troubleshoot-kubernetes-oom/
[3]CPU Shares 是 Linux 控制组 cgroups 功能: https://www.batey.info/cgroup-cpu-shares-for-kubernetes.html
[4]目前 GitHub 上有一个未解决的问题: https://github.com/python/cpython/issues/77167
[5]手动指定 CPU 限制的核心数: https://docs.oracle.com/en/java/javase/19/docs/specs/man/java.html#advanced-runtime-options-for-java
[6]提供了自动容器/cgroup 检测支持: https://github.com/dotnet/designs/blob/main/accepted/2019/support-for-memory-limits.md.
[7]为容器设置 GOMAXPROCS 环境变量: https://pkg.go.dev/runtime
[8]automaxprocs 包: https://github.com/uber-go/automaxprocs
10T 技术资源大放送!包括但不限于:Linux、虚拟化、容器、云计算、网络、Python、Go 等。在开源Linux公众号内回复10T,即可免费获取!
新闻来源:开源Linux,文中所述为作者独立观点,不代表icspec立场。更多精彩资讯请下载icspec App。如对本稿件有异议,请联系微信客服specltkj。
暂无评论哦,快来评论一下吧!
2026-06-08

2026-06-22

2026-06-17