3. APF 核心组件:FlowSchema 与 PriorityLevelConfiguration 详解
API 优先级与公平性(APF)是 Kubernetes 1.20+ 默认启用的请求排队机制,用于替代旧的 MaxInFlight 限流。APF 通过两个核心 CRD 资源——FlowSchema 和 PriorityLevelConfiguration——实现精细化的请求分类与排队控制。理解这两个组件是调优 APF 队列、保障 etcd 水位稳定的前提。
3.1 核心概念与职责划分
APF 将请求处理分为两个阶段:分类(由 FlowSchema 完成)和 排队(由 PriorityLevelConfiguration 完成)。
| 组件 | API 版本 | 核心职责 | 关键字段 |
|---|---|---|---|
| FlowSchema | flowcontrol.apiserver.k8s.io/v1beta3 | 将入站请求按规则匹配到指定优先级级别 | spec.priorityLevelConfiguration, spec.rules |
| PriorityLevelConfiguration | flowcontrol.apiserver.k8s.io/v1beta3 | 定义每个优先级级别的队列数、并发度、排队行为 | spec.limited.assuredConcurrencyShares, spec.limited.limitResponse |
关键原则: 一个 FlowSchema 必须引用一个已存在的 PriorityLevelConfiguration。多个 FlowSchema 可以指向同一个优先级级别,实现请求聚合。
3.2 FlowSchema:请求分类引擎
FlowSchema 通过一组规则(rules)对请求进行匹配。每个规则包含 subjects(请求来源)和 resourceRules(请求目标)。匹配顺序由 spec.matchingPrecedence 决定,数值越小优先级越高。
3.2.1 内置 FlowSchema 示例
apiVersion: flowcontrol.apiserver.k8s.io/v1beta3
kind: FlowSchema
metadata:
name: kube-controller-manager
spec:
matchingPrecedence: 800
priorityLevelConfiguration:
name: workload-high
rules:
- subjects:
- kind: ServiceAccount
serviceAccount:
name: kube-controller-manager
namespace: kube-system
resourceRules:
- verbs: ["*"]
apiGroups: ["*"]
resources: ["*"]
clusterScope: true
namespaces: ["*"]
调优提示: 自定义 FlowSchema 时,matchingPrecedence 建议设置在 1000~9999 之间,避免与内置系统 FlowSchema(通常 ≤1000)冲突。数值越小,匹配优先级越高。
3.2.2 匹配规则字段详解
| 字段 | 可选值 | 说明 |
|---|---|---|
| subjects.kind | User, Group, ServiceAccount | 请求身份类型 |
| resourceRules.verbs | get, list, watch, create, update, patch, delete, * | 匹配的 HTTP 动词 |
| resourceRules.apiGroups | apps, batch, "", * | API 组,空字符串表示核心组 |
| resourceRules.resources | pods, deployments, nodes, * | 资源类型 |
| resourceRules.clusterScope | true, false | 是否匹配集群范围资源 |
| resourceRules.namespaces | ["*"], ["default"], [] | 匹配的命名空间列表 |
3.3 PriorityLevelConfiguration:排队与并发控制
PriorityLevelConfiguration 定义每个优先级级别的 队列数量、并发度 和 排队策略。APF 使用 公平排队(Fair Queuing) 算法,确保低优先级请求不会饿死高优先级请求。
3.3.1 核心参数
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
| spec.limited.assuredConcurrencyShares | int32 | 3 | 并发份额,决定该级别可获得的并发执行配额 |
| spec.limited.limitResponse.type | string | Queue | 限流类型:Queue(排队)或 Reject(直接拒绝) |
| spec.limited.limitResponse.queuing.queues | int32 | 64 | 队列数量,建议为 2 的幂次 |
| spec.limited.limitResponse.queuing.handSize | int32 | 8 | 哈希种子数,影响请求分布均匀性 |
| spec.limited.limitResponse.queuing.queueLengthLimit | int32 | 50 | 每个队列的最大排队请求数 |
3.3.2 内置优先级级别
Kubernetes 默认创建 6 个 PriorityLevelConfiguration,覆盖从系统关键请求到低优先级批处理任务的全场景。
| 优先级级别名称 | 并发份额 | 队列数 | 队列长度 | 适用场景 |
|---|---|---|---|---|
| system | 30 | 64 | 50 | kubelet、kube-scheduler 等系统组件 |
| workload-high | 40 | 64 | 50 | 控制器管理器、关键工作负载 |
| workload-low | 100 | 64 | 50 | 普通 Pod 创建、更新 |
| global-default | 20 | 64 | 50 | 未匹配到其他 FlowSchema 的请求 |
| catch-all | 5 | 64 | 50 | 兜底级别,防止请求丢失 |
| exempt | N/A | N/A | N/A | 豁免级别,不排队直接执行 |
注意: exempt 级别没有限流参数,所有匹配到该级别的请求直接通过。只有系统关键组件(如 kube-apiserver 自身健康检查)应使用此级别。切勿将用户请求误配到 exempt。
3.4 FlowSchema 与 PriorityLevelConfiguration 的关联关系
下图展示了请求从进入 API Server 到最终执行的完整 APF 处理流程:
3.5 调优实践:如何设计 FlowSchema 与 PriorityLevel
3.5.1 设计原则
- 隔离关键路径: 将 kubelet 心跳、kube-scheduler 绑定、控制器管理器的 list-watch 请求映射到高并发份额的优先级级别。
- 限制批量操作: 将 Job/CronJob 创建、大规模 Pod 删除等批量操作映射到低并发份额级别,防止突发流量冲击 etcd。
- 避免过度细分: 优先级级别建议控制在 8~12 个以内,过多级别会导致队列管理开销增加。
- 监控调整: 通过
apiserver_flowcontrol_*指标观察每个优先级的排队深度、拒绝率和等待时间,动态调整并发份额。
3.5.2 自定义 FlowSchema 示例
apiVersion: flowcontrol.apiserver.k8s.io/v1beta3
kind: FlowSchema
metadata:
name: ci-pipeline-workloads
spec:
matchingPrecedence: 2000
priorityLevelConfiguration:
name: ci-pipeline-priority
rules:
- subjects:
- kind: ServiceAccount
serviceAccount:
name: jenkins
namespace: ci
resourceRules:
- verbs: ["create", "delete", "deletecollection"]
apiGroups: ["batch"]
resources: ["jobs", "cronjobs"]
namespaces: ["*"]
---
apiVersion: flowcontrol.apiserver.k8s.io/v1beta3
kind: PriorityLevelConfiguration
metadata:
name: ci-pipeline-priority
spec:
type: Limited
limited:
assuredConcurrencyShares: 10
limitResponse:
type: Queue
queuing:
queues: 32
handSize: 6
queueLengthLimit: 20
调优建议: 对于 CI/CD 流水线等突发性批量操作,建议将 queueLengthLimit 设置为 20~30,避免队列堆积导致 etcd 写放大。同时降低 assuredConcurrencyShares 至 10~20,限制并发写入速率。
3.6 常见问题与排查思路
| 现象 | 可能原因 | 排查方法 |
|---|---|---|
| API Server 响应延迟飙升 | 某个优先级级别队列深度过高 | 查看 apiserver_flowcontrol_current_inqueue_requests 指标 |
| 请求被频繁拒绝(429) | queueLengthLimit 过小或并发份额不足 | 检查 apiserver_flowcontrol_rejected_requests_total 指标 |
| etcd 写入延迟增加 | 低优先级请求占用过多并发执行槽 | 降低 workload-low 的 assuredConcurrencyShares |
| 高优先级请求仍被排队 | FlowSchema 匹配顺序错误或优先级级别配置不当 | 检查 matchingPrecedence 数值,确保高优先级数值更小 |
避坑指南: 不要直接修改内置的 system 和 exempt 优先级级别。如需调整系统组件行为,应创建新的 FlowSchema 并引用自定义 PriorityLevelConfiguration,保留内置配置作为回退。