在 Kubernetes 集群中,限流、降级与排队并不是单一开关,而是分布在 API Server、Ingress、调度器和应用多个层面的组合策略。一个请求从进入集群到被 Pod 处理,会经历认证、鉴权、准入控制、调度、网络转发等环节,任何一层出现资源争用,都可能引发延迟升高或请求被丢弃。要构建稳定的容量保护机制,需要同时理解 API 请求限流、入口流量控制、资源配额与调度队列,以及应用自身的降级逻辑。下面将围绕这些层次展开,并给出可直接使用的配置示例。

API Server 限流:APF 如何对请求分类、排队和限流
从 Kubernetes 1.20 起,API 优先级和公平性(API Priority and Fairness,APF)成为控制 kube-apiserver 请求并发的推荐方式。早期通过 --max-requests-inflight 和 --max-mutating-requests-inflight 参数进行全局限制,只能限制同时处理的请求总量,无法防止某个控制器或用户占用过多资源。APF 将请求划分为多个 FlowSchema,每个 FlowSchema 根据请求属性比如用户名、组、命名空间、资源类型和操作动词进行匹配,并指向一个 PriorityLevelConfiguration,从而获得独立的并发份额和队列配置。
PriorityLevelConfiguration 中的 assuredConcurrencyShares 表示该优先级在总并发中的权重份额,shares 越大,能够占用的并发越多。queues 和 handSize 控制队列数量与每次从队列中取出的请求数,queueLengthLimit 决定每个队列最多能缓存多少个请求。当队列已满且并发达到上限时,新请求会立即收到 429 Too Many Requests,而不是无限等待。exempt 优先级可以完全绕过限流,适合集群关键组件如 system:masters。
apiVersion: flowcontrol.apiserver.k8s.io/v1
kind: FlowSchema
metadata:
name: normal-user-flow
spec:
priorityLevelConfiguration:
name: normal-user-priority
distinguishingMethod:
type: ByUser
rules:
- subjects:
- kind: User
apiGroup: rbac.authorization.k8s.io
name: '*'
resourceRules:
- apiGroups:
- '*'
resources:
- '*'
verbs:
- list
- get
matchingPrecedence: 1000
---
apiVersion: flowcontrol.apiserver.k8s.io/v1
kind: PriorityLevelConfiguration
metadata:
name: normal-user-priority
spec:
type: Limited
limited:
assuredConcurrencyShares: 20
queues: 32
handSize: 8
queueLengthLimit: 16
上述配置把所有普通用户的读请求放入一个有限优先级,并发份额为 20,队列数为 32,每个队列最多缓存 16 个请求。实际调优时,可以先观察 kube-apiserver 的 apiserver_flowcontrol_request_concurrency_limit 等指标,再逐步调整 shares 和 queueLengthLimit。如果限流过紧,正常请求会被误伤;如果队列过长,请求在 API 层排队时间会显著增加,最终可能导致客户端超时。
Ingress 层限流与降级:Nginx 注解如何控制突发和溢出
入口层是外部流量进入集群的第一道门,Nginx Ingress Controller 提供了丰富的注解,可以在不修改应用代码的情况下实现限流与降级。nginx.ingress.kubernetes.io/limit-rps 限制每秒请求数,limit-burst 定义允许的突发队列大小,当突发请求超过 rps 与 burst 的组合阈值时,Nginx 会返回 503 或 429,将过载请求挡在 Pod 前面。limit-conn 则限制单个客户端 IP 的并发连接数,适合防止单 IP 占用过多长连接。
降级场景中,可以使用 Canary 注解把一部分流量切到简化后的服务版本,例如 nginx.ingress.kubernetes.io/canary 设置为 true,并通过 canary-weight 控制灰度比例。当核心服务出现延迟升高时,把读流量切到缓存服务或静态页,实现快速降级。排队策略主要依赖 burst 和 limit-rate-after 的组合:burst 允许短时间排队,limit-rate 控制超过阈值后的响应速率,形成类似令牌桶的平滑限流。
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: payment-api
annotations:
nginx.ingress.kubernetes.io/limit-rps: "50"
nginx.ingress.kubernetes.io/limit-burst: "20"
nginx.ingress.kubernetes.io/limit-conn: "10"
nginx.ingress.kubernetes.io/canary: "true"
nginx.ingress.kubernetes.io/canary-weight: "30"
spec:
ingressClassName: nginx
rules:
- host: api.ipipp.com
http:
paths:
- path: /
pathType: Prefix
backend:
service:
name: payment-api-canary
port:
number: 80
上面的 Ingress 对象同时演示了限流和灰度降级:每秒只允许 50 个请求,额外允许 20 个突发请求,单 IP 并发连接最大 10。canary 注解会把 30% 的流量切到 payment-api-canary 服务,当主服务过载时可以调整权重或直接切换。注意 limit-rps 和 limit-burst 只对单个 Ingress 规则生效,如果需要全局入口防护,可以在 ConfigMap 中配置全局限流参数。
资源配额、QoS 与调度队列:Pod 层的排队和资源隔离
在 Pod 层面,ResourceQuota 和 LimitRange 是基础限流手段。ResourceQuota 限制一个命名空间内所有 Pod 的资源总量,LimitRange 为没有显式设置 requests 和 limits 的 Pod 注入默认值,防止个别容器无限申请 CPU 和内存。requests 是调度器分配资源的依据,limits 是节点运行时强制上限,两者设置合理时,可以有效避免节点资源耗尽。Kubernetes 会根据 requests 和 limits 将 Pod 划分为 Guaranteed、Burstable 和 BestEffort 三个 QoS 等级,在节点内存或磁盘压力升高时,kubelet 会按 BestEffort、Burstable、Guaranteed 的顺序驱逐 Pod,实现底层资源紧张时的自动降级。
调度队列也有排队策略。kube-scheduler 维护 activeQ、backoffQ 和 unschedulableQ 三个队列,Pod 第一次调度失败后不会立即无限重试,而是进入 backoffQ 进行指数退避,避免频繁无效调度。通过 PriorityClass 可以为关键业务 Pod 设置更高优先级,在资源不足时抢占低优先级 Pod,保证核心服务优先获得资源。PriorityClass 的 value 越高,优先级越高,同时可以设置 preemptionPolicy 为 Never 禁止抢占。
apiVersion: v1
kind: ResourceQuota
metadata:
name: team-a-quota
namespace: team-a
spec:
hard:
requests.cpu: "10"
requests.memory: "16Gi"
limits.cpu: "20"
limits.memory: "32Gi"
---
apiVersion: scheduling.k8s.io/v1
kind: PriorityClass
metadata:
name: high-priority-apps
value: 1000000
globalDefault: false
preemptionPolicy: PreemptLowerPriority
description: 关键业务 Pod 使用的高优先级
配置 ResourceQuota 后,team-a 命名空间所有 Pod 的 CPU 请求总量不能超过 10 核,内存请求不能超过 16Gi,从源头限制单个团队抢占集群资源。PriorityClass 则给关键 Pod 赋值为 1000000,在节点资源紧张时能够抢占低优先级 Pod,但这种抢占会引发 Pod 重启,需要结合 PodDisruptionBudget 控制最小可用副本数。实际生产环境中,建议让 requests 接近实际平均使用量,limits 根据峰值设置但不要过大,否则会降低 QoS 等级,更容易被驱逐。
HPA 和就绪探针:弹性伸缩与实例级降级
限流和排队解决的是短时过载,长时流量增长则需要 HPA 自动增加副本。HPA 根据 CPU、内存或自定义指标动态调整 Deployment 的 replicas,可以在负载上升后几分钟内完成扩容。对于延迟敏感的服务,建议同时配置 ResourceQuota 和 Cluster Autoscaler,确保新 Pod 有节点可调度。如果指标采集有延迟,可以通过 external metrics 或 Prometheus 自定义指标提前发现排队长度上升,触发扩容。
就绪探针是另一种降级手段。当 Pod 内部队列过长或依赖服务不可用时,readinessProbe 可以返回失败,Service 控制器会将该 Pod 从后端列表中摘除,新的请求不再转发到该实例,直到探针恢复。应用层还可以结合本地队列和超时控制:请求进入本地队列后等待超过 200ms 直接返回降级响应,而不是继续堆积。这样的配合让排队策略从基础设施延伸到应用内部,形成更完整的保护闭环。
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: payment-api-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: payment-api
minReplicas: 3
maxReplicas: 20
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
behavior:
scaleDown:
stabilizationWindowSeconds: 300
HPA 根据平均 CPU 利用率 70% 自动调整副本数,最少 3 个,最多 20 个,并且缩容前有 300 秒稳定窗口,避免频繁抖动。还需要在 Deployment 中配置 readinessProbe,例如 HTTP GET /healthz,超时时间设置短一些,让不健康的实例快速从 Service 后端摘除。这样即使某个 Pod 内部出现线程池阻塞或依赖超时,也不会继续接收新请求,达到实例级降级效果。
Kubernetes 的限流、降级与排队不是单独某个参数能解决的,而是需要根据请求路径从 API Server、Ingress、资源调度到应用层层布防。APF 适合保护控制平面,Ingress 注解适合入口防护,ResourceQuota 和 PriorityClass 保障资源分配,HPA 和就绪探针实现动态伸缩与实例摘除。实际配置时应先明确流量模型和租户边界,然后从最外层的入口限流开始,逐步向内调整队列长度和突发阈值。限流参数设置过紧会误伤正常请求,过松则失去保护作用,建议通过监控请求拒绝率、p99 延迟和调度等待时间持续调优。
Kubernetes限流降级排队策略修改时间:2026-08-25 18:06:03