为容器和 Pod 分配 CPU 资源

本页面展示如何为容器分配 CPU *请求* 和 CPU *限制*。容器使用的 CPU 不能超过配置的限制。如果系统有空闲的 CPU 时间,则保证容器将被分配与它请求的相同量的 CPU。

在开始之前

您需要拥有一个 Kubernetes 集群,并且 kubectl 命令行工具必须配置为与您的集群通信。建议您在至少有两个节点(不是充当控制平面主机)的集群上运行本教程。如果您还没有集群,可以使用 minikube 创建一个集群,或者可以使用以下 Kubernetes Playground 之一

要检查版本,请输入 kubectl version

您的集群必须至少有 1 个 CPU 可用于运行任务示例。

本页面上的部分步骤要求您在集群中运行 metrics-server 服务。如果您已运行 metrics-server,可以跳过这些步骤。

如果您正在运行 Minikube,请运行以下命令启用 metrics-server

minikube addons enable metrics-server

要查看 metrics-server(或其他提供资源指标 API(metrics.k8s.io)的提供者)是否正在运行,请键入以下命令

kubectl get apiservices

如果资源指标 API 可用,则输出将包含对 metrics.k8s.io 的引用。

NAME
v1beta1.metrics.k8s.io

创建一个命名空间

创建一个 命名空间,以便您在此练习中创建的资源与集群中的其他资源隔离。

kubectl create namespace cpu-example

指定 CPU 请求和 CPU 限制

要为容器指定 CPU 请求,请在容器资源清单中包含 resources:requests 字段。要指定 CPU 限制,请包含 resources:limits

在本练习中,您将创建一个包含一个容器的 Pod。该容器的请求为 0.5 个 CPU,限制为 1 个 CPU。以下是 Pod 的配置文件

apiVersion: v1
kind: Pod
metadata:
  name: cpu-demo
  namespace: cpu-example
spec:
  containers:
  - name: cpu-demo-ctr
    image: vish/stress
    resources:
      limits:
        cpu: "1"
      requests:
        cpu: "0.5"
    args:
    - -cpus
    - "2"

配置文件的 args 部分提供了容器启动时的参数。-cpus "2" 参数告诉容器尝试使用 2 个 CPU。

创建 Pod

kubectl apply -f https://k8s.io/examples/pods/resource/cpu-request-limit.yaml --namespace=cpu-example

验证 Pod 是否正在运行

kubectl get pod cpu-demo --namespace=cpu-example

查看有关 Pod 的详细信息

kubectl get pod cpu-demo --output=yaml --namespace=cpu-example

输出显示 Pod 中的单个容器的 CPU 请求为 500 毫 CPU,CPU 限制为 1 个 CPU。

resources:
  limits:
    cpu: "1"
  requests:
    cpu: 500m

使用 kubectl top 获取 Pod 的指标

kubectl top pod cpu-demo --namespace=cpu-example

此示例输出显示 Pod 正在使用 974 毫 CPU,略小于 Pod 配置中指定的 1 个 CPU 限制。

NAME                        CPU(cores)   MEMORY(bytes)
cpu-demo                    974m         <something>

回想一下,通过设置 -cpu "2",您配置了容器尝试使用 2 个 CPU,但容器只被允许使用大约 1 个 CPU。容器的 CPU 使用率正在被限制,因为容器试图使用比其限制更多的 CPU 资源。

CPU 单位

CPU 资源以 *CPU* 单位衡量。在 Kubernetes 中,一个 CPU 等效于

  • 1 个 AWS vCPU
  • 1 个 GCP 内核
  • 1 个 Azure vCore
  • 支持超线程的裸机英特尔处理器上的 1 个超线程

允许使用小数。请求 0.5 个 CPU 的容器,保证的 CPU 是请求 1 个 CPU 的容器的一半。可以使用后缀 m 表示毫。例如,100m CPU、100 毫 CPU 和 0.1 个 CPU 都相同。不允许小于 1m 的精度。

CPU 始终以绝对数量请求,而不是以相对数量请求;0.1 在单核、双核或 48 核机器上是相同的 CPU 量。

删除您的 Pod

kubectl delete pod cpu-demo --namespace=cpu-example

指定一个超出节点容量的 CPU 请求

CPU 请求和限制与容器相关联,但将 Pod 视为具有 CPU 请求和限制是有用的。Pod 的 CPU 请求是 Pod 中所有容器的 CPU 请求之和。同样,Pod 的 CPU 限制是 Pod 中所有容器的 CPU 限制之和。

Pod 调度基于请求。只有当节点拥有足够的 CPU 资源来满足 Pod CPU 请求时,Pod 才会被调度到该节点上运行。

在本练习中,您将创建一个 CPU 请求超过集群中任何节点容量的 Pod。以下是一个包含一个容器的 Pod 的配置文件。该容器请求 100 个 CPU,这很可能超过集群中任何节点的容量。

apiVersion: v1
kind: Pod
metadata:
  name: cpu-demo-2
  namespace: cpu-example
spec:
  containers:
  - name: cpu-demo-ctr-2
    image: vish/stress
    resources:
      limits:
        cpu: "100"
      requests:
        cpu: "100"
    args:
    - -cpus
    - "2"

创建 Pod

kubectl apply -f https://k8s.io/examples/pods/resource/cpu-request-limit-2.yaml --namespace=cpu-example

查看 Pod 状态

kubectl get pod cpu-demo-2 --namespace=cpu-example

输出显示 Pod 状态为 Pending。也就是说,Pod 尚未被调度到任何节点上运行,并且它将无限期地保持 Pending 状态

NAME         READY     STATUS    RESTARTS   AGE
cpu-demo-2   0/1       Pending   0          7m

查看有关 Pod 的详细信息,包括事件

kubectl describe pod cpu-demo-2 --namespace=cpu-example

输出显示容器无法调度,因为节点上的 CPU 资源不足

Events:
  Reason                        Message
  ------                        -------
  FailedScheduling      No nodes are available that match all of the following predicates:: Insufficient cpu (3).

删除您的 Pod

kubectl delete pod cpu-demo-2 --namespace=cpu-example

如果您没有指定 CPU 限制

如果您没有为容器指定 CPU 限制,则以下情况之一适用

  • 容器没有对它可以使用的 CPU 资源的上限。容器可以使用它运行所在节点上的所有可用 CPU 资源。

  • 容器运行在具有默认 CPU 限制的命名空间中,并且容器会自动分配默认限制。集群管理员可以使用 LimitRange 为 CPU 限制指定默认值。

如果您指定了 CPU 限制,但没有指定 CPU 请求

如果您为容器指定了 CPU 限制,但没有指定 CPU 请求,Kubernetes 会自动分配与限制匹配的 CPU 请求。类似地,如果容器指定了自己的内存限制,但没有指定内存请求,Kubernetes 会自动分配与限制匹配的内存请求。

CPU 请求和限制的动机

通过配置在集群中运行的容器的 CPU 请求和限制,您可以有效地利用集群节点上可用的 CPU 资源。通过保持 Pod CPU 请求较低,您可以让 Pod 有很大的机会被调度。通过设置大于 CPU 请求的 CPU 限制,您可以实现两件事

  • Pod 可以有活动高峰,在这些高峰中它可以使用碰巧可用的 CPU 资源。
  • Pod 在活动高峰期间可以使用 CPU 资源的量限制在合理范围内。

清理

删除您的命名空间

kubectl delete namespace cpu-example

下一步

面向应用程序开发人员

面向集群管理员

上次修改时间:2023 年 8 月 24 日 下午 6:38 PST:使用 code_sample 短代码而不是 code 短代码 (e8b136c3b3)