4. 命名空间默认限制:LimitRange 对象

在多租户或微服务架构中,不同团队或应用共享同一个 Kubernetes 集群。如果没有资源约束,单个 Pod 可能因 Bug 或恶意行为耗尽节点资源,导致其他 Pod 被驱逐。LimitRange 是命名空间级别的准入控制机制,它定义了 Pod 或容器在命名空间内必须遵守的最小/最大资源约束,并为未显式设置资源请求/限制的 Pod 提供默认值。

核心作用:LimitRange 在 Pod 创建时由准入控制器(LimitRanger)强制执行,确保每个 Pod 的资源声明在命名空间允许的范围内,防止资源争抢和滥用。

4.1 LimitRange 对象结构

LimitRange 通过 spec.limits 字段定义一组限制规则,每条规则可以针对容器(Container)、Pod 或 PersistentVolumeClaim(PVC)。以下是一个典型的 LimitRange YAML 示例:

apiVersion: v1
kind: LimitRange
metadata:
  name: resource-limits
  namespace: production
spec:
  limits:
  - type: Container
    max:
      cpu: "2"
      memory: "2Gi"
    min:
      cpu: "100m"
      memory: "128Mi"
    default:
      cpu: "500m"
      memory: "512Mi"
    defaultRequest:
      cpu: "200m"
      memory: "256Mi"
    maxLimitRequestRatio:
      cpu: "4"
      memory: "4"
  - type: Pod
    max:
      cpu: "4"
      memory: "4Gi"
  - type: PersistentVolumeClaim
    max:
      storage: "100Gi"
    min:
      storage: "1Gi"

4.2 关键字段解析

字段 作用范围 说明
min Container / Pod / PVC 容器或 Pod 资源请求(requests)不能低于此值。如果 Pod 中某个容器未设置 requests,则拒绝创建。
max Container / Pod / PVC 容器或 Pod 资源限制(limits)不能超过此值。如果 Pod 中某个容器未设置 limits,则拒绝创建。
default Container 当容器未设置 limits 时,自动注入此值作为 limits。不影响 requests。
defaultRequest Container 当容器未设置 requests 时,自动注入此值作为 requests。不影响 limits。
maxLimitRequestRatio Container 限制 limits 与 requests 的最大比值。例如 ratio=4 表示 limits 不能超过 requests 的 4 倍,防止过度突发。
最佳实践:始终为每个命名空间创建 LimitRange,即使团队承诺会手动设置资源。默认值可以降低人为遗漏的风险,而 min/max 约束可以防止配置错误或恶意行为。

4.3 默认请求与限制的注入机制

当 Pod 创建时,LimitRanger 准入控制器会按以下顺序处理资源字段:

  1. 检查显式设置:如果容器已设置 requests 和 limits,直接使用,不覆盖。
  2. 注入默认值:如果容器缺少 requests,使用 defaultRequest;如果缺少 limits,使用 default。
  3. 验证约束:检查注入后的值是否满足 min、max 和 maxLimitRequestRatio。如果不满足,拒绝 Pod 创建并返回错误。

以下示例展示了一个未设置资源的 Pod 如何被 LimitRange 自动补全:

# 用户提交的 Pod(未设置资源)
apiVersion: v1
kind: Pod
metadata:
  name: default-demo
  namespace: production
spec:
  containers:
  - name: app
    image: nginx

# 实际生效的 Pod(LimitRange 注入后)
apiVersion: v1
kind: Pod
metadata:
  name: default-demo
  namespace: production
spec:
  containers:
  - name: app
    image: nginx
    resources:
      requests:
        cpu: 200m
        memory: 256Mi
      limits:
        cpu: 500m
        memory: 512Mi

4.4 最小与最大资源约束

min 和 max 约束是 LimitRange 最强大的安全特性。它们确保命名空间内的所有 Pod 都遵循统一的资源边界,防止单个 Pod 占用过多资源或请求过少导致调度问题。

注意:min 和 max 是针对单个容器或整个 Pod 的,取决于 type 字段。如果 type 为 Container,则每个容器独立检查;如果 type 为 Pod,则所有容器的资源总和必须满足约束。

以下场景展示了约束如何阻止非法 Pod:

  • 场景 A:容器请求 50m CPU,但 min 为 100m → Pod 被拒绝。
  • 场景 B:容器限制 4Gi 内存,但 max 为 2Gi → Pod 被拒绝。
  • 场景 C:容器请求 100m CPU,限制 1 CPU,但 maxLimitRequestRatio 为 4 → 1 CPU / 100m = 10 > 4 → Pod 被拒绝。

4.5 LimitRange 与 Pod 优先级

Pod 优先级(PriorityClass)决定了调度和抢占时的相对重要性。LimitRange 与 Pod 优先级之间存在重要的交互关系:

优先级类 资源保证 LimitRange 影响
高优先级(如 system-cluster-critical) 调度时优先分配资源,可抢占低优先级 Pod 仍受命名空间 min/max 约束,不能突破 LimitRange 上限
低优先级(如 best-effort) 调度顺序靠后,可能被高优先级 Pod 驱逐 必须满足 min 约束,否则无法创建
默认优先级 无特殊保证 完全受 LimitRange 默认值和约束控制

关键原则:LimitRange 是准入控制,Pod 优先级是调度控制。即使 Pod 具有最高优先级,也不能绕过 LimitRange 的资源边界。这防止了高优先级 Pod 通过声明超大资源来垄断集群。

安全建议:在关键命名空间(如 kube-system、production)中,结合使用 LimitRange 和 ResourceQuota。LimitRange 控制单个 Pod 的边界,ResourceQuota 控制命名空间的总资源上限。两者配合形成双层防护。

4.6 LimitRange 工作流程

LimitRange 准入控制流程 用户提交 Pod LimitRanger 准入控制器 拦截 Pod 创建请求 检查容器资源字段 缺少字段 已有字段 注入默认值 保留原值 验证 min / max / ratio 通过 → Pod 创建

4.7 多命名空间策略示例

以下表格展示了不同环境下的典型 LimitRange 配置策略:

命名空间 min CPU max CPU default CPU defaultRequest CPU maxLimitRatio
production 100m 4 1 500m 4
staging 50m 2 500m 200m 4
development 10m 1 200m 100m 10
kube-system 50m 8 500m 250m 8
策略解读:production 命名空间约束最严格(min 100m,ratio 4),确保生产应用资源稳定;development 命名空间更宽松(min 10m,ratio 10),允许开发人员快速迭代;kube-system 允许更大的 max CPU(8),为系统组件提供弹性。

4.8 常见错误与排查

  • 错误 1:Pod 创建失败,错误信息 "minimum cpu usage per Container is 100m" → 容器 requests 低于 min 值。
  • 错误 2:Pod 创建失败,错误信息 "maximum memory usage per Container is 2Gi" → 容器 limits 超过 max 值。
  • 错误 3:Pod 创建失败,错误信息 "cpu max limit to request ratio per Container is 4" → limits/requests 比值超过 maxLimitRequestRatio。
  • 错误 4:LimitRange 未生效 → 检查 API Server 是否启用了 LimitRanger 准入控制器(默认开启)。
重要:LimitRange 只影响创建操作,不影响已存在的 Pod。如果修改 LimitRange 使其更严格,现有 Pod 不会受影响,但新 Pod 必须满足新约束。建议在修改 LimitRange 前先检查命名空间内现有 Pod 的资源声明。

4.9 本章小结

LimitRange 是 Kubernetes 命名空间资源治理的基础组件。通过合理配置 min、max、default、defaultRequest 和 maxLimitRequestRatio,可以实现:

  • 资源规范化:所有 Pod 都有明确的资源声明,避免隐式默认值导致调度问题。
  • 安全边界:防止单个 Pod 声明过大或过小的资源,降低资源争抢和节点过载风险。
  • 成本控制:结合 ResourceQuota,实现命名空间级别的资源预算管理。
  • 优先级隔离:即使高优先级 Pod 也不能突破 LimitRange 约束,确保公平性。