限制范围

默认情况下,容器在 Kubernetes 集群上运行时,其计算资源是不受限的。使用 Kubernetes 的资源配额(Resource Quotas),管理员(也称作 集群操作员)可以在指定的命名空间内限制集群资源(例如 CPU 时间、内存和持久性存储)的消耗和创建。在一个命名空间内,一个Pod 可以消耗该命名空间所适用的资源配额(Resource Quotas)允许的最大 CPU 和内存。作为集群操作员或命名空间级别的管理员,你可能还会关心如何确保单个对象无法垄断命名空间内的所有可用资源。

LimitRange 是一种策略,用于约束你在命名空间中为每种适用对象(例如 Pod 或PersistentVolumeClaim)指定的资源分配(限制和请求)。

*LimitRange* 提供了以下约束:

  • 在命名空间中强制执行每个 Pod 或 Container 的最小和最大计算资源使用量。
  • 在命名空间中强制执行每个PersistentVolumeClaim 的最小和最大存储请求。
  • 在命名空间中强制执行某个资源的请求和限制之间的比例。
  • 在命名空间中为计算资源设置默认请求/限制,并在运行时自动将其注入到 Containers 中。

只要命名空间中存在至少一个 LimitRange 对象,Kubernetes 就会约束该命名空间中 Pod 的资源分配。

LimitRange 对象的名称必须是有效的DNS 子域名

资源限制和请求上的约束

  • 管理员在一个命名空间中创建一个 LimitRange。
  • 用户在该命名空间中创建(或尝试创建)对象,例如 Pod 或 PersistentVolumeClaims。
  • 首先,LimitRange 准入控制器会为所有未设置计算资源需求的 Pod(及其容器)应用默认的请求和限制值。
  • 其次,LimitRange 会跟踪使用情况,以确保其不超过命名空间中任何 LimitRange 定义的资源最小值、最大值和比例。
  • 如果你尝试创建或更新违反 LimitRange 约束的对象(Pod 或 PersistentVolumeClaim),向 API 服务器发出的请求将失败,并返回 HTTP 状态码 403 Forbidden 以及一条说明违反了哪项约束的消息。
  • 如果你在命名空间中添加适用于计算相关资源(例如 cpumemory)的 LimitRange,则必须为这些值指定请求或限制。否则,系统可能会拒绝创建 Pod。
  • LimitRange 的验证仅在 Pod 准入阶段进行,不会应用于正在运行的 Pod。如果你添加或修改 LimitRange,该命名空间中已存在的 Pod 保持不变。
  • 如果命名空间中存在两个或多个 LimitRange 对象,则无法确定将应用哪个默认值。

LimitRange 和 Pod 的准入检查

LimitRange **不会**检查其所应用默认值的一致性。这意味着 LimitRange 设置的默认*限制*值可能小于客户端提交给 API 服务器的 Spec 中为容器指定的*请求*值。如果发生这种情况,最终的 Pod 将无法调度。

例如,你使用以下 Manifest 定义一个 LimitRange:

apiVersion: v1
kind: LimitRange
metadata:
  name: cpu-resource-constraint
spec:
  limits:
  - default: # this section defines default limits
      cpu: 500m
    defaultRequest: # this section defines default requests
      cpu: 500m
    max: # max and min define the limit range
      cpu: "1"
    min:
      cpu: 100m
    type: Container

以及一个声明 CPU 资源请求为 700m 但未声明限制的 Pod:

apiVersion: v1
kind: Pod
metadata:
  name: example-conflict-with-limitrange-cpu
spec:
  containers:
  - name: demo
    image: registry.k8s.io/pause:3.8
    resources:
      requests:
        cpu: 700m

那么该 Pod 将无法调度,并出现类似以下的错误:

Pod "example-conflict-with-limitrange-cpu" is invalid: spec.containers[0].resources.requests: Invalid value: "700m": must be less than or equal to cpu limit

如果你同时设置了 requestlimit,即使存在相同的 LimitRange,新 Pod 也将成功调度。

apiVersion: v1
kind: Pod
metadata:
  name: example-no-conflict-with-limitrange-cpu
spec:
  containers:
  - name: demo
    image: registry.k8s.io/pause:3.8
    resources:
      requests:
        cpu: 700m
      limits:
        cpu: 700m

资源约束示例

可以使用 LimitRange 创建的策略示例包括:

  • 在一个拥有 8 GiB 内存和 16 个核心的 2 节点集群中,限制命名空间中的 Pod 请求 100m CPU,CPU 最大限制为 500m;请求 200Mi 内存,内存最大限制为 600Mi。
  • 对于在其 Spec 中未声明 CPU 和内存请求的 Containers,将其默认 CPU 限制和请求设置为 150m,默认内存请求设置为 300Mi。

如果命名空间的总限制小于 Pod/Container 的限制总和,可能会发生资源争用。在这种情况下,Container 或 Pod 将无法创建。

资源争用或对 LimitRange 的更改都不会影响已创建的资源。

下一步

有关使用限制的示例,请参阅:

有关上下文和历史信息,请参阅LimitRanger 设计文档

最后修改于 2024 年 11 月 25 日 11:32 AM PST: 更新了缩进 (67676624a5)