3、资源配额工作原理:Admission Controller流程、配额校验生命周期、资源计数与更新机制
资源配额(ResourceQuota)是 Kubernetes 多租户隔离与资源管控的核心机制。理解其工作原理,对于正确配置配额、排查资源争用以及优化大规模集群性能至关重要。本章从 Admission Controller 流程、配额校验生命周期、资源计数与更新机制三个维度进行深度剖析。
3.1 核心组件与架构
资源配额系统由以下关键组件协同工作:
| 组件 | 角色 | 说明 |
|---|---|---|
| ResourceQuota Controller | 状态维护者 | 运行在 kube-controller-manager 中,负责配额对象的创建、更新、删除以及资源使用量的周期性重新计算。 |
| ResourceQuota Admission Controller | 准入校验者 | 作为 Kubernetes API Server 的一个准入插件,在请求持久化之前拦截并校验。 |
| kube-apiserver | 请求入口 | 接收所有资源操作请求,串联多个准入插件,最终将合法请求写入 etcd。 |
| etcd | 持久化存储 | 存储 ResourceQuota 对象定义以及当前资源使用量的快照。 |
3.2 Admission Controller 流程
ResourceQuota 作为 ValidatingAdmissionPlugin 在 API Server 的准入控制链中执行。其完整的处理流程如下:
- 请求到达:用户通过 kubectl、API 调用或控制器发起资源创建/更新请求。
- 认证与授权:API Server 首先验证请求者身份,然后检查 RBAC 权限。
- Mutating Admission:执行 MutatingWebhookConfiguration 和内置的变更准入插件(如 NamespaceLifecycle、DefaultStorageClass)。
- 对象验证:对请求体进行 Schema 校验(如必填字段、字段类型)。
- Validating Admission:执行 ValidatingWebhookConfiguration 和内置的校验准入插件,ResourceQuota 在此阶段执行。
- 配额校验:Admission Controller 读取当前 Namespace 下的 ResourceQuota 对象,计算请求资源与已用资源的和,判断是否超出硬限制。
- 持久化:校验通过后,请求对象写入 etcd。
关键点:ResourceQuota 校验发生在 Validating Admission 阶段,这意味着所有 Mutating Webhook 已经执行完毕,请求对象已经过可能的变更(如 Sidecar 注入、标签追加)。因此,配额计算的是最终持久化的资源量。
3.3 配额校验生命周期
配额校验并非只在创建时执行一次,而是贯穿资源的整个生命周期。下表展示了不同操作下的校验行为:
| 操作类型 | 是否触发校验 | 校验逻辑 | 典型场景 |
|---|---|---|---|
| 创建(Create) | 是 | 计算请求资源 + 当前已用资源 ≤ 硬限制 | 创建 Pod、PVC、Service |
| 更新(Update) | 是 | 计算新资源量 - 旧资源量 + 当前已用资源 ≤ 硬限制 | 调整 Pod 的 CPU/内存请求、扩缩容 Deployment |
| 删除(Delete) | 否 | 不触发校验,资源释放由 Controller 异步更新 | 删除 Pod、PVC |
| 状态更新(Status Update) | 否 | 不触发配额校验 | Pod 状态变为 Running |
工程实践:更新操作(如调整 Pod 的 resources.requests)会触发重新校验。如果集群中大量 Pod 同时更新资源规格,可能导致 API Server 的准入控制器负载飙升。建议在变更窗口期分批操作,或使用 PDB(PodDisruptionBudget)控制并发。
3.4 资源计数与更新机制
资源配额系统采用 两阶段计数模型:
- 阶段一:准入计数(Admission-time Accounting):在请求通过准入校验后,立即在内存中增加资源计数,防止并发请求导致超配。此计数是乐观锁的一部分。
- 阶段二:实际计数(Actual Accounting):ResourceQuota Controller 通过 List/Watch 机制,定期从 API Server 获取 Namespace 下所有资源的最新状态,重新计算实际使用量,并更新 ResourceQuota 对象的 Status 字段。
3.5 资源更新机制详解
ResourceQuota 对象的 Status 字段维护了当前 Namespace 下各类资源的实际使用量。更新机制如下:
- Watch 事件驱动:Controller 通过 Informer 监听 ResourceQuota 对象以及所有被配额追踪的资源类型(Pod、PVC、ConfigMap、Secret 等)。
- 变更触发:当任何被追踪资源发生创建、更新、删除事件时,Controller 将对应的 ResourceQuota 对象加入工作队列。
- 重新计算:Controller 从工作队列取出 ResourceQuota 对象,调用 API Server 的 List 接口获取当前 Namespace 下所有相关资源,重新计算使用量。
- 状态更新:将计算后的新使用量写入 ResourceQuota 的 Status.Used 字段,触发 Status 更新。
性能风险:在拥有大量 Namespace 和 ResourceQuota 的集群中(例如 SaaS 平台每个租户一个 Namespace),频繁的 List 操作会给 API Server 和 etcd 带来巨大压力。建议:
- 合理设置
--resource-quota-sync-period(默认 5 分钟,可适当增大到 10-15 分钟)。 - 避免为每个 Namespace 创建过多的 ResourceQuota 对象(建议每个 Namespace 只使用 1-2 个)。
- 使用
ResourceQuota的scope字段(如NotTerminating、BestEffort)减少不必要的计数范围。
3.6 关键参数与调优建议
| 参数 | 默认值 | 作用 | 调优建议 |
|---|---|---|---|
--resource-quota-sync-period |
5m | Controller 全量重新计算 ResourceQuota 的周期 | 大规模集群可调整为 10m-15m,减少 API Server 负载 |
--min-resync-period |
12h | Informer 的最小重新同步周期 | 保持默认,避免频繁全量同步 |
--concurrent-resource-quota-syncs |
5 | 同时处理 ResourceQuota 同步的工作线程数 | 当 Namespace 数量超过 1000 时,可适当提升至 10-20 |
总结:资源配额的工作原理可以概括为“准入时拦截校验 + 异步周期修正”。Admission Controller 保证请求不会立即超配,而 Controller 的异步同步机制则确保长期计数的准确性。理解这一机制,是进行配额性能调优和故障排查的基础。