我深入了解Kubernetes资源限制,并且很难理解CPU limits
的用途。我知道Kubernetes将requests
和limits
传递给(在我的情况下)Docker运行时。
示例:我有1个节点,1个CPU和2个Pod,CPU requests: 500m
和limits: 800m
。在Docker中,这会产生(500m -> 0.5 * 1024 = 512
)--cpu-shares=512
和(800m -> 800 * 100
)--cpu-quota=80000
。 pod由Kube调度程序分配,因为requests
总和不超过节点容量的100%;就limits
而言,节点过度使用。
以上允许每个容器每100ms周期获得80ms的CPU时间(默认值)。一旦CPU使用率为100%,CPU时间就会根据其权重在容器之间共享,以CPU份额表示。根据1024的基值和每个512的份额,每个容器的50%。在这一点上 - 在我的理解中 - limits
没有更多的相关性,因为没有一个容器可以再获得它的80ms。他们都会得到50毫秒。因此,无论我定义了多少limits
,当使用率达到100%时,它仍被requests
分割。
这让我想知道:为什么我应该首先定义CPU limits
,并且过度使用会有什么不同吗?另一方面,requests
就“当所有内容正在使用时获得多少份额”而言完全可以理解。
答案 0 :(得分:0)
通过使CPU限制大于CPU请求,您 完成两件事:
- Pod可以使用恰好可用的CPU资源进行突发活动。
- Pod在突发期间可以使用的CPU资源量限制在一定的合理数量。
我想这可能让我们想知道为什么我们关心将突发限制为“一些合理的数量”,因为它可以突发的事实似乎似乎表明当时没有其他进程竞争CPU。但我发现自己对这种推理不满意......
首先,我检查了你提到的docker标志的命令行帮助:
--cpu-quota int Limit CPU CFS (Completely Fair Scheduler) quota
-c, --cpu-shares int CPU shares (relative weight)
对Linux Completely Fair Scheduler的引用意味着为了理解CPU限制/配额的值,我们需要了解底层进程调度算法的工作原理。有道理,对吗?我的直觉是,它不像根据CPU份额/请求对CPU执行进行时间分割那么简单,并且在先到先得的基础上在一些固定时间片的末尾分配剩余的东西。
我找到了this old Linux Journal article代码段,这似乎是对CFS如何运作的合理描述:
CFS试图跟踪CPU的公平份额 已经可用于系统中的每个进程。所以,CFS运行公平 时钟只是实际CPU时钟速度的一小部分。公平时钟的费率 增加的计算方法是将墙壁时间(以纳秒为单位)除以 等待的进程总数。结果值是 每个进程有权获得的CPU时间量。
当进程等待CPU时,调度程序会跟踪数量 它会用在理想的处理器上的时间。 这个等待时间, 由每任务wait_runtime变量表示,用于排名 调度和确定时间的过程 允许进程在被抢占之前执行。进程有 最长的等待时间(即最需要的CPU)是 由调度程序选择并分配给CPU。当这个过程是 运行时,其等待时间减少,而其他等待时间则减少 任务增加(因为他们在等待)。这基本上意味着 一段时间后,将会有另一项具有最长等待时间的任务 (最急需的CPU),当前正在运行的任务将是 抢占。使用这一原则,CFS试图公平地对待所有任务和 总是试图让每个系统的等待时间为零 进程 - 每个进程拥有相同的CPU份额(某事物 “理想,精确,多任务处理CPU”本来可以做到。)
虽然我没有深入研究Linux内核源代码以了解该算法是如何工作的,但我确实想要提出一些关于共享/请求和配额/限制如何发挥作用的猜测。这个CFS算法。
首先,我的直觉使我相信不同的进程/任务根据自Wikipedia claims that CFS is an implementation of weighted fair queuing以来分配的CPU份额/请求以不同的相对速率累积wait_runtime
,这似乎是一种合理的实现方式基于共享/请求的加权,在算法的上下文中尝试最小化所有进程/任务的wait_runtime
。我知道这并没有直接提到被问到的问题,但我想确保我的整体解释对于共享/请求和配额/限制这两个概念都有一席之地。
其次,关于配额/限制我直觉认为这些适用于在等待I / O时进程/任务累积了不成比例的大wait_runtime
的情况。请记住,上面引用的CFP描述会优先考虑具有最大wait_runtime
的流程/任务?如果在给定的进程/任务上没有配额/限制,那么在我看来,就像该进程/任务上的CPU使用量的爆发一样,只要它wait_runtime
减少它就会产生效果足以允许另一个任务抢占它,阻止所有其他进程/任务执行。
所以换句话说,Docker / Kubernetes中的CPU配额/限制是一种机制,允许给定的容器/ pod /进程在CPU活动中突发以在等待I / O之后赶上其他进程(而不是CPU)没有在这样做的过程中不公平地阻止其他进程也在做工作。
答案 1 :(得分:0)
设置CPU限制的一个原因是,如果将CPU请求==限制和内存请求==限制,则会为您的pod分配一个服务质量等级= Guaranteed
, which makes it less likely to be OOMKilled if the node runs out of memory。在这里,我引用了Kubernetes文档Configure Quality of Service for Pods:
为Pod提供QoS级别的保证:
- Pod中的每个容器都必须有一个内存限制和一个内存请求,并且它们必须相同。
- Pod中的每个容器都必须有CPU限制和CPU请求,并且它们必须相同。
使用Guaranteed
QoS类的另一个好处是,它允许您锁定Pod的专用CPU,这对于某些类型的低延迟程序至关重要。来自Control CPU Management Policies的引用:
static
CPU管理策略允许Guaranteed
容器中具有整数CPUrequests
的容器访问节点上的独占CPU。 ...仅将既属于Guaranteed
容器又具有整数CPUrequests
的容器分配了专用CPU。
答案 2 :(得分:0)
仅cpu份额没有上限。如果有免费循环,则可以自由使用它们。施加了限制,以使一个恶意进程不会永远占用资源。 应该有一些合理的安排。 CFS通过此处配置的limit属性强制使用cpu配额和cpu期限。
总而言之,这种属性可确保在我安排任务时,您至少需要50微秒才能完成任务。如果您需要更多时间,那么如果没有人在队列中等待,我会让您再运行几秒,但不超过80微秒。