K8S-CPU-RAM资源配额整理

1.   K8S资源配额

       在K8S集群环境中,宿主机的计算资源是有限的,当多个用户或者多个团队共同使用该集群环境时,一个重要的事情就是如何公平的分配宿主机计算资源。为了精细控制POD中容器对宿主机计算资源的使用情况,K8S中提供了requests和limits配额设置方案。此外K8s还提供了ResourceQuota对象和LimitRange对象来控制某个命名空间下POD的资源配额,具体作用如下:

1)    ResourceQuota可以对某个命名空间下资源总量进行限制

2)    LimitRange可以为某个命令空间下POD中容器提供资源配额的默认值,以及指定资源配额的设置范围。

1.1 requests和limits

该资源配额设置方案是在POD的yaml文件中,针对每一个容器显式指定资源配额数值,从而对每个容器的资源进行限制。整体设置如下图所示:

 

由上图可以看到,requests和limits配额设置是定义在POD内容器层面上的,未定义资源配额的容器默认值为0,POD的资源配额值为POD内所有容器资源配额之和(已验证,包括初始化容器)。

CPU和RAM 换算单位如下:

1)   CPU

单位为m时表示毫核(1个逻辑核分1000毫核);单位为空默认单位为(逻辑)核。

2) RAM

K,M,G,T,P,E       通常这些单位是以1000为换算标准的。

Ki, Mi,Gi, Ti,Pi, Ei 这些通常是以1024为换算标准的

1.1.1 requests介绍

requests是POD期望能够得到的资源值,主要作用是K8S调度POD时节点选择的判断依据。只有当节点上未分配的资源量 >= request 时,才允许将POD调度到该节点上。requests不限制POD的最大可使用资源。

 

如上图所示,节点上有A、B、C三个POD,现在 Pod D在调度的时候,K8s统计节点上未分配的资源量,其中CPU的未分配资源量(Unallocated)小于Pod D的CPU requests值,故Pod D仍然无法调度到该节点上。可见,K8S 调度Pod的时候并不关注在调度时节点的资源实际使用情况,而是根据现存非终止态容器的requests之和情况判断是否进行调度。(已验证,终止态容器包含初始化容器和job的业务容器)

此外, Pod实际使用量可能大于或小于设置的requests资源值。如果Kubernetes找不到满足资源请求的Node,则Pod创建会停留在Pending状态。

    针对CPU和RAM,requests的作用总结如下:

  • CPU requests的作用

1)    作为k8s调度POD进行节点筛选的判断依据(绝对值)

2)    宿主机CPU资源抢占时,容器按比例分配CPU使用的依据(相对值)

                 CPU requests,会对应到容器内cgroup下cpu.shares属性上,当宿主机CPU资源发生抢占时,各个容器按照shares份额比例进行宿主机CPU资源的使用。

  • RAM requests的作用

             1)   POD作为k8s调度POD进行节点筛选的依据

1.1.2 limits介绍

Limits表示POD使用资源的最大值,如果不设置limits,则理论上POD可以使用Node的全部资源。如果POD设置limits,则该POD的资源使用的最大值不超过设置的limits值,并且全部POD资源limits总和可以超过Node的容量。

  • CPU limits

CPU是一种可以压榨的资源,可以用满并且Pod之间可以共享使用。CPU limits会作用到cgroup下的cpu.cfs_quota_us(CPU切换周期内的最大使用时间,单位us)属性上,从而控制POD能使用的CPU资源的上限。

cpu.cfs_quota_us值受cpu.cfs_period_us(CPU切换周期,默认100ms)的影响。公式近似如下:

  • RAM limits

内存limits对应cgroup下memory.limit_in_bytes属性上,当节点的RAM被使用完或者POD超过了limits上限,便会触发 OOM Killed。

1.2   ResourceQuota对象

1.2.1 作用

1. 为某一个命名空间设置指定资源总量的约束,可以防止不同命名空间肆意使用宿主机资源。

2. 强制约束命名空间下POD内所有容器指定一个资源配额或者使用默认值,否则POD创建失败,报 403 FORBIDDEN 。

1.2.2 设置方式

以CPU和RAM计算资源为例,设置方式如下图所示:

 

该对象定义了,某个命名空间下,所有非终止态的POD:

  1. CPU requests之和不超过1核
  2. CPU limits之和不超过为2核
  3. RAM requests之和不超过1Gi
  4. RAM limits之和不超过2Gi

1.2.3 验证结论

1.  ResourceQuota作用时机:不影响已经存在的pod运行(POD重启除外),对之后POD的创建合法性进行检查

2.  POD定义的资源配额之和不能超过该对象中定义的资源总和,否则POD创建失败

3.  ResourceQuota要求pod内所有容器(包括初始化容器)必须按要求配置上资源配额,否则创建失败

1.3   LimitRange对象

1.3.1  作用

  1. 为POD或者Container设置CPU、RAM资源配额的最小值和最大值
  2. 为POD或者Container设置CPU、RAM资源配额的limits和requests的比率
  3. 为POD内容器设置CPU、RAM资源配额默认的requests和limits
  4. LimitRange作用于POD的创建阶段,YAML文件中设置的资源配额不符合limitRange对象的约束要求,则容器会启动失败(403 FORBIDDEN);已运行的POD不受限制(POD重启除外)。

1.3.2  设置方式

 

字段属性说明:

1.  type:取值为Pod或者Container,表示作用域为Pod或者容器

2.  min:Pod或者容器CPU、RAM  requests资源最小值

3.  max:Pod或者容器CPU、RAM  requests资源最大值

4.  default:容器的CPU、RAM  limits的默认值

5.  defaultRequest:容器的CPU、RAM  requests的默认值

6.  maxLimitRequestRatio:Pod或者容器CPU、RAM的 limits值和requests值两者之间的最大比值

1.3.3  验证结论

  1. Type可以为POD或者Container,不同Type下资源设置值大小没有约束关系
  2. Type为POD的时候,不支持在该类型下设置CPU、RAM计算资源的默认值
  3. Min < defultRequest < defaultLimits < max  ,计算资源的(limits/requests)比率 <= max/min
  4. POD中容器的资源配额设置需要在Limitrange的min和max之间
  5. POD中容器如果只设置CPU配额,RAM配额会使用Limitrange的默认值
  6. POD设置的资源配额的比率要小于等于limitrange的比率限制,并且K8S不检查limitrange中设置的默认值设置是否符合比率要求。

2. 资源值的获取

为了准确的获取POD的消耗的资源值,有以下2个关键点

3.2.1 真实可靠的业务压力

        特定组件根据自身特点,首先需要模拟出“正常”和“峰值”下的业务操作(或称为业务操作集合),在执行该业务压力下,去监控POD使用的资源,才更具有代表性。

3.2.2     有效的资源消耗监控手段

为了获取容器的资源使用情况,有以下2种命令行工具,如下表所示:

监控方式

说明

Kubectl top

  1. K8S命令行工具,默认一分钟更新一次

Kubectl top查询的是heapster组件每1分钟的聚合数据。Heapster的聚合数据是将内存中2分钟内的cAdvisor的监控数据进行整合汇总后插入数据库。cAdvisor是每10秒监控一下POD资源消耗,并将数据放在内存中。

  1. 查询的RAM包括了缓存cache + 真实的内存消耗

Docker stats

  1. Dokcer容器资源消耗监控工具,默认一秒钟更新一次
  2. RAM不包括缓存cache

3.2.2.1        特别说明

  • CPU-limits:设置过小,将会影响容器的api响应速度;设置过大,该容器内部故障时,又限制不了该容器的cpu资源使用量,导致其他容器可用cpu资源变少
  • RAM-limits:设置过小,oom风险增加;设置过大,该容器内部故障时,又限制不了该容器的ram资源使用量,导致其他容器可用ram资源变少,设置oom
  • CPU-requests: 设置过小,部署的容器过多导致节点资源紧张,影响每个容器;设置过大,节点资源会大大浪费
  • RAM-requests: 设置过小,部署的容器过多导致节点资源紧张,影响每个容器;设置过大,节点资源会大大浪费
原文地址:https://www.cnblogs.com/qgbk2018/p/13168032.html