简介

此文讲解如何定义容器CPU请求和CPU限制。容器使用的CPU不能超过配置的限制。如果系统有空闲的CPU时间,则可以保证为容器分配所需的CPU数量。

备注:此文档参考官方文档,并加以自己的理解。如有误导性的内容,请批评指正。

定义容器的CPU请求和限制

创建名称空间

# kubectl create namespace cpu-example

为了定义容器的CPU请求,使用容器资源清单中的resources:requests字段。为了定义CPU的限制,使用容器资源清单中的resources:limits字段,以下创建只用一个容器的Pod,该容器CPU请求是0.5,CPU限制数1。文件名:cpu-request-limit.yaml

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"

容器YAML配置文件的args块中提供的配置参数--cpus "2"告诉容器尝试使用2 CPUs。

创建Pod

# kubectl apply -f /root/k8s-example/pods/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

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

使用kubectl top 获取Pod的metrics指标

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

从输出结果看,该Pod使用了1001 milliCPU,该值小于Pod定义的CPU限制数1

NAME       CPU(cores)   MEMORY(bytes)
cpu-demo   1001m        1Mi

我们前面创建Pod时,设置的-cpu "2",即让容器尝试使用2 CPUs,但是容器只被分配了1个CPU,容器的CPU使用量受到限制,因为该容器正尝试使用超出其限制的CPU资源。

删除Pod

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

删除namespace

# kubectl delete namespace cpu-example

CPU 单位

CPU资源用 CPU作为单位。在Kubernetes中,等于

  • 1 AWS vCPU
  • 1 GCP Core
  • 1 Azure vCore
  • 1 Hyperthread on a bare-metal Intel processor with Hyperthreading

CPU允许使用小数值。确保请求0.5 CPU的容器的CPU是请求1 CPU的容器的一半。可以使用后缀m表示milli。例如100m CPU,100 milliCPU和0.1 CPU都相同。精度不能超过1m。

定义CPU请求远大于节点CPU个数

如果Pod自定义了CPU请求和限制,那么自定义容器的CPU请求和限制是非常有用的。一个Pod的CPU请求数等于该Pod内所有容器的CPU请求数总和;Pod的CPU限制数等于该Pod内所有容器CPU限制的总和。

Pod的基于请求数来调度,Pod被调度到有足够CPU资源的node上,该node节点满足该Pod请求的CPU资源。

创建一个Pod,该Pod的CPU请求数远大于集群节点任何node的CPU总数。文件名:``

# kubectl apply -f /root/k8s-example/pods/cpu-request-limit-2.yaml --namespace=cpu-example

查看Pod状态

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

从结果看出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

结果如下,容器不能被调度到任何node节点上,所有node节点没有足够的CPU资源。

Events:
  Type     Reason            Age        From               Message
  ----     ------            ----       ----               -------
  Warning  FailedScheduling  <unknown>  default-scheduler  0/7 nodes are available: 7 Insufficient cpu.

删除Pod

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

没有自定义CPU限制

如果没有自定义容器的CPU限制,适用以下情况之一:

  • 容器使用的CPU资源没有上限,只要容器在运行,容器能使用该node节点的所有CPU资源
  • 容器运行在默认CPU限制的namespace上,容器被自动分配默认的CPU限制,集群管理员可以使用LimitRange对象设置默认的CPU限制。

设置CPU请求数和限制数的原因

通过在集群中配置容器的CPU请求和内存限制,可以合理的使用集群中node节点的CPU资源。如果保证Pod的CPU请求在合理值范围内,则该Pod可以在集群中被合理的调度到合适的node节点上。