4、API优先级与公平性(APF):FlowSchema与PriorityLevelConfiguration原理
在Kubernetes多租户控制面中,API Server是唯一的请求入口。当大量请求(来自不同租户、不同组件、不同优先级)同时涌入时,如果没有精细的流量控制机制,高优先级的控制面操作(如kubelet心跳、调度器绑定)可能被低优先级的List-Watch请求淹没,导致集群不稳定。Kubernetes 1.20+引入的API优先级与公平性(APF)机制,通过FlowSchema和PriorityLevelConfiguration两个核心资源,实现了基于队列的、可配置的请求调度隔离。
4.1 APF核心设计目标
APF取代了旧的--max-requests-inflight和--max-mutating-requests-inflight全局硬限制,提供了更细粒度的控制:
- 优先级隔离:不同租户或不同请求类型使用独立的队列,避免相互影响。
- 公平调度:同一优先级内的请求按先进先出(FIFO)排队,但通过队列数和并发度控制防止饥饿。
- 拒绝降级:当队列满时,新请求被拒绝(HTTP 429 Too Many Requests),而非阻塞整个API Server。
- 可观测性:通过Prometheus指标暴露每个优先级的排队深度、拒绝次数、执行延迟。
FlowSchema(流量模式)和PriorityLevelConfiguration(优先级级别)。前者负责将请求分类,后者定义每个分类的排队与并发行为。
4.2 FlowSchema:请求分类器
FlowSchema定义了如何将进入API Server的请求映射到某个PriorityLevelConfiguration。每个请求会按顺序匹配FlowSchema列表,第一个匹配的FlowSchema决定该请求的归属。
4.2.1 FlowSchema匹配规则
每个FlowSchema包含一组rules,规则由以下维度组成:
| 匹配维度 | 描述 | 示例值 |
|---|---|---|
subjects |
请求发起者身份(用户、组、ServiceAccount) | system:serviceaccounts:kube-system |
resourceRules |
请求的资源类型、命名空间、动词(get/list/create) | pods, namespaces=default, verb=list |
nonResourceRules |
非资源请求路径(如/healthz、/api) |
/healthz, verb=get |
匹配顺序由matchingPrecedence字段控制,数值越小优先级越高。系统内置的FlowSchema(如system-leader-election、workload-high)通常具有较高的优先级。
4.2.2 内置FlowSchema示例
apiVersion: flowcontrol.apiserver.k8s.io/v1beta3
kind: FlowSchema
metadata:
name: system-leader-election
spec:
matchingPrecedence: 50
priorityLevelConfiguration:
name: leader-election
rules:
- subjects:
- kind: Group
group:
name: system:authenticated
resourceRules:
- verbs: ["get", "update"]
apiGroups: ["coordination.k8s.io"]
resources: ["leases"]
resourceNames: ["*"]
clusterScope: true
上述FlowSchema确保所有经过认证的用户对coordination.k8s.io/leases资源的get和update请求,都被路由到leader-election优先级级别。
4.3 PriorityLevelConfiguration:排队与并发控制器
PriorityLevelConfiguration定义了每个优先级级别的队列行为和并发限制。它是APF实现公平性和隔离性的核心。
4.3.1 核心参数
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
spec.limited.assuredConcurrencyShares |
int32 | 该优先级在全局并发配额中的权重,权重越高,可同时执行的请求越多 | 3 |
spec.limited.limitResponse.type |
string | 限流策略类型:Queue(队列)或Reject(直接拒绝) |
Queue |
spec.limited.limitResponse.queuing.queues |
int32 | 该优先级下的队列数量(用于实现公平性) | 64 |
spec.limited.limitResponse.queuing.handSize |
int32 | 每个请求的哈希种子数,用于将请求分配到队列 | 8 |
spec.limited.limitResponse.queuing.queueLengthLimit |
int32 | 每个队列的最大长度,超过后请求被拒绝 | 50 |
4.3.2 队列公平性原理
APF使用公平排队(Fair Queuing)算法:
- 每个请求根据其
FlowSchema和请求特征(如用户、资源)计算哈希值,映射到queues中的某个队列。 - 同一队列内的请求按FIFO顺序处理。
- 调度器以轮询方式从各队列取出请求执行,确保每个队列都能获得执行机会,防止某个队列被饿死。
- 当队列满时,新请求立即返回HTTP 429,不会阻塞其他队列。
PriorityLevelConfiguration,并设置合理的assuredConcurrencyShares。例如,kubelet心跳请求应分配较高的权重,而普通用户的List请求分配较低权重。
4.4 APF请求处理流程(SVG)
下图展示了从请求到达API Server到最终被处理或拒绝的完整APF流程:
4.5 多租户场景下的APF配置策略
在面向多租户的控制面中,APF的配置需要兼顾隔离性和资源利用率。以下是一个典型的多租户APF配置方案:
| 优先级级别 | 目标租户/组件 | assuredConcurrencyShares | 队列数 | 队列长度 | 说明 |
|---|---|---|---|---|---|
leader-election |
系统租约 | 20 | 1 | 10 | 最高优先级,确保选举不阻塞 |
node-health |
kubelet心跳 | 15 | 4 | 20 | 节点健康检查,低延迟要求 |
scheduler |
调度器绑定 | 10 | 8 | 30 | 调度操作,中等优先级 |
tenant-a-critical |
租户A关键操作 | 8 | 16 | 50 | 租户A的写操作 |
tenant-b-critical |
租户B关键操作 | 8 | 16 | 50 | 租户B的写操作 |
default |
普通用户请求 | 3 | 64 | 50 | 低优先级,大量队列防饥饿 |
default优先级,通过调整队列数实现软隔离。
4.6 APF与旧限流机制的对比
| 特性 | 旧机制(max-requests-inflight) | APF(FlowSchema + PriorityLevelConfiguration) |
|---|---|---|
| 隔离粒度 | 全局(所有请求共享一个队列) | 按优先级、按队列隔离 |
| 公平性 | 无(先到先服务,可能被大请求阻塞) | 公平排队,防止饥饿 |
| 配置方式 | 启动参数(静态) | API资源(动态,无需重启API Server) |
| 拒绝行为 | HTTP 429(无区分) | HTTP 429(可区分优先级) |
| 可观测性 | 有限(仅全局指标) | 每个优先级、每个队列的详细指标 |
| 适用场景 | 小规模集群 | 多租户、大规模、关键业务集群 |
4.7 监控与调试APF
APF暴露了丰富的Prometheus指标,用于监控每个优先级级别的状态:
# 每个优先级的当前排队请求数
apiserver_flowcontrol_current_inqueue_requests{priority_level="tenant-a-critical"}
# 每个优先级的并发执行请求数
apiserver_flowcontrol_current_executing_requests{priority_level="tenant-a-critical"}
# 请求被拒绝的总数
apiserver_flowcontrol_rejected_requests_total{priority_level="tenant-a-critical"}
# 请求在队列中的等待时间(分位数)
apiserver_flowcontrol_request_wait_duration_seconds{priority_level="tenant-a-critical"}
current_inqueue_requests是否持续增长。如果队列深度接近queueLengthLimit,说明需要增加队列长度或提高assuredConcurrencyShares。如果rejected_requests_total快速上升,则说明请求量已超过该优先级的处理能力,需要扩容或限流。
4.8 总结
APF通过FlowSchema和PriorityLevelConfiguration的组合,为Kubernetes API Server提供了强大的流量控制能力。在多租户控制面中,合理配置APF可以实现:
- 关键业务保障:系统组件(如kubelet、调度器)的请求始终优先处理。
- 租户隔离:每个租户的突发流量不会影响其他租户。
- 可预测的拒绝行为:当负载超过容量时,低优先级请求被优雅拒绝,而非整个API Server不可用。
- 动态调整:无需重启API Server即可调整限流策略,适应业务变化。