配置命名空间的最小和最大内存约束

定义一个命名空间中有效的内存资源限制范围,使该命名空间中的每个新 Pod 都落在你配置的范围内。

本页面展示了如何为在命名空间中运行的容器设置内存使用的最小和最大值。你在LimitRange对象中指定最小和最大内存值。如果 Pod 不符合 LimitRange 施加的约束,则无法在该命名空间中创建。

准备工作

你需要有一个 Kubernetes 集群,并且 kubectl 命令行工具已配置为与你的集群通信。建议在至少有两个不作为控制平面主机的节点集群上运行本教程。如果你还没有集群,可以使用 minikube 创建一个,或者使用以下 Kubernetes 演练环境之一:

你必须有权在集群中创建命名空间。

集群中的每个节点必须至少有 1 GiB 内存可供 Pod 使用。

创建命名空间

创建一个命名空间,以便你在本练习中创建的资源与集群的其余部分隔离。

kubectl create namespace constraints-mem-example

创建一个 LimitRange 和一个 Pod

这是一个 LimitRange 的示例清单:

apiVersion: v1
kind: LimitRange
metadata:
  name: mem-min-max-demo-lr
spec:
  limits:
  - max:
      memory: 1Gi
    min:
      memory: 500Mi
    type: Container

创建 LimitRange

kubectl apply -f https://k8s.io/examples/admin/resource/memory-constraints.yaml --namespace=constraints-mem-example

查看 LimitRange 的详细信息

kubectl get limitrange mem-min-max-demo-lr --namespace=constraints-mem-example --output=yaml

输出显示了预期的最小和最大内存限制。但请注意,即使你没有在 LimitRange 的配置文件中指定默认值,它们也会自动创建。

  limits:
  - default:
      memory: 1Gi
    defaultRequest:
      memory: 1Gi
    max:
      memory: 1Gi
    min:
      memory: 500Mi
    type: Container

现在,每当你在 constraints-mem-example 命名空间中定义一个 Pod 时,Kubernetes 会执行以下步骤:

  • 如果该 Pod 中的任何容器没有指定自己的内存请求和限制,则控制平面会为该容器分配默认内存请求和限制。

  • 验证该 Pod 中的每个容器至少请求 500 MiB 内存。

  • 验证该 Pod 中的每个容器请求的内存不超过 1024 MiB (1 GiB)。

这是一个包含一个容器的 Pod 的清单。在 Pod 规约中,唯一容器指定了 600 MiB 的内存请求和 800 MiB 的内存限制。这些都满足 LimitRange 施加的最小和最大内存约束。

apiVersion: v1
kind: Pod
metadata:
  name: constraints-mem-demo
spec:
  containers:
  - name: constraints-mem-demo-ctr
    image: nginx
    resources:
      limits:
        memory: "800Mi"
      requests:
        memory: "600Mi"

创建 Pod

kubectl apply -f https://k8s.io/examples/admin/resource/memory-constraints-pod.yaml --namespace=constraints-mem-example

验证 Pod 是否正在运行以及其容器是否健康

kubectl get pod constraints-mem-demo --namespace=constraints-mem-example

查看 Pod 的详细信息

kubectl get pod constraints-mem-demo --output=yaml --namespace=constraints-mem-example

输出显示该 Pod 中的容器的内存请求为 600 MiB,内存限制为 800 MiB。这些都满足了该命名空间 LimitRange 施加的约束。

resources:
  limits:
     memory: 800Mi
  requests:
    memory: 600Mi

删除你的 Pod

kubectl delete pod constraints-mem-demo --namespace=constraints-mem-example

尝试创建超出最大内存约束的 Pod

这是一个包含一个容器的 Pod 的清单。该容器指定了 800 MiB 的内存请求和 1.5 GiB 的内存限制。

apiVersion: v1
kind: Pod
metadata:
  name: constraints-mem-demo-2
spec:
  containers:
  - name: constraints-mem-demo-2-ctr
    image: nginx
    resources:
      limits:
        memory: "1.5Gi"
      requests:
        memory: "800Mi"

尝试创建 Pod

kubectl apply -f https://k8s.io/examples/admin/resource/memory-constraints-pod-2.yaml --namespace=constraints-mem-example

输出显示 Pod 未被创建,因为它定义了一个请求内存超出允许范围的容器。

Error from server (Forbidden): error when creating "examples/admin/resource/memory-constraints-pod-2.yaml":
pods "constraints-mem-demo-2" is forbidden: maximum memory usage per Container is 1Gi, but limit is 1536Mi.

尝试创建不符合最小内存请求的 Pod

这是一个包含一个容器的 Pod 的清单。该容器指定了 100 MiB 的内存请求和 800 MiB 的内存限制。

apiVersion: v1
kind: Pod
metadata:
  name: constraints-mem-demo-3
spec:
  containers:
  - name: constraints-mem-demo-3-ctr
    image: nginx
    resources:
      limits:
        memory: "800Mi"
      requests:
        memory: "100Mi"

尝试创建 Pod

kubectl apply -f https://k8s.io/examples/admin/resource/memory-constraints-pod-3.yaml --namespace=constraints-mem-example

输出显示 Pod 未被创建,因为它定义了一个请求内存低于强制最小值的容器。

Error from server (Forbidden): error when creating "examples/admin/resource/memory-constraints-pod-3.yaml":
pods "constraints-mem-demo-3" is forbidden: minimum memory usage per Container is 500Mi, but request is 100Mi.

创建一个未指定任何内存请求或限制的 Pod

这是一个包含一个容器的 Pod 的清单。该容器未指定内存请求,也未指定内存限制。

apiVersion: v1
kind: Pod
metadata:
  name: constraints-mem-demo-4
spec:
  containers:
  - name: constraints-mem-demo-4-ctr
    image: nginx

创建 Pod

kubectl apply -f https://k8s.io/examples/admin/resource/memory-constraints-pod-4.yaml --namespace=constraints-mem-example

查看 Pod 的详细信息

kubectl get pod constraints-mem-demo-4 --namespace=constraints-mem-example --output=yaml

输出显示 Pod 的唯一容器的内存请求为 1 GiB,内存限制为 1 GiB。该容器是如何获得这些值的?

resources:
  limits:
    memory: 1Gi
  requests:
    memory: 1Gi

由于你的 Pod 没有为该容器定义任何内存请求和限制,集群应用了 LimitRange 中的默认内存请求和限制

这意味着该 Pod 的定义显示了这些值。你可以使用 kubectl describe 来检查它。

# Look for the "Requests:" section of the output
kubectl describe pod constraints-mem-demo-4 --namespace=constraints-mem-example

此时,你的 Pod 可能正在运行,也可能没有运行。回想一下,此任务的先决条件是你的节点至少有 1 GiB 内存。如果你的每个节点只有 1 GiB 内存,那么任何节点上都没有足够的可用内存来容纳 1 GiB 的内存请求。如果你碰巧使用 2 GiB 内存的节点,那么你可能有足够的空间来容纳 1 GiB 的请求。

删除你的 Pod

kubectl delete pod constraints-mem-demo-4 --namespace=constraints-mem-example

最小和最大内存约束的强制执行

LimitRange 对命名空间施加的最大和最小内存约束仅在 Pod 创建或更新时强制执行。如果你更改 LimitRange,它不会影响之前创建的 Pod。

最小和最大内存约束的动机

作为集群管理员,你可能希望对 Pod 可以使用的内存量施加限制。例如:

  • 集群中的每个节点都有 2 GiB 内存。你不希望接受任何请求超过 2 GiB 内存的 Pod,因为集群中没有节点可以支持该请求。

  • 一个集群由你的生产和开发部门共享。你希望允许生产工作负载消耗高达 8 GiB 的内存,但希望开发工作负载限制在 512 MiB。你为生产和开发创建单独的命名空间,并对每个命名空间应用内存约束。

清理

删除你的命名空间

kubectl delete namespace constraints-mem-example

下一步

致集群管理员

致应用开发者

最后修改于 2024 年 10 月 30 日下午 5:17 PST:KEP 2837:Pod 级别资源 Alpha (0374213f57)