限制范围
默认情况下,容器在 Kubernetes 集群上运行,其计算资源不受限制。通过使用 Kubernetes 资源配额,管理员(也称为_集群操作员_)可以限制在特定命名空间内集群资源的消耗和创建(例如 CPU 时间、内存和持久存储)。在一个命名空间内,Pod 可以消耗该命名空间适用的资源配额所允许的任意多的 CPU 和内存。作为集群操作员或命名空间级管理员,你可能还会关注确保单个对象不会独占命名空间内的所有可用资源。
LimitRange 是一种策略,用于限制你在命名空间中为每个适用的对象类型(例如 Pod 或PersistentVolumeClaim)指定的资源分配(限制和请求)。
_LimitRange_ 提供了以下限制:
- 在命名空间中强制执行每个 Pod 或容器的最小和最大计算资源使用量。
- 在命名空间中强制执行每个PersistentVolumeClaim 的最小和最大存储请求。
- 在命名空间中强制执行资源的请求与限制之间的比率。
- 为命名空间中的计算资源设置默认请求/限制,并在运行时自动将其注入容器。
只要命名空间中至少存在一个 LimitRange 对象,Kubernetes 就会限制该特定命名空间中 Pod 的资源分配。
LimitRange 对象的名称必须是有效的DNS 子域名。
资源限制和请求的约束
- 管理员在命名空间中创建 LimitRange。
- 用户在该命名空间中创建(或尝试创建)对象,例如 Pod 或 PersistentVolumeClaim。
- 首先,LimitRange Admission Controller 会为所有未设置计算资源要求的 Pod(及其容器)应用默认的请求和限制值。
- 其次,LimitRange 会跟踪使用情况,以确保它不超过命名空间中存在的任何 LimitRange 中定义的资源最小值、最大值和比率。
- 如果你尝试创建或更新违反 LimitRange 约束的对象(Pod 或 PersistentVolumeClaim),则对 API 服务器的请求将失败,并返回 HTTP 状态码
403 Forbidden
以及一条解释所违反约束的消息。 - 如果你在命名空间中添加适用于计算相关资源(例如
cpu
和memory
)的 LimitRange,则必须为这些值指定请求或限制。否则,系统可能会拒绝 Pod 的创建。 - LimitRange 验证仅发生在 Pod 准入阶段,而不是对正在运行的 Pod 进行验证。如果你添加或修改 LimitRange,该命名空间中已存在的 Pod 将保持不变。
- 如果命名空间中存在两个或更多 LimitRange 对象,则应用的默认值是不确定的。
LimitRange 和 Pod 的准入检查
LimitRange 不检查其应用的默认值的一致性。这意味着 LimitRange 设置的_限制_默认值可能小于客户端提交到 API 服务器的 spec 中为容器指定的_请求_值。如果发生这种情况,最终的 Pod 将无法调度。
例如,你使用以下清单定义一个 LimitRange:
注意
由于未定义命名空间参数且 LimitRange 范围仅限于命名空间级别,因此以下示例将在集群的默认命名空间中运行。这意味着这些示例中的任何引用或操作都将与集群默认命名空间中的元素进行交互。你可以通过配置metadata.namespace
字段中的命名空间来覆盖操作命名空间。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
如果你同时设置了 request
和 limit
,即使存在相同的 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 RAM 和 16 核的 2 节点集群中,限制命名空间中的 Pod 请求 100m CPU,最大限制为 500m CPU;请求 200Mi 内存,最大限制为 600Mi 内存。
- 对于在其 spec 中未设置 CPU 和内存请求的容器,将默认 CPU 限制和请求定义为 150m,将内存默认请求定义为 300Mi。
如果命名空间的总限制小于 Pod/容器的限制之和,则可能会出现资源争用。在这种情况下,容器或 Pod 将不会被创建。
资源争用或对 LimitRange 的更改都不会影响已创建的资源。
下一步
有关使用限制的示例,请参阅:
- 如何配置每个命名空间的最小和最大 CPU 约束.
- 如何配置每个命名空间的最小和最大内存约束.
- 如何配置每个命名空间的默认 CPU 请求和限制.
- 如何配置每个命名空间的默认内存请求和限制.
- 如何配置每个命名空间的最小和最大存储消耗.
- 有关配置每个命名空间配额的详细示例。
请参阅LimitRanger 设计文档以获取背景和历史信息。