了解Kubernetes的请求和限制

您是否看到您的应用程序卡住或无法响应健康检查请求,并且找不到任何解释? 可能是因为CPU配额限制。 我们将在这里解释为什么。

容器和Kubernetes入门
Kubernetes(缩写为k8s)在现在的基础设施世界中几乎是事实上的标准。 它是一个容器编排工具。

容器
过去,我们曾经创建过诸如Java JAR / WAR或Python Eggs或Executables之类的工件,然后将它们让别人在服务器上运行它们。但是要运行它们,还有更多工作-必须安装应用程序运行时(Java / Python),适当的文件,不合适的位置,特定的OS等。它需要大量的配置管理,并且经常引起开发人员和系统管理员的痛苦。容器改变了这一点。在这里,工件是容器图像。想象它是一个胖子可执行文件,它不仅包含您的程序,而且还包含完整的运行时(Java / Python /…),预安装并准备运行的必要文件和包。它可以被运送并在各种服务器上运行,而无需任何进一步的自定义安装。
容器还可以在自己的沙盒环境中运行。他们有自己的虚拟网络适配器,自己的受限文件系统,自己的进程层次结构,自己的CPU和内存限制等。这是一个称为名称空间的内核功能。

Kubernetes
Kubernetes是容器编排工具。您给它一个机器池。然后,您会说:“嘿,kubernetes –运行10个容器映像实例,每个实例具有2个cpus和3GB RAM,并保持其运行!”。 Kubernetes负责其余的工作。它会在发现可用CPU容量的任何地方运行它们,如果它们不正常,则重新启动它们,如果我们更改版本,则进行滚动更新,依此类推。
本质上,Kubernetes抽象了机器的概念,并使它们全部成为一个部署目标。

好的,我们了解什么是容器和Kubernetes。 我们还看到,多个容器可以容纳在同一台机器中。
这就得到资源共享。 您需要一些大型(机器/节点),并与多个不同的租户(容器)共享。 Kubernetes好比是我们的租赁经纪人。 但是,如何防止所有这些租户互相争吵呢? 如果其中一位接管浴室半天怎么办? ;)
这是请求和限制出现的地方。 CPU“请求”仅用于调度目的。 就像容器的期望清单一样,主要用于找到最适合它的节点。 而CPU“限额”是租赁合同。 一旦找到容器的节点,它绝对不能超过限制。
问题就出现在这里……

Kubernetes请求和限制的实现方式
Kubernetes使用内核限制来实现CPU限制。 如果应用程序超出限制,则会受到限制(也称为更少的CPU周期)。 另一方面,内存请求和限制的实现方式有所不同,更易于检测。 您只需要检查Pod的上次重启状态是否为OOMKilled。 但是,CPU限制并不容易识别,因为k8s仅公开使用量度指标,而不公开cgroup相关量度。

CPU Request

为了简单起见,让我们讨论一下它是如何在四核计算机中组织的。
k8使用cgroup来控制资源分配(用于内存和CPU)。 它具有层次结构模型,只能使用分配给父级的资源。的详细信息存储在一个虚拟文件系统(/ SYS / FS / cgroup中)。 如果是CPU,则为/ sys / fs / cgroup / cpu,cpuacct / *。

k8s使用cpu.share文件分配CPU资源。在这种情况下,根cgroup继承了4096个CPU份额,这是可用CPU能力的100%(1核心= 1024;这是固定值)。根cgroup根据孩子的cpu.share按比例分配其份额,他们对孩子的情况也是如此,依此类推。在典型的Kubernetes节点中,根cgroup下有三个cgroup,分别是system.slice,user.slice和kubepods。前两个用于为关键系统工作负载和非k8s用户空间程序分配资源。最后一个kubepods由k8s创建,以将资源分配给pod。
如果看上图,您可以看到第一个cgroup和第二个cgroup分别具有1024个共享,而kubepod具有4096个共享。现在,您可能会认为根中只有4096个CPU共享,但是子代的总数份额超过该值(6144)。该问题的答案是,该值是逻辑值,Linux调度程序(CFS)使用该值按比例分配CPU。在这种情况下,前两个cgroup分别获得680(占4096的16.6%),而kubepod得到其余2736。但是在空闲情况下,前两个cgroup不会使用所有分配的资源。调度程序具有避免浪费未使用的CPU份额的机制。调度程序将未使用的CPU释放到全局池中,以便它可以分配给需要更多CPU功能的cgroup(它可以分批执行以避免计费损失)。相同的工作流程也将应用于所有子孙。

这种机制将确保公平地分配CPU电源,并且没有人可以从其他人那里窃取CPU。

CPU Limit

即使限制和请求的k8s配置看起来相似,实现也完全不同。 这是最具误导性和文档较少的部分。
k8使用CFS的配额机制来实现限制。 限制的配置在cgroup目录下的两个文件cfs_period_us和cfs_quota_us(cpu.share旁边)中进行配置。
与cpu.share不同,配额基于时间段,而不基于可用的CPU能力。 cfs_period_us用于定义时间段,始终为100000us(100毫秒)。 k8s具有允许更改此值的选项,但仍然具有alpha和特征门控。 调度程序使用该时间段来重置已使用的配额。 第二个文件cfs_quota_us用于表示配额期内的允许配额。
请注意,它也在us单位中配置。 配额可以超过配额期限。 这意味着您可以配置超过100ms的配额。

让我们讨论16种核心机器(Omio最常见的机器类型)上的两种情况。