k8s之内存、CPU资源请求与限制

一个 Kubernetes 集群可被划分为多个命名空间。 如果你在具有默认内存限制和默认CPU限制的命名空间内尝试创建一个 Pod,并且这个 Pod 中的容器没有声明自己的内存和CPU限制, 那么控制面会为该容器设定默认的内存限制和默认的CPU限制,Kubernetes 还可以在某些情况指定默认的内存请求和CPU请求

CPU资源单位

在k8s中,一个 CPU 等于 1 个物理 CPU 核 或者 1 个虚拟核, 取决于节点是一台物理主机还是运行在某物理主机上的虚拟机

你也可以表达带小数 CPU 的请求。 当定义一个容器,将spec.containers[].resources.requests.cpu 设置为 0.5 时, 你所请求的 CPU 是你请求 1.0 CPU 时的一半。 对于 CPU 资源单位,数量 表达式 0.1 等价于表达式 100m,可以看作 “100 millicpu”。 有些人说成是“一百毫核”,其实说的是同样的事情

CPU 资源总是设置为资源的绝对数量而非相对数量值。 例如,无论容器运行在单核、双核或者 8核的机器上,500m CPU 表示的是大约相同的计算能力,Kubernetes 不允许设置精度小于 1m 的 CPU 资源。 因此,当 CPU 单位小于 1 或 1000m 时,使用毫核的形式是有用的; 例如 5m 而不是 0.005,最小为1m

内存资源单位

memory 的限制和请求以字节为单位。 你可以使用普通的整数,或者带有以下 数量后缀 的定点数字来表示内存:E、P、T、G、M、k。 你也可以使用对应的 2 的幂数:Ei、Pi、Ti、Gi、Mi、Ki。 例如,以下表达式所代表的是大致相同的值:

30M=30Mi

请注意后缀的大小写。如果你请求 400m 临时存储,实际上所请求的是 0.4 字节。 如果有人这样设定资源请求或限制,可能他的实际想法是申请 400Mi 字节(400Mi) 或者 400M 字节

内存请求与限制

1、首先我们在命名空间test中创建资源限制清单,指定了默认的内存请求和默认内存限制,如图:

查看命名空间test中创建的LimitRange资源,如图:

2、在命名空间test中创建pod,pod中容器不声明内存请求和内存限制,如图:

3、查看pod详情,可通过命令kubectl get po podname -o yaml -n test,如图:

从上图可以看出,pod中的内存请求和内存限制都是 LimitRange 设置的默认值

4、下面手动指定pod中容器的内存限制但是不指定内存请求,如图:

查看创建后的pod详细信息,如图:

从上图看出,内存请求的值也是1G,与设置的内存限制一样,而不是最开始设置的默认值256M

5、下面手动指定pod中容器的内存请求但是不指定内存限制,如图:

创建后查看pod详细信息,如图:

从上图看出,容器的内存请求为我们手动设定的128M,但是内存限制为最开始设置的默认值512M

注:LimitRange 设置的 limit 的默认值可能小于客户端提交给 API 服务器的声明中为容器指定的 request 值。如果发生这种情况,最终会导致 Pod 无法调度

6、修改pod,将内存请求设置为1G,如图:

查看结果可以看到pod无法完成调度,如图:

默认的请求是256M,默认限制为512M,但是我们设置了pod中容器请求为1G,因此导致pod无法调度

同时设置了 request 和 limit,那么即使使用相同的 LimitRange,新 Pod 也会被成功调度,如下修改pod的内存请求和限制都超过了默认值,请求600,限制800,如图:

此时pod可以正常调度,并且定义的限制值会覆盖掉默认值限制值

CPU请求与限制

1、首先我们在命名空间test中创建资源限制清单,指定了默认的CPU请求和默认CPU限制,如图:

查看命名空间test中创建的LimitRange资源,如图:

2、在命名空间test中创建pod,pod中容器不声明CPU请求和CPU限制,如图:

3、查看pod详情,可通过命令kubectl get po podname -o yaml -n test,如图:

从上图可以看出,pod中的CPU请求和CPU限制都是 LimitRange 设置的默认值

4、下面pod中容器声明了 CPU 限制,而没有声明 CPU 请求,如图:

查看创建后的pod详细信息,如图:

从上图看出,CPU请求的值也是1,与设置的CPU限制一样,而不是最开始设置的默认值0.5

5、下面pod中容器声明了 CPU 请求,而没有声明 CPU 限制,如图:

创建后查看pod详细信息,如图:

从上图看出,容器的CPU请求为pod中设定的值,CPU限制则为默认值

如果你的命名空间设置了 CPU 资源配额, 为 CPU 限制设置一个默认值会很有帮助。 以下是 CPU 资源配额对命名空间的施加的两条限制:

  • 命名空间中运行的每个 Pod 中的容器都必须有 CPU 限制
  • CPU 限制用来在 Pod 被调度到的节点上执行资源预留

预留给命名空间中所有 Pod 使用的 CPU 总量不能超过规定的限制

配置最小和最大内存约束

首先在命名空间test中定义内存最小与最大的约束清单,没有指定默认的请求和限制值,如图:

执行清单文件后,查看资源信息,如图:

从上图看出,虽然我们没有指定默认值,但是默认值也会自动生成,并且都是700M

此时,如果我们在命名空间test中创建pod时,k8s将会执行如下步骤:

  • 如果 Pod 中的任何容器未声明自己的内存请求和限制,控制面将为该容器设置默认的内存请求和限制
  • 确保该 Pod 中的每个容器的内存请求至少 256 MiB
  • 确保该 Pod 中每个容器内存请求不大于700M

1、修改上面Pod文件,定义内存请求和限制在最小和最大限制内,如图:

创建pod后,查看pod中的资源信息,如图:

从上图可以看出,pod中的资源请求和限制都在最开始定义的最小和最大之间

2、修改pod,声明内存限制的值超出最开始设置的最大的值700,如图:

创建后,可以发现pod并没有创建出来,查看deploy,如图:

从上图看出,此pod并没有创建成功,因为内存限制已经超出了最大内存的值700M

3、修改pod,定义内存请求的值小于设置的最小内存请求的值,如图:

查看pod信息,可以看到pod并没有创建成功,因此内存限制小于最小内存值,如图:

4、创建一个没有声明内存请求和内存限制的pod,如图:

查看pod中的资源情况,如图:

从上图看出,没有为pod中容器指定内存请求和限制的值,那么pod会从LimitRange中来获取这个值,并且获取的是max的值作为请求和限制的值

配置最小和最大CPU约束

CPU的最小和最大约束与内存的使用方法基本一样,只需要将上图中的memory改为cpu,然后后面的数值改为对应CPU的单位即可,比如:

cpu: 1      #表示1颗CPU
cpu: 500m   #表示500毫核,为半颗CPU

具体使用方法参考内存最小和最大约束即可

为命名空间配置内存和CPU配额

命名空间下运行的所有 Pod 设置总的内存和 CPU 配额。你可以通过使用 ResourceQuota 对象设置配额

1、创建namespace,如下:

kubectl create namespace mem-cpu-example

2、创建 ResourceQuota资源清单,内容如下:

ResourceQuota 在mem-cpu-example 命名空间中设置了如下要求:

  • 在该命名空间中的每个 Pod 的所有容器都必须要有内存请求和限制,以及 CPU 请求和限制
  • 在该命名空间中所有 Pod 的内存请求总和不能超过 1 GiB
  • 在该命名空间中所有 Pod 的内存限制总和不能超过 2 GiB
  • 在该命名空间中所有 Pod 的 CPU 请求总和不能超过 1 cpu
  • 在该命名空间中所有 Pod 的 CPU 限制总和不能超过 2 cpu

配置命名空间下pod配额

命名空间中设置可运行 Pod 总数的配额。 你可以通过使用 ResourceQuota 对象来配置配额

1、创建一个命名空间,如下:

kubectl create namespace quota-pod-example

2、创建 ResourceQuota清单,最多运行2个pod,内容如下:

查看情况,可以看到配额是2,使用率为0,如图:

3、定义pod资源文件,指定副本数为3个,如图:

4、查看创建后的Pod数,可以发现只有2个,因此我们定义的命名空间限额就是2个,如图:

标签