3. APF 架构深度解析:FlowSchema 与 PriorityLevelConfiguration
APF(API Priority and Fairness)是 Kubernetes 1.20+ 引入的请求队列与并发控制机制,替代了原有的 MaxInFlight 限流器。其核心设计围绕两个 CRD 资源展开:FlowSchema 负责请求分类与优先级映射,PriorityLevelConfiguration 负责并发预算与排队策略。理解这两者的协同关系,是进行容量调优与配额校准的前提。
3.1 FlowSchema:请求分类与优先级映射
FlowSchema 定义了如何将进入 API Server 的请求归类,并指定其归属的 PriorityLevel。每个请求会按 matchingPrecedence(匹配优先级,数值越小优先级越高)依次匹配 FlowSchema,一旦命中即停止匹配。
| FlowSchema 字段 | 作用 | 调优要点 |
|---|---|---|
matchingPrecedence |
匹配顺序,数值越小越优先 | 系统内置 FlowSchema 通常占用 1000-2000 范围,自定义建议使用 500-900 |
rules |
匹配规则(subjects + resources + verbs) | 规则越具体越好,避免通配符导致意外匹配 |
distinguisherMethod |
区分请求来源的方式(ByUser / ByNamespace) | 多租户场景建议使用 ByNamespace 实现租户级公平 |
priorityLevelConfiguration |
映射的目标 PriorityLevel 名称 | 必须引用已存在的 PriorityLevel 资源 |
3.2 PriorityLevelConfiguration:并发控制与排队机制
PriorityLevelConfiguration 定义了每个优先级级别的并发预算和排队行为。每个 PriorityLevel 拥有独立的 并发槽位(concurrency slots),请求在槽位不足时进入队列等待,队列满则直接拒绝(429 Too Many Requests)。
| PriorityLevel 字段 | 说明 | 调优建议 |
|---|---|---|
spec.limited.assuredConcurrencyShares |
保证并发份额(相对值) | 系统组件建议 5-10,租户级建议 1-3 |
spec.limited.limitResponse.type |
限流类型:Queue / Reject | 关键组件用 Queue,非关键用 Reject |
spec.limited.limitResponse.queuing.queues |
队列数量(默认 64) | 高并发场景可增至 128,避免队列竞争 |
spec.limited.limitResponse.queuing.handSize |
哈希种子数(默认 8) | 保持默认,调整 queues 更有效 |
spec.limited.limitResponse.queuing.queueLengthLimit |
单队列最大长度(默认 50) | 延迟敏感场景建议 20-30,吞吐优先可 100 |
assuredConcurrencyShares 设置过大。所有 PriorityLevel 的 shares 之和决定了总并发预算的分配比例。如果某个级别设置过高,会挤占其他级别的并发槽位,导致低优先级请求被频繁排队或拒绝。
3.3 排队机制与公平调度
APF 使用 公平排队(Fair Queuing) 算法,结合 分片哈希(Shuffle Sharding) 实现请求级别的公平调度。每个 PriorityLevel 内部维护多个队列,请求通过 distinguisher 计算哈希后分配到特定队列,同一 distinguisher 的请求进入同一队列,避免单个用户/命名空间阻塞其他请求。
3.4 并发控制计算模型
APF 的并发控制基于 总并发预算(Total Concurrency Budget) 的分配。API Server 启动时根据 --max-requests-inflight 和 --max-mutating-requests-inflight 计算总槽位数,然后按各 PriorityLevel 的 assuredConcurrencyShares 比例分配。
PL_i 的保证槽位数 = 总槽位数 × (PL_i.shares / 所有 PL.shares 之和)实际可用槽位 = 保证槽位 + 其他 PL 未使用的槽位(可借用)
当某个 PriorityLevel 的保证槽位未被完全使用时,空闲槽位可以临时借给其他负载较高的 PriorityLevel,实现资源利用率最大化。但每个 PriorityLevel 的 借用上限 受限于其配置的 queuing 参数和系统总预算。
3.5 请求分类与优先级实战配置
以下是一个生产环境的 FlowSchema 与 PriorityLevel 配置示例,适用于多租户集群:
apiVersion: flowcontrol.apiserver.k8s.io/v1beta3
kind: FlowSchema
metadata:
name: system-kubelet
spec:
matchingPrecedence: 500
distinguisherMethod:
type: ByUser
rules:
- subjects:
- kind: ServiceAccount
serviceAccount:
name: kubelet
namespace: kube-system
resources:
- apiGroups: [""]
resources: ["nodes", "pods", "events"]
verbs: ["get", "list", "watch", "update", "patch"]
priorityLevelConfiguration:
name: system-high
---
apiVersion: flowcontrol.apiserver.k8s.io/v1beta3
kind: PriorityLevelConfiguration
metadata:
name: system-high
spec:
type: Limited
limited:
assuredConcurrencyShares: 10
limitResponse:
type: Queue
queuing:
queues: 64
handSize: 8
queueLengthLimit: 50
- 确认每个 FlowSchema 的
matchingPrecedence不冲突,系统组件优先 - 检查 PriorityLevel 的
assuredConcurrencyShares总和是否合理(建议 20-50) - 监控
apiserver_flowcontrol_request_wait_duration_seconds指标,排队延迟超过 1s 说明需要扩容或调整 shares - 观察
apiserver_flowcontrol_rejected_requests_total,拒绝数突增说明队列长度或并发槽位不足
3.6 监控与调试命令
| 命令/指标 | 用途 |
|---|---|
kubectl get flowschemas |
查看所有 FlowSchema 及其匹配优先级 |
kubectl get prioritylevelconfigurations |
查看所有 PriorityLevel 及其并发配置 |
kubectl describe flowschema <name> |
查看 FlowSchema 详细匹配规则和命中统计 |
apiserver_flowcontrol_current_inqueue_requests |
当前排队中的请求数,判断队列压力 |
apiserver_flowcontrol_dispatched_requests_total |
已分发的请求总数,评估吞吐量 |