2. 资源配额基础:Kubernetes ResourceQuota 与 LimitRange 的概念、工作原理、在升级场景中的角色
2.1 为什么升级场景必须关注资源配额?
在 Kubernetes 集群升级过程中,控制面组件(kube-apiserver、kube-controller-manager、kube-scheduler)和节点上的 kubelet 都会经历版本变更。此时,ResourceQuota 和 LimitRange 作为准入控制插件,会在 API 请求处理路径上执行校验。如果配额配置不当,升级期间可能发生以下问题:
- Pod 创建失败:新版本的控制器或 Operator 尝试创建临时 Pod(如迁移 Pod、健康检查 Pod),但配额不足导致调度阻塞。
- 资源超分导致节点压力:LimitRange 未正确设置默认请求/限制,升级过程中突增的 Pod 可能耗尽节点资源。
- 滚动更新卡死:Deployment 滚动更新时,旧 Pod 未及时终止,新 Pod 因配额不足无法启动,造成更新停滞。
升级前必查项:检查所有命名空间的 ResourceQuota 和 LimitRange 配置,确保升级期间有足够的“弹性配额”余量(建议预留 10%~20% 的 CPU/内存配额缓冲)。
2.2 ResourceQuota 概念与工作原理
ResourceQuota 是命名空间级别的资源约束对象,用于限制该命名空间内所有 Pod 和对象的资源使用总量。其核心字段包括:
| 资源类型 | 示例字段 | 说明 |
|---|---|---|
| 计算资源 | requests.cpu, requests.memory, limits.cpu, limits.memory |
限制所有 Pod 的 CPU/内存请求和上限总和 |
| 存储资源 | requests.storage, persistentvolumeclaims |
限制 PVC 总容量和数量 |
| 对象数量 | pods, services, configmaps, secrets |
限制命名空间内各类对象的数量 |
| 扩展资源 | requests.nvidia.com/gpu |
限制 GPU 等特殊硬件资源 |
工作原理:ResourceQuota 通过 准入控制(Admission Control) 实现。当用户提交创建/更新 Pod 或 PVC 的请求时,kube-apiserver 会调用 ResourceQuota 准入插件,计算当前命名空间已使用资源总量,加上新请求的资源量,若超过配额则拒绝请求。其计算逻辑基于 资源使用量(Usage),而非调度时的实际分配量。
升级场景关键点:ResourceQuota 的校验发生在 API 层,与节点状态无关。升级期间如果 kube-apiserver 版本变更,配额校验逻辑可能发生变化(例如 Kubernetes 1.22 后对 ephemeral containers 的配额支持),需要提前验证兼容性。
2.3 LimitRange 概念与工作原理
LimitRange 是命名空间级别的资源约束对象,用于为 Pod 和容器设置默认资源请求/限制,以及最小/最大资源约束。它解决的是“单个 Pod 或容器”的资源行为规范,而非总量控制。
| 策略类型 | 字段 | 作用 |
|---|---|---|
| 默认值 | default, defaultRequest |
为未显式设置资源限制/请求的容器自动填充 |
| 最小/最大 | min, max |
限制单个容器资源请求/限制的取值范围 |
| 比例约束 | maxLimitRequestRatio |
限制 limit/request 的最大比例(防止过度超分) |
工作原理:LimitRange 同样通过准入控制实现。当创建或更新 Pod 时,LimitRange 准入插件会:
- 检查 Pod 中每个容器是否设置了资源请求和限制;
- 如果未设置,则使用 LimitRange 中定义的默认值进行填充;
- 验证容器资源值是否在 min 和 max 范围内;
- 验证 limit/request 比例是否超过 maxLimitRequestRatio。
升级陷阱:如果升级前未配置 LimitRange,升级后新版本的调度器可能因缺少默认资源值而做出错误调度决策。例如,未设置 CPU 请求的 Pod 在升级后可能被调度到高负载节点,导致节点压力上升。建议在升级前为所有命名空间配置合理的 LimitRange 默认值。
2.4 ResourceQuota 与 LimitRange 在升级场景中的角色对比
| 维度 | ResourceQuota | LimitRange |
|---|---|---|
| 作用范围 | 命名空间级别(总量控制) | 命名空间级别(单 Pod/容器约束) |
| 核心功能 | 限制资源使用总量 | 设置默认值、最小/最大值、比例约束 |
| 升级风险 | 配额不足导致 Pod 创建失败;API 版本差异导致校验逻辑变化 | 默认值缺失导致调度器误判;新版本对比例约束更严格 |
| 升级前准备 | 检查配额使用率,预留缓冲;验证新版本配额 API 兼容性 | 确保所有命名空间配置默认值;检查 maxLimitRequestRatio 是否合理 |
| 升级后验证 | 监控配额使用率,确认无拒绝事件 | 检查 Pod 资源注入是否正确,无校验失败 |
2.5 升级场景中的典型问题与应对策略
案例:升级期间 ResourceQuota 导致滚动更新失败
某集群升级至 Kubernetes 1.24 后,Deployment 滚动更新时新 Pod 无法启动。排查发现命名空间 ResourceQuota 中
某集群升级至 Kubernetes 1.24 后,Deployment 滚动更新时新 Pod 无法启动。排查发现命名空间 ResourceQuota 中
pods 数量限制为 50,但旧 Pod 未及时终止(Terminating 状态),导致新 Pod 创建被拒绝。解决方案:升级前将 pods 配额临时提升至 60,或调整 Deployment 的 maxSurge 和 maxUnavailable 参数。
应对策略总结:
- 升级前:使用
kubectl get resourcequota -A和kubectl get limitrange -A导出所有配置,评估使用率;为关键命名空间预留 15%~20% 的配额缓冲。 - 升级中:监控 API Server 日志中的
Forbidden事件,重点关注exceeded quota和LimitRange相关错误。 - 升级后:运行
kubectl describe quota和kubectl describe limitrange确认配置未丢失;使用kubectl top pod验证资源使用是否符合预期。
自动化建议:将 ResourceQuota 和 LimitRange 配置纳入 GitOps 管理(如 ArgoCD),升级前通过 PR 调整配额,升级后自动同步回正常值,避免人工遗漏。