3. APF 架构深度解析:FlowSchema 与 PriorityLevelConfiguration

APF(API Priority and Fairness)是 Kubernetes 1.20+ 引入的请求队列与并发控制机制,替代了原有的 MaxInFlight 限流器。其核心设计围绕两个 CRD 资源展开:FlowSchema 负责请求分类与优先级映射,PriorityLevelConfiguration 负责并发预算与排队策略。理解这两者的协同关系,是进行容量调优与配额校准的前提。

核心原则:APF 将 API 请求按 FlowSchema 规则分类为不同的“流”,再映射到对应的 PriorityLevel(优先级级别),每个 PriorityLevel 拥有独立的并发槽位和排队队列,从而实现细粒度的请求隔离与公平调度。

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 资源
最佳实践:为关键组件(kubelet、controller-manager、scheduler)创建独立的 FlowSchema,并设置较高的匹配优先级(如 500),确保系统组件请求不会被租户请求淹没。
FlowSchema 请求分类与匹配流程 API 请求到达 FlowSchema 列表(按 matchingPrecedence 排序) FS-1: system-leader-election (precedence=100) FS-2: system-nodes (precedence=200) FS-3: workload-default (precedence=1000) 匹配成功 → 映射到 PriorityLevel PriorityLevel: workload-high (并发配额 + 队列)

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 的请求进入同一队列,避免单个用户/命名空间阻塞其他请求。

PriorityLevel 内部排队与并发控制模型 并发槽位池(Concurrency Slots Pool) 总槽位 = 所有 PriorityLevel 的 assuredConcurrencyShares 之和 × 基础并发数 PriorityLevel 按 shares 比例分配槽位 PL: system-high shares=10, 槽位=20 队列: 64, 长度: 50 排队: Queue PL: workload-high shares=5, 槽位=10 队列: 32, 长度: 30 排队: Queue PL: workload-low shares=2, 槽位=4 队列: 16, 长度: 20 排队: Reject 请求处理 / 排队等待 请求处理 / 排队等待 直接拒绝 (429) 说明:每个 PriorityLevel 独立管理自己的队列和槽位,互不干扰 同一 PriorityLevel 内,不同 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 已分发的请求总数,评估吞吐量