如何提升 Kubernetes 资源利用率

2025-10-23 23:25:00
丁国栋
原创 35
摘要:本文主要记录和汇总如何提升Kubernetes 资源利用率相关知识。

如何提升 Kubernetes 资源利用率

Kubernetes 调度器的调度决策

首先需要搞清楚两个概念: 

1、机器实际利用率 

2、k8s 封装率(有的翻译叫做装箱率)

3、利用率不等于封装率


k8s 调度看的是节点封装率,即 这个节点上所有pod request.cpu 和 request.memory 占用比例进行打分决定。 节点利用率是节点真实进程占用使用节点资源大小,与k8s 封装率 是两个概念,所以 pod 能否调度到节点上,是要看节点封装率,决定是否可以调度: 举个例子: 

1、有个8c16G的节点,封装率 cpu 和 memory 分别为 85% 和 90% 

2、节点利用率 cpu和 mem 分别为 35% 和 55% 


pod 调度时 是看1的封装率,不是看2的利用率。

Pod 状态 Pending 或者节点池自动扩容的原因

如果发现Pod无法分配到节点,可能的原因有: 1、节点资源不足 2、存在选择器标签不匹配,如 Pod 设置了节点亲和性(Node Affinity) 3、节点状态不可用或者设置为不调度等

要查看集群的资源用量,不仅需要查看利用率还要查看封装率,关于这一部分可以参考腾讯云的文档节点使用资源分布

名词 描述
CPU 利用率 CPU 利用率定义为节点真实 CPU 资源使用量除以节点规格。
CPU 装箱率 CPU 装箱率定义为节点上所有 Pod 的 CPU Request 之和除以节点规格。
内存利用率 内存利用率定义为节点真实内存资源使用量除以节点规格。
内存装箱率 内存装箱率定义为节点上所有 Pod 的内存 Request 之和除以节点规格。

为什么 Kubernetes 集群实际资源利用率不高?

降本增效从云计算发展至今一直都是企业上云最核心的关注点,无论是在线业务还是大数据、AI业务,都非常依赖算力的消耗,成本问题都是企业上云进行决策的核心因素。 从云计算本身来看,单纯把业务从 IDC 搬迁上云不修改任何业务架构,提高计算资源利用率需要非常大的运维成本和人力成本投入到改造业务适配弹性伸缩和业务可调度性中。

Kubernetes 可以显著提升业务编排能力和资源利用率,但如果没有额外的支持,其提升效果会非常有限。根据 TKE 团队之前的统计数据(参见 Kubernetes 降本增效标准指南 | 容器化计算资源利用率现象剖析),TKE 节点的资源平均利用率仅为 14%左右。而 Kubernetes 集群的资源利用率不高的主要原因是根据 Kubernetes 的资源调度逻辑,在创建 Kubernetes 工作负载时,通常需要为工作负载配置合适的资源 Request 和 Limit,表示对资源的占用和限制,其中对利用率影响最大的是 Request。用户为了防止自己的工作负载资源被其他工作负载占用,或者为了应对高峰流量时的资源消耗需求,用户习惯于为 Request 设置较大的数值。Request 和实际使用资源之间的差值是不能被其他工作负载使用的,因此造成了资源浪费。Request 数值设置不合理,导致了 Kubernetes 集群资源利用率低下。


如果 Pod 定义的 request 值较高,但实际CPU和内存利用率很低,那么可能会出现节点有资源但无法调度 Pod 的情况,从而引发节点自动扩容。


资源利用率低的企业,在使用容器时,前期更多仅关注在容器解决环境一致性的问题上,实际上并未充分利用好容器的弹性能力, 并且在部署模型上,单节点的容器密度不高,导致整体资源利用率跟容器化改造前差异不大。

从实际数据看,业务即便已经容器化,但在一定时间內的资源使用,仍然存在波峰波谷不均的情况。因此,为了保证服务的可靠性和稳定性,一般会以流量峰值为基线去配置资源规格,以保证高并发时业务以良好的性能运转,但是过了峰值期之后(一般时间占比较小),业务回到峰谷状态,实际仅使用一小部分资源,从而导致在峰谷时段,造成大量的资源浪费。

合理利用 Kubernetes 节点资源

要做到合理利用 Kubernetes 节点资源就必须正确设置 Pod 的 request 值。参考腾讯云的这个文档:设置 Request 与 Limit

容器的 request 及 limit 需根据服务类型、需求及场景进行灵活设置。

Request 工作原理

Request 的值并不代表给容器实际分配的资源大小,而是用于提供给调度器。调度器会检测每个节点可用于分配的资源(节点可分配资源 = 节点资源总额 - 已调度到节点上的 Pod 内容器 request 之和),同时记录每个节点已经被分配的资源(节点上所有 Pod 中定义的容器 request 之和)。如发现节点剩余的可分配资源已小于当前需被调度的 Pod 的 request,则该 Pod 就不会被调度到此节点。反之,则会被调度到此节点。 若不配置 request,调度器就无法感知节点资源使用情况,无法做出合理的调度决策,可能会造成调度不合理,引起节点状态混乱。建议给所有容器设置 request,使调度器可感知节点资源情况,以便做出合理的调度决策。集群的节点资源能够被合理的分配使用,避免因资源分配不均而导致发生故障。 设置 request 与 limit 默认值 可使用 LimitRange 来设置 namespace 的 request 与 limit 默认值,也可设定 request 与 limit 的最大值与最小值。示例如下:

apiVersion: v1
kind: LimitRange
metadata:
  name: mem-limit-range
  namespace: test
spec:
  limits:
  - default:
      memory: 512Mi
      cpu: 500m
    defaultRequest:
      memory: 256Mi
      cpu: 100m
    type: Container

重要线上应用配置

节点资源不足时,会触发自动驱逐,删除低优先级的 Pod 以释放资源使节点自愈。Pod 优先级由低到高排序如下:

  1. 未设置 request 及 limit 的 Pod。
  2. 设置 request 值不等于 limit 值的 Pod。
  3. 设置 request 值等于 limit 值的 Pod。

建议重要线上应用设置 request 值等于 limit 值,此类 Pod 优先级较高,在节点故障时不易被驱逐导致线上业务受到影响。

提高资源利用率

如应用设置了较高的 request 值,而实际占用资源远小于设定值,会导致节点整体的资源利用率较低。除对时延非常敏感的业务外,敏感的业务本身并不期望节点利用率过高,影响网络包收发速度。 建议对非核心,并且资源非长期占用的应用,适当减少 request 以提高资源利用率。若您的服务支持水平扩容,则除 CPU 密集型应用外,单副本的 request 值通常可设置为不大于1核。例如,coredns 设置为0.1核,即100m即可。

避免 request 与 limit 值过大

若您的服务使用单副本或少量副本,且 request 及 limit 的值设置过大,使服务可分配到足够多的资源去支撑业务。则某个副本发生故障时,可能会给业务带来较大影响。当 Pod 所在节点发生故障时,由于 request 值过大,且集群内资源分配的较为碎片化,其余节点无足够可分配资源满足该 Pod 的 request,则该 Pod 无法实现漂移,无法自愈,会加重对业务的影响。 建议尽量减小 request 及 limit,通过增加副本的方式对您的服务支撑能力进行水平扩容,使系统更加灵活可靠。

避免测试目的使用的 namespace 消耗过多资源

若生产集群有用于测试的 namespace,如不加以限制,则可能导致集群负载过高,影响生产业务。可以使用 ResourceQuota 限制测试 namespace 的 request 与 limit 的总大小。示例如下:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: quota-test
  namespace: test
spec:
  hard:
    requests.cpu: "1"
    requests.memory: 1Gi
    limits.cpu: "2"
    limits.memory: 2Gi

Request 推荐最小值

Deployment、StatefulSet 等资源的推荐最小值:单个容器推荐的 CPU 最小值是0.125核,即125m;内存的最小值是125Mi。

参考资料:

  1. Request 智能推荐
  2. TKE Insight 成本洞察
  3. kubernetes 降本增效标准指南| 容器化计算资源利用率现象剖析
发表评论
博客分类