本文分享自华为云社区《kube-apiserver限流机制原理》,作者:可以交个朋友。
apiserver是kubernetes中最重要的组件,一旦遇到恶意刷接口或请求量超过承载范围,apiserver服务可能会崩溃,导致整个kubernetes集群不可用。所以我们需要对apiserver做限流处理来提升kubernetes的健壮性。
kubernetes 1.18版本之前kube-apiserver只是将请求分成了变更类型(create、update、delete、patch)和非变更类型(get、list、watch),并通过启动参数设置了两种类型的最大并发数。此时的apiserver限流能力较弱,若某个客户端错误的向kube-apiserver发起大量的请求时,必然会阻塞kube-apiserver,影响其他客户端的请求,因此高阶的限流APF就诞生了。
kubernetes1.18版本之后APF( APIPriorityAndFairness )成为kubernetes的默认限流方式。 APF以更细粒度的方式对请求进行分类和隔离,根据优先级和公平性进行处理。
两个阶段限流能力对比
限流能力 | 1.18版本前 | 1.18版本后(APF) |
---|---|---|
颗粒度 | 仅根据是否变更做分类 | 可以根据请求对象、请求者身份、命名空间等做分类 |
隔离性 | 一个坏用户可能堵塞整个系统 | 为请求分配固定队列,坏请求只能撑爆其使用的队列 |
公平性 | 会出现饿死 | 用公平性算法从队列中取出请求 |
优先级 | 无 | 有特权级别,可让重要请求不被限制 |
APF通过FlowSchema 和 PriorityLevelConfiguration两个资源配置限流策略。
FlowSchema:解决老版本分类颗粒度粗的问题。根据rules字段匹配请求,匹配规则包含:请求对象、执行操作、请求者身份和命名空间。
PriorityLevelConfiguration:解决老版本隔离性差的问题和优先级问题,并定义了限流细节(总队列数、队列长度、是否可排队)。当请求与某个FlowSchema匹配后,该请求会关联FlowSchema中指定的PriorityLevelConfiguration资源,每个PriorityLevelConfiguration相互隔离,且能承受的并发请求数也不一样。
一个FlowSchema只能关联一个priorityLevelConfiguration,多个FlowSchema可以关联同一个priorityLevelConfiguration。
PriorityLevelConfiguration并发上限 = assuredConcurrencyShares / 所有assuredConcurrencyShares之和 * apiserver总并发数。
请求与集群中的FlowSchema列表按照顺序依次匹配,每个FlowSchema的matchingPrecedence字段决定其在列表中的顺序,matchingPrecedence字段值越小,越靠前,越先进行匹配请求。
根据FlowSchema资源中的rules规则进行匹配,匹配方式可以是 “请求的资源类型”、“请求的动作类型”、“请求者的身份”、“请求的命名空间” 等多个维度。
若请求与某个FlowSchema成功匹配,匹配就会结束。FlowSchema关联着一个PriorityLevelConfiguration,每个PriorityLevelConfiguration中包含许多queue,根据FlowSchema.spec.Distinguisher字段将请求进行”分组”,根据分组来分配queue,分配queue数量由PriorityLevelConfiguration资源的handSize字段决定,如果省略该参数,则该FlowSchema匹配的所有请求都将视为同一个”分组”。
每个PriorityLevelConfiguration资源都有独立的并发上限,assuredConcurrencyShares字段为apiserver总并发数的权重占比,值越大分配的并发上限就越高,当PriorityLevelConfiguration达到并发上限后,请求会根据所属的”分组”写入固定的queue中,请求被阻塞等待。请求与queue的固定关联可以让恶意用户只影响其使用的queue,而不会影响同PriorityLevelConfiguration中的其他queue。
当PriorityLevelConfiguration未达到并发上限时,fair queuing算法从所有queue中选择一个合适的queue取出请求,解除请求的阻塞,执行这个请求。fair queuing算法能保证同一个 PriorityLevelConfiguration 中的所有queue被处理机会平等。
kubernetes原生自带了一些FlowSchema和PriorityLevelConfiguration规则,我们选择一个查看,如下图:
下面我们创建新的APF规则:当请求对象是apf命名空间中的deployment,则进行”apfpl”限流规则。
接着在apf命名空间和default命名空间分别创建deployment进行测试。apf_fs为请求被分类到的 FlowSchema 的名称,apf_pl为该请求的优先级名称。查看apiserver日志信息,见下图:
循环操作deployment,我们可以使用命令查看是否触发限流等待
kubectl get --raw /debug/api_priority_and_fairness/dump_priority_levels
返回waitingRequests非0,则代表触发最大并发数,有请求被限流进入等待队列。PriorityLevelConfiguration资源不为空闲表示已达到并发上限。
点击关注,第一时间了解华为云新鲜技术~