为容器和 Pod 分配 CPU 资源
本页展示如何为容器分配 CPU 请求 和 CPU 限制。容器使用的 CPU 不能超过配置的限制。在系统有空闲 CPU 时间的情况下,保证为容器分配其请求的 CPU 量。
开始之前
你需要有一个 Kubernetes 集群,并且必须配置 kubectl 命令行工具以与你的集群进行通信。建议在至少有两个不充当控制平面主机的节点的集群上运行本教程。如果你还没有集群,你可以使用 minikube 创建一个,或者你可以使用以下 Kubernetes 游乐场之一
要检查版本,请输入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 milliCPU,CPU 限制为 1 CPU。
resources:
limits:
cpu: "1"
requests:
cpu: 500m
使用 kubectl top
获取 Pod 的指标
kubectl top pod cpu-demo --namespace=cpu-example
此示例输出显示 Pod 正在使用 974 milliCPU,略低于 Pod 配置中指定的 1 CPU 的限制。
NAME CPU(cores) MEMORY(bytes)
cpu-demo 974m <something>
请记住,通过设置 -cpu "2"
,你配置了容器以尝试使用 2 个 CPU,但该容器仅被允许使用大约 1 个 CPU。容器的 CPU 使用受到限制,因为容器尝试使用的 CPU 资源超过了其限制。
注意
CPU 使用量低于 1.0 的另一个可能解释是节点可能没有足够的可用 CPU 资源。请记住,此练习的先决条件要求你的集群至少有 1 个可用的 CPU 用于使用。如果你的容器在只有一个 CPU 的节点上运行,则无论为容器指定了多少 CPU 限制,该容器都无法使用超过 1 个 CPU。CPU 单位
CPU 资源以 CPU 单位进行衡量。在 Kubernetes 中,一个 CPU 等效于
- 1 个 AWS vCPU
- 1 个 GCP 核心
- 1 个 Azure vCore
- 带有超线程的裸机 Intel 处理器上的 1 个超线程
允许使用小数值。请求 0.5 CPU 的容器保证获得相当于请求 1 CPU 的容器一半的 CPU。你可以使用后缀 m 来表示 milli。例如,100m CPU、100 milliCPU 和 0.1 CPU 都相同。不允许使用小于 1m 的精度。
CPU 始终以绝对数量请求,而不是相对数量;在单核、双核或 48 核机器上,0.1 的 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 才会在该节点上被调度运行。
在本练习中,你将创建一个 Pod,其 CPU 请求太大,以至于超过了集群中任何节点的容量。以下是具有一个容器的 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