3. Kubernetes 资源配额基础:ResourceQuota、LimitRange 与命名空间资源管控
在 Argo CD 滚动升级场景中,资源配额的精准校准是保障集群稳定性的第一道防线。Kubernetes 通过 ResourceQuota 和 LimitRange 两个原生对象,在命名空间级别实施资源管控。理解其原理,是后续进行性能调优和滚动升级资源校准的前提。
3.1 命名空间资源管控的核心逻辑
Kubernetes 的资源管控采用分层模型:集群 → 命名空间 → Pod/Container。ResourceQuota 作用于命名空间,限制该空间内所有 Pod 的资源总和;LimitRange 则作用于单个 Pod 或 Container,设置资源请求与限制的默认值及边界。两者配合,形成“总量控制 + 单实例约束”的双重机制。
3.2 ResourceQuota 对象详解
ResourceQuota 是命名空间级别的资源配额控制器。它通过准入控制(Admission Control)拦截所有 Pod 创建请求,确保命名空间内所有容器的资源请求(requests)和限制(limits)总和不超过配额上限。
3.2.1 核心字段与配置示例
| 资源类型 | 字段名 | 说明 | 典型值(示例) |
|---|---|---|---|
| 计算资源 | requests.cpu |
所有 Pod CPU 请求总和上限 | 10 |
| 计算资源 | requests.memory |
所有 Pod 内存请求总和上限 | 20Gi |
| 计算资源 | limits.cpu |
所有 Pod CPU 限制总和上限 | 20 |
| 计算资源 | limits.memory |
所有 Pod 内存限制总和上限 | 40Gi |
| 对象数量 | count/pods |
命名空间内 Pod 总数上限 | 50 |
| 对象数量 | count/deployments.apps |
Deployment 数量上限 | 20 |
| 存储资源 | requests.storage |
所有 PVC 存储请求总和上限 | 100Gi |
apiVersion: v1
kind: ResourceQuota
metadata:
name: argo-rollout-quota
namespace: argo-demo
spec:
hard:
requests.cpu: "10"
requests.memory: "20Gi"
limits.cpu: "20"
limits.memory: "40Gi"
count/pods: "50"
count/deployments.apps: "20"
count/services: "10"
requests.storage: "100Gi"
最佳实践:在 Argo CD 管理的命名空间中,建议将
requests.cpu 和 limits.cpu 的比值控制在 1:2 以内,避免突发流量导致 Pod 被 OOMKill 或 CPU 节流。
3.3 LimitRange 对象详解
LimitRange 在命名空间级别设置 Pod 或 Container 的资源默认值及边界。当用户未显式设置资源请求/限制时,LimitRange 会自动注入默认值;同时,它还会校验用户设置的值是否在允许范围内。
3.3.1 核心字段与配置示例
| 限制类型 | 字段名 | 说明 | 典型值(示例) |
|---|---|---|---|
| 默认请求 | defaultRequest.cpu |
未设置 requests.cpu 时的默认值 | 100m |
| 默认请求 | defaultRequest.memory |
未设置 requests.memory 时的默认值 | 256Mi |
| 默认限制 | default.cpu |
未设置 limits.cpu 时的默认值 | 500m |
| 默认限制 | default.memory |
未设置 limits.memory 时的默认值 | 512Mi |
| 最小值 | min.cpu |
允许的最小 CPU 请求值 | 50m |
| 最大值 | max.cpu |
允许的最大 CPU 限制值 | 4 |
| 比值约束 | maxLimitRequestRatio.cpu |
limits/requests 的最大比值 | 3 |
apiVersion: v1
kind: LimitRange
metadata:
name: argo-rollout-limits
namespace: argo-demo
spec:
limits:
- type: Container
defaultRequest:
cpu: "100m"
memory: "256Mi"
default:
cpu: "500m"
memory: "512Mi"
min:
cpu: "50m"
memory: "128Mi"
max:
cpu: "4"
memory: "4Gi"
maxLimitRequestRatio:
cpu: "3"
注意:LimitRange 的
maxLimitRequestRatio 字段在滚动升级场景中尤为重要。如果设置过小(如 1:1),会导致 Pod 无法在升级过程中临时提高资源限制;设置过大(如 5:1),则可能造成资源超分严重。建议 Argo CD 滚动升级场景中设置为 2:1 或 3:1。
3.4 资源管控的准入控制流程
当用户通过 Argo CD 向集群提交一个 Deployment 或 Rollout 时,Kubernetes 的准入控制器会按以下顺序执行资源校验:
- LimitRange 校验:检查每个 Container 的 requests 和 limits 是否在 min/max 范围内;若未设置,则注入默认值。
- ResourceQuota 校验:计算命名空间内所有 Pod 的资源总和(包括新 Pod),检查是否超过 hard 限制。
- 对象数量校验:检查 Pod、Service、PVC 等对象数量是否超过配额。
- 准入通过/拒绝:若任何一项校验失败,API Server 返回 403 Forbidden,Pod 创建被拒绝。
3.5 滚动升级场景下的资源配额校准要点
关键校准策略:
- 预留缓冲空间:ResourceQuota 的 hard 值不应设置为集群容量的 100%。建议预留 15%-20% 的缓冲,用于应对滚动升级过程中的临时 Pod 双跑(旧 Pod 未终止,新 Pod 已启动)。
- LimitRange 默认值对齐:确保 LimitRange 的 default 值与 Argo CD 的 Application 中定义的资源请求一致,避免因默认值注入导致配额计算偏差。
- 对象数量配额:滚动升级时,ReplicaSet 数量会短暂增加。建议将
count/replicasets.apps的配额设置为 Deployment 数量的 2-3 倍。 - 监控与告警:使用
kubectl describe quota或 Prometheus 监控 ResourceQuota 的使用率,当使用率超过 80% 时触发告警。
3.6 常见问题与避坑指南
| 问题场景 | 原因 | 解决方案 |
|---|---|---|
| 滚动升级时 Pod 创建失败 | ResourceQuota 的 count/pods 配额不足,无法容纳新旧 Pod 共存 |
将 count/pods 设置为期望副本数的 1.5-2 倍 |
| Pod 资源请求被 LimitRange 拒绝 | Container 的 requests 或 limits 超出 LimitRange 的 max 范围 | 调整 Pod 资源规格,或放宽 LimitRange 的 max 值 |
| 配额未生效 | ResourceQuota 或 LimitRange 未创建在正确的命名空间 | 使用 kubectl get quota -n <namespace> 确认对象存在 |
| LimitRange 默认值覆盖了 Argo CD 的显式设置 | LimitRange 的 default 优先级高于用户未设置的值,但不会覆盖已显式设置的值 | 在 Argo CD Application 中显式设置 resources.requests 和 resources.limits |
快速验证命令:
kubectl describe quota argo-rollout-quota -n argo-demo — 查看当前配额使用情况kubectl describe limitrange argo-rollout-limits -n argo-demo — 查看 LimitRange 配置kubectl get pods -n argo-demo --field-selector=status.phase=Running | wc -l — 统计当前运行 Pod 数量