在Kubernetes中使用 CPU请求/限制时,我遇到了奇怪的问题。在完全设置任何CPU请求/限制之前,我所有的服务都执行得很好。我最近开始放置一些资源配额,以避免将来资源匮乏。这些值是根据这些服务的实际使用情况设置的,但是令我惊讶的是,在添加了这些服务之后,某些服务开始大幅增加其响应时间。我的第一个猜测是我可能放置了错误的“请求/限制”,但是查看指标表明,实际上面临此问题的服务中没有一个接近那些值。实际上,其中一些更接近要求而不是限制。
然后,我开始查看CPU限制指标,发现我的所有Pod都已受到限制。然后,我将其中一项服务的限制从250m增加到1000m,而在该吊舱中看到的节流减少了,但我不明白为什么如果吊舱未达到其原来的极限(250m),我应该设置更高的限制)。
所以我的问题是:如果我没有达到CPU限制,为什么我的Pod会节流?如果Pod没有充分利用容量,为什么我的响应时间会增加?
这里有一些有关我的指标的屏幕截图(CPU请求:50m,CPU限制:250m):
CPU使用率(在这里我们可以看到此Pod的CPU从未达到其250m的限制):
将此吊舱的限制设置为 1000m 后,我们可以观察到更少的节流
kubectl top
P.S:设置这些请求/限制之前,完全没有节流(如预期)
P.S 2:我的节点都没有面临高使用率。实际上,它们都不在任何时候都使用超过50%的CPU。
谢谢!
答案 0 :(得分:4)
Kubernetes使用(完全公平调度程序)CFS配额对Pod容器实施CPU限制。有关更多详细信息,请参见https://kubernetes.io/blog/2018/07/24/feature-highlight-cpu-manager/中描述的“ CPU Manager如何工作”。
CFS是Linux功能,添加了2.6.23内核,该内核基于两个参数:cpu.cfs_period_us和cpu.cfs_quota 为了形象化这两个参数,我想从Daniele Polencic的出色博客(https://twitter.com/danielepolencic/status/1267745860256841731)中借用以下图片:
如果在K8s中配置CPU限制,它将设置期限和配额。如果在容器中运行的进程达到限制,它将被抢占并必须等待下一个时间段。它被节流了。 这就是您正在体验的效果。周期和配额算法不应视为CPU限制,如果未达到限制,则进程不受限制。 行为令人困惑,并且为此存在一个K8s问题:https://github.com/kubernetes/kubernetes/issues/67577 https://github.com/kubernetes/kubernetes/issues/51135中的建议是不要为不应限制的Pod设置CPU限制。
答案 1 :(得分:3)
如果看到documentation,则在为CPU发出Request
时看到,它实际上在Docker中使用了--cpu-shares
选项,而在Docker中实际上使用了cpu.shares属性。 }}在Linux上。因此,基于最大值为50m
,--cpu-shares=51
的值约为1024
。 1024
代表100%的股份,因此51
将是股份的4-5%。首先,这很低。但是这里重要的因素是,这与您的系统上有多少个pod /容器以及这些cpu共享(它们是否使用默认值)有关。
因此,假设您的节点上有另一个共享1024的Pod /容器,这是默认设置,并且您拥有具有4-5共享的该Pod /容器。然后此容器将获得约0.5%的CPU,而另一个容器/容器将获得 获得大约99.5%的CPU(如果没有限制)。因此,这又取决于节点上有多少个吊舱/容器以及它们的份额。
此外,cpu,cpuacct cgroup中没有很好的文档说明,但是如果您在Pod上使用Limit
,则基本上是在Docker中使用两个标志:Kubernetes docs,实际上使用了cpu.cfs_period_us和Linux上--cpu-period and --cpu--quota
的cpu.cfs_quota_us属性。这是因为cpu.shares没有提供限制,所以您可能会遇到容器占用大部分CPU的情况。
因此,就此限制而言,如果在同一节点上还有其他没有限制(或更高限制)但具有更高cpu.shares的容器,您将永远无法达到它,因为它们最终将进行优化并选择空闲的CPU。这可能是您所看到的,但再次取决于您的具体情况。
以上所有cpu,cpuacct cgroup的详细说明。