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

为命名空间定义有效的内存资源限制范围,以便该命名空间中每个新 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

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

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

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

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

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

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

清理

删除你的命名空间

kubectl delete namespace constraints-mem-example

下一步

对于集群管理员

对于应用程序开发人员

上次修改时间:2024 年 10 月 30 日下午 5:17(太平洋标准时间):KEP 2837:Pod 级别资源 Alpha (0374213f57)