为容器和 Pod 分配 CPU 资源
本页展示了如何为一个容器设置 CPU 请求(request) 和 CPU 限制(limit)。容器不能使用超过配置限制的 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
创建命名空间
创建一个 Namespace,以便你在本练习中创建的资源与集群的其余部分隔离。
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 中的一个容器具有 500 毫核 (milliCPU) 的 CPU 请求和 1 CPU 的 CPU 限制。
resources:
limits:
cpu: "1"
requests:
cpu: 500m
使用 kubectl top
获取 Pod 的指标
kubectl top pod cpu-demo --namespace=cpu-example
此示例输出显示 Pod 正在使用 974 毫核,略低于 Pod 配置中指定的 1 CPU 限制。
NAME CPU(cores) MEMORY(bytes)
cpu-demo 974m <something>
回想一下,通过设置 -cpu "2"
,你配置容器尝试使用 2 个 CPU,但容器只被允许使用大约 1 个 CPU。容器的 CPU 使用率正在被限制,因为容器试图使用超过其限制的 CPU 资源。
注意
另一种 CPU 使用率低于 1.0 的可能解释是 Node 可能没有足够的 CPU 资源可用。回想一下,本练习的先决条件要求你的集群至少有 1 个 CPU 可供使用。如果你的容器运行在只有一个 CPU 的 Node 上,则无论为容器指定的 CPU 限制如何,容器都不能使用超过 1 个 CPU。CPU 单位
CPU 资源以 CPU 单位衡量。在 Kubernetes 中,1 个 CPU 等同于:
- 1 个 AWS vCPU
- 1 个 GCP 核心
- 1 个 Azure vCore
- 带有超线程的裸金属 Intel 处理器上的 1 个超线程
允许使用小数。请求 0.5 CPU 的容器保证获得的 CPU 资源是请求 1 CPU 的容器的一半。你可以使用后缀 m 表示毫核 (milli)。例如,100m CPU、100 毫核和 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 调度基于请求。仅当 Node 有足够的可用 CPU 资源满足 Pod CPU 请求时,Pod 才能被调度到该 Node 上运行。
在本练习中,你将创建一个 Pod,其 CPU 请求大到超出集群中任何 Node 的容量。这是一个包含一个容器的 Pod 的配置文件。该容器请求 100 CPU,这很可能超出你集群中任何 Node 的容量。
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 尚未被调度到任何 Node 上运行,并且将无限期地保持在 Pending 状态。
NAME READY STATUS RESTARTS AGE
cpu-demo-2 0/1 Pending 0 7m
查看 Pod 的详细信息,包括事件
kubectl describe pod cpu-demo-2 --namespace=cpu-example
输出显示容器因 Node 上 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 资源没有上限。容器可以使用它正在运行的 Node 上可用的所有 CPU 资源。
容器正在运行在一个具有默认 CPU 限制的命名空间中,容器被自动分配该默认限制。集群管理员可以使用 LimitRange 来指定 CPU 限制的默认值。
如果你指定了 CPU 限制但未指定 CPU 请求
如果为容器指定了 CPU 限制但未指定 CPU 请求,Kubernetes 会自动分配一个与限制匹配的 CPU 请求。类似地,如果容器指定了自己的内存限制但未指定内存请求,Kubernetes 会自动分配一个与限制匹配的内存请求。
设置 CPU 请求和限制的动机
通过配置集群中运行的容器的 CPU 请求和限制,你可以高效地利用集群 Node 上可用的 CPU 资源。通过保持 Pod CPU 请求较低,你可以使 Pod 有更大的机会被调度。通过设置大于 CPU 请求的 CPU 限制,你可以达到两个目的:
- Pod 可以有突发活动,利用正好可用的 CPU 资源。
- Pod 在突发期间可以使用的 CPU 资源量被限制在一个合理的范围内。
清理
删除你的命名空间
kubectl delete namespace cpu-example