API优先级和公平性Alpha

作者: Min Kim(Ant Financial),Mike Spreitzer(IBM),Daniel Smith(Google)

该博客介绍了“ API优先级和公平性”,这是Kubernetes 1.18中的新alpha功能。 API优先级和公平性允许集群管理员将控制平面的并发性划分为不同的加权优先级。每个到达kube-apiserver的请求都将被分类为优先级之一,并获得其在控制平面吞吐量中的合理份额。

这能解决什么问题?

如今,apiserver具有一种简单的机制来保护自己免受CPU和内存超载的侵害:变异和只读请求的动态上限。除了区分变异和只读以外,请求之间没有其他区分;因此,可能会有不希望的情况,其中一个请求子集排挤其他请求。

简而言之,对于Kubernetes工作负载而言,意外地对api服务器进行DoS太容易了,导致其他重要的流量(例如系统控制器或领导者选举)间歇性地失败。在最坏的情况下,一些损坏的节点或控制器可以将繁忙的群集推到边缘,从而将本地问题转变为控制平面故障。

我们如何解决这个问题?

新功能“ API优先级和公平性”旨在推广每个api服务器中现有的运行中请求处理程序,以使行为更加智能和可配置。总体方法如下。

  1. 每个请求都由一个 流模式。流模式说明与之匹配的请求的优先级,并为这些请求分配“流标识符”。流标识符是系统如何确定请求是否来自同一源。
  2. 优先级可以配置为以几种方式运行。每个优先级都有自己的隔离并发池。优先级还引入了无法立即处理的排队请求的概念。
  3. 为了防止任何一个用户或名称空间垄断优先级,可以将它们配置为具有多个队列。 “随机分片” 用于将请求的每个流分配给队列的子集。
  4. 最后,当有能力处理请求时, “公平排队” 算法用于选择下一个请求。在每个优先级内,队列之间甚至公平竞争。

早期结果非常有希望!看看这个 分析.

我该如何尝试呢?

您需要准备以下内容才能试用该功能:

  • 下载并安装大于v1.18.0版本的kubectl
  • Enabling the new API groups with the command line flag --runtime-config="flowcontrol.apiserver.k8s.io/v1alpha1=true" on the kube-apiservers
  • Switch on the feature gate with the command line flag --feature-gates=APIPriorityAndFairness=true on the kube-apiservers

成功启动kube-apiserver后,您将在集群中看到一些默认的FlowSchema和PriorityLevelConfiguration资源。这些默认配置旨在为群集提供常规保护和流量管理。 您可以通过运行常用工具来检查和自定义默认配置,例如:

  • kubectl get flowschemas
  • kubectl get prioritylevelconfigurations

这是如何工作的?

到达处理程序后,将请求分配给恰好一个优先级,并在该优先级内恰好分配一个流。因此,了解FlowSchema和PriorityLevelConfiguration的工作方式将有助于您管理通过kube-apiserver的请求流量。

  • FlowSchema:FlowSchema将标识PriorityLevelConfiguration对象以及计算请求的“流标识符”的方式。当前,我们支持根据以下条件匹配请求:发出请求的身份,动词和目标对象。身份可以在以下方面进行匹配:用户名,用户组名称或ServiceAccount。至于目标对象,我们可以通过apiGroup,resource [/ subresource]和命名空间进行匹配。

    • 流标识符用于随机分片,因此,如果请求来自同一来源,则必须具有相同的流标识符,这一点很重要!我们喜欢考虑“大象”(发送很多/繁重的请求)与“老鼠”(发送很少/轻的请求)的场景:确保大象的请求都具有相同的流标识符很重要,否则它们看起来像系统中的许多不同鼠标一样!
    • 请参阅API文档 这里 !
  • PriorityLevelConfiguration:定义优先级。

    • 对于apiserver自身的请求以及任何可重入的流量(例如,它们自己发出API请求的准入Webhook),可以将优先级标记为“免除”,这意味着不会进行任何排队或限制。这是为了防止优先级倒置。
    • 每个非豁免优先级级别都配置有多个“并发份额”,并获得了一个隔离的并发池以供使用。当该优先级未满时,它将在该池中运行,再也不会在其他任何位置运行。每个apiserver都配置有一个总的并发限制(取为变异请求和只读请求的旧限制的总和),然后按优先级与它们的并发份额成比例地在优先级之间进行分配。
    • 非豁免优先级可以选择多个队列和一个“手大小”以用于随机分片。随机分片以比一致性哈希更好的方式将流映射到队列。给定的流可以访问少量队列,并且为每个传入请求选择最短的队列。当“优先级”具有队列时,它还会设置队列长度的限制。对请求可以在队列中等待多长时间也有一个限制。这是apiserver的请求超时的固定比例。无法执行且无法排队(不再)的请求被拒绝。
    • 或者,非豁免优先级可以选择立即拒绝,而不是在队列中等待。
    • API文档 为此功能。

少了什么东西?什么时候会有测试版?

我们已经在计划基于Alpha的一些增强功能,随着用户向我们的社区发送反馈,还会有更多增强功能。以下是它们的列表:

  • WATCH和EXEC请求的流量管理
  • 调整和改进默认的FlowSchema / PriorityLevelConfiguration集
  • 增强此功能的可观察性
  • 加入讨论 这里

根据对结果的估计值,可能会不同地对待LIST请求。

我该如何参与?

一如既往!懒散地到达我们 #sig-api-machinery,或通过 邮件列表。我们有许多令人兴奋的功能可以构建,并可以使用各种帮助。

非常感谢到目前为止获得此功能的贡献者:Aaron Prindle,Daniel Smith,Jonathan Tomer,Mike Spreitzer,Min Kim,Bruce Ma,余廖,Mengyi Zhou!