2. Kubernetes资源模型与容量抽象:Pod、Node、ResourceQuota、LimitRange的容量语义

在容量规划中,Kubernetes 的资源模型是理解集群“能装多少、还剩多少”的基础。Pod、Node、ResourceQuota、LimitRange 这四个对象分别从微观请求、宏观容量、配额边界和默认约束四个维度定义了容量语义。只有准确理解这些原语的数学关系,才能设计出合理的 Kyverno/OPA 策略。

2.1 核心容量原语:Pod 与 Node

Pod 是 Kubernetes 中最小的调度单元,其资源声明直接决定了 Node 的容量消耗。Node 则是集群的物理/虚拟计算节点,其可分配容量是调度决策的硬边界。

原语 容量语义 关键字段 规划影响
Pod 资源请求(requests)与限制(limits) spec.containers[].resources.requests.cpu/memory
spec.containers[].resources.limits.cpu/memory
决定调度时的“承诺容量”与运行时的“突发上限”
Node 总容量减去系统预留后的可分配容量 status.allocatable.cpu/memory 决定集群实际可调度 Pod 的总和上限
Node 节点压力驱逐阈值 --eviction-hard / --eviction-soft 触发 Pod 驱逐的剩余容量警戒线
容量规划要点: 调度器只检查 Pod 的 requests 总和是否超过 Node 的 allocatable;limits 仅用于运行时 CPU 限流和 OOM 判定。因此,requests 是容量规划的第一性原理。

2.2 容量抽象层:ResourceQuota 与 LimitRange

ResourceQuota 为命名空间级别的容量上限提供硬约束,LimitRange 则为单个 Pod/Container 设置默认值和范围。两者共同构成了多租户环境下的容量治理骨架。

2.2.1 ResourceQuota:命名空间容量天花板

ResourceQuota 定义了命名空间内所有 Pod 的资源请求总和上限。当配额耗尽时,后续 Pod 创建将被 API Server 拒绝。

apiVersion: v1
kind: ResourceQuota
metadata:
  name: team-a-quota
  namespace: team-a
spec:
  hard:
    requests.cpu: "10"
    requests.memory: "20Gi"
    limits.cpu: "20"
    limits.memory: "40Gi"
    persistentvolumeclaims: "5"
    pods: "50"
容量语义: ResourceQuota 的 hard 字段是上限,而非预留。即使命名空间内实际使用量远低于配额,其他命名空间也无法借用。这要求容量规划时必须为每个命名空间预留足够的“安全余量”。

2.2.2 LimitRange:默认值与边界约束

LimitRange 为未显式声明资源请求/限制的 Pod 注入默认值,并强制约束单个容器的资源范围。它防止了“无限制”容器意外耗尽节点容量。

apiVersion: v1
kind: LimitRange
metadata:
  name: default-limits
  namespace: team-a
spec:
  limits:
  - default:
      cpu: "500m"
      memory: "512Mi"
    defaultRequest:
      cpu: "200m"
      memory: "256Mi"
    max:
      cpu: "2"
      memory: "4Gi"
    min:
      cpu: "50m"
      memory: "64Mi"
    type: Container
LimitRange 字段 容量语义 违反后果
default 未设置 limits 时的默认上限 自动注入,不拒绝
defaultRequest 未设置 requests 时的默认请求值 自动注入,不拒绝
max 单个容器的资源上限 超出则拒绝创建
min 单个容器的资源下限 低于则拒绝创建

2.3 容量语义关系图

下图展示了从 Node 物理容量到 Pod 资源声明的完整抽象链路,以及 ResourceQuota 和 LimitRange 在其中的拦截位置。

Kubernetes 容量抽象层级与语义关系 Kubernetes 容量抽象层级与语义关系 Node 物理容量 capacity.cpu / capacity.memory Node 可分配容量 allocatable = capacity - 系统预留 - 驱逐阈值 ResourceQuota(命名空间配额) requests.cpu / requests.memory / pods 等 LimitRange(默认值与边界) default / defaultRequest / max / min Pod(容器资源声明) requests / limits(CPU & Memory) 容量规划关键点 • 调度只看 requests • 驱逐看 allocatable 余量 • Quota 是硬上限 • LimitRange 防“无限制” • 策略应校验 requests 合理性 • 避免 limits >> requests 策略治理介入点 ① 校验 requests 是否合理 ② 强制设置 limits ③ 限制 requests/limits 比例 ④ 防止 Quota 超卖 ⑤ 校验 LimitRange 合规 ⑥ 监控 allocatable 余量

2.4 容量语义在策略中的映射

Kyverno 和 OPA 在编写资源校验规则时,必须准确理解上述原语的容量语义。以下表格总结了常见策略场景与对应的容量抽象关系:

策略场景 涉及原语 容量语义校验逻辑 典型规则示例
禁止 requests 为 0 Pod requests 是调度承诺,为 0 会导致节点过载 requests.cpu > 0
限制 limits/requests 比例 Pod 防止 limits 远大于 requests 造成突发超卖 limits.cpu / requests.cpu ≤ 3
命名空间总配额校验 ResourceQuota 确保命名空间 requests 总和不超过 Quota sum(requests) ≤ quota.hard
强制设置默认 limits LimitRange 未设置 limits 的 Pod 使用默认值 default.limits.cpu = "500m"
节点可分配容量预警 Node 监控 allocatable 余量,低于阈值时告警 allocatable - sum(requests) < 10%
常见误区: 很多策略只校验 limits 而忽略 requests。实际上,requests 决定了调度可行性,而 limits 只影响运行时行为。容量规划策略应优先关注 requests 的合理性与配额匹配度。

2.5 容量抽象与策略协同总结

从容量规划视角看,Kubernetes 的资源模型形成了一个清晰的抽象栈:

  1. 物理层: Node 的 capacity 和 allocatable 定义了集群的容量天花板。
  2. 配额层: ResourceQuota 在命名空间级别划分容量池,防止单个团队耗尽集群。
  3. 约束层: LimitRange 为单个容器设置默认值和边界,避免“无限制”容器破坏容量规划。
  4. 声明层: Pod 的 requests/limits 是容量消耗的最小单元,也是策略校验的核心对象。