4. API Server 限流机制:APF 对 Controller-Manager 查询的影响

在 Kubernetes 控制面中,API Server 是唯一与 etcd 交互的组件,也是所有客户端(包括 Controller-Manager)的请求入口。当集群规模增长或控制器出现异常重试时,API Server 可能面临突发流量冲击。Kubernetes 1.20 起默认启用 APF(API Priority and Fairness) 作为内置的请求队列与限流机制,取代了旧的 --max-requests-inflight 简单限流。APF 对 Controller-Manager 的 List-Watch 请求、周期性 Re-list 以及 Informer 重试行为有直接影响,理解其工作原理是优化 Operator 控制面查询的关键前提。

4.1 APF 核心架构与请求分类

APF 将每个到达 API Server 的请求按 FlowSchema 匹配规则分类,再分配到对应的 PriorityLevelConfiguration 队列中。每个优先级级别拥有独立的并发配额和排队深度,从而保证高优先级请求(如节点心跳、系统关键控制器)不会被低优先级请求(如大规模 List 查询、用户调试命令)阻塞。

APF 请求处理流水线 API 请求 FlowSchema 匹配规则 PriorityLevel 并发配额 + 排队 请求执行 APF 放行 排队队列(Queue) HandSize: 4 QueueLengthLimit: 50 Queues: 8 关键参数说明 • FlowSchema:按请求属性(用户、组、资源、动词)匹配,决定请求归属的优先级级别。 • PriorityLevelConfiguration:定义并发数(ConcurrencyShares)、排队队列数(Queues)、队列长度(QueueLengthLimit)。 • 排队算法:使用公平排队(Fair Queuing)结合混洗分片(Shuffle Sharding),防止单一客户端饿死其他请求。

4.2 Controller-Manager 请求的 FlowSchema 匹配

Controller-Manager 使用 system:serviceaccount:kube-system:controller-manager 身份发起请求。Kubernetes 内置的 FlowSchema 规则会将其匹配到 system 或 workload-high 优先级级别。以下是默认 FlowSchema 对 Controller-Manager 请求的分类情况:

FlowSchema 名称 匹配规则 优先级级别 典型请求
system 用户组 system:authenticated 且资源为 nodes/healthz system(最高) 节点心跳、Leader Election
workload-high 服务账户 kube-system 命名空间,动词 list/watch workload-high Informer List-Watch、Re-list
workload-low 服务账户 kube-system,动词 get/update workload-low 状态更新、Patch 操作
global-default 未匹配其他规则的请求 global-default 自定义控制器、用户请求
关键观察:Controller-Manager 的 Informer List-Watch 请求通常被归入 workload-high 优先级,这意味着它们与节点心跳等系统关键请求共享较高的并发配额。但如果集群中存在大量自定义控制器也使用 kube-system 服务账户,可能导致 workload-high 队列积压,进而影响 Controller-Manager 的 Re-list 延迟。

4.3 APF 对 Controller-Manager 查询的具体影响

APF 对 Controller-Manager 的影响主要体现在以下三个场景:

4.3.1 Informer 初始 List 与 Watch 建立

当 Controller-Manager 启动或 Informer 因 Watch 断开需要重新同步时,会发起 List 请求 获取全量对象。如果此时 workload-high 优先级队列已满(默认 QueueLengthLimit=50),List 请求将被排队等待。在大型集群(10k+ Pods)中,List 请求可能消耗数秒甚至数十秒才能被 APF 放行,导致控制器启动延迟。

4.3.2 周期性 Re-list 与 Watch 重连

Informer 默认每 5~10 分钟执行一次 Re-list(全量重新同步)。如果 APF 队列中积压了大量低优先级请求,Re-list 可能被延迟执行,导致 Informer 缓存与 etcd 状态出现短暂不一致。对于 Operator 而言,这意味着控制器可能基于过期缓存做出决策。

4.3.3 控制器异常重试风暴

当某个控制器因资源版本冲突或网络抖动频繁重试时,APF 的排队机制会将其请求限制在队列中,避免直接打满 API Server 的并发连接。但若重试频率过高,同一 FlowSchema 下的其他控制器(包括核心 Controller-Manager)也会受到影响,因为队列是优先级级别共享的。

避坑提示:不要将自定义 Operator 的服务账户放在 kube-system 命名空间下,否则其请求会与 Controller-Manager 共享 workload-high 优先级队列。建议为每个 Operator 创建独立的 FlowSchema 和 PriorityLevelConfiguration,将其归入 workload-low 或自定义的 operator 优先级,避免干扰核心控制面。

4.4 监控 APF 对 Controller-Manager 的影响

Kubernetes 通过 apiserver_flowcontrol_* 指标暴露 APF 的运行状态。以下是需要重点关注的指标:

指标名称 类型 含义 告警阈值建议
apiserver_flowcontrol_current_inqueue_requests Gauge 当前排队中的请求数 > 10 持续 5 分钟
apiserver_flowcontrol_request_queue_length_after_enqueue Histogram 请求入队后的队列长度 分位数 P99 > 30
apiserver_flowcontrol_request_wait_duration_seconds Histogram 请求在队列中的等待时间 P99 > 2s
apiserver_flowcontrol_dispatched_requests Counter 已放行的请求总数 与排队数对比,判断是否拥塞
优化建议:在 Prometheus 中配置以下告警规则,及时发现 Controller-Manager 受 APF 影响的情况:
# 当 workload-high 优先级队列等待时间超过 1 秒时告警
- alert: APFWorkloadHighQueueLatency
  expr: |
    histogram_quantile(0.99,
      sum(rate(apiserver_flowcontrol_request_wait_duration_seconds_bucket{
        priority_level="workload-high"
      }[5m])) by (le)
    ) > 1
  for: 5m
  labels:
    severity: warning
  annotations:
    summary: "workload-high 优先级队列 P99 等待时间超过 1 秒"

4.5 优化 APF 配置以保障 Controller-Manager 查询

针对 Controller-Manager 的查询特点,可以通过调整 PriorityLevelConfiguration 来优化其 APF 表现:

  1. 提升 workload-high 的并发份额:默认 ConcurrencyShares=20,如果集群中核心控制器较多,可提升至 30~40。
  2. 增加队列深度:将 QueueLengthLimit 从默认 50 提升到 100~200,避免突发 List 请求被直接拒绝。
  3. 为 Operator 创建独立优先级:避免自定义控制器与 Controller-Manager 共享队列。
  4. 调整 FlowSchema 匹配顺序:确保 Controller-Manager 的请求优先匹配到高优先级规则。
APF 优化前后对比:Controller-Manager 请求等待时间 优化前(默认配置) • workload-high 队列深度:50 • ConcurrencyShares:20 • 自定义控制器共享同一队列 • P99 等待时间:3~5 秒 • Re-list 延迟:可能超时 优化后(推荐配置) • workload-high 队列深度:200 • ConcurrencyShares:40 • 自定义控制器独立优先级 • P99 等待时间:< 0.5 秒 • Re-list 稳定在 1 秒内完成

4.6 实战:调整 Controller-Manager 的 APF 配置

以下 YAML 示例展示如何为 Controller-Manager 创建专用的 PriorityLevelConfiguration 和 FlowSchema,确保其 List-Watch 请求获得优先处理:

apiVersion: flowcontrol.apiserver.k8s.io/v1beta3
kind: PriorityLevelConfiguration
metadata:
  name: controller-manager
spec:
  type: Limited
  limited:
    assuredConcurrencyShares: 30
    limitResponse:
      queuing:
        queues: 16
        handSize: 4
        queueLengthLimit: 200
      type: Queue
---
apiVersion: flowcontrol.apiserver.k8s.io/v1beta3
kind: FlowSchema
metadata:
  name: controller-manager
spec:
  priorityLevelConfiguration:
    name: controller-manager
  rules:
  - subjects:
    - kind: ServiceAccount
      serviceAccount:
        name: controller-manager
        namespace: kube-system
    resourceRules:
    - verbs: ["list", "watch"]
      apiGroups: ["*"]
      resources: ["*"]
验证方法:应用上述配置后,通过 kubectl get prioritylevelconfiguration controller-manager -o yaml 确认配置生效。然后使用 kubectl get --raw /metrics | grep apiserver_flowcontrol 观察 controller-manager 优先级级别的队列长度和等待时间是否显著下降。