Kubernetes的Limits和Requests

本文深入探讨Kubernetes中资源分配的核心概念,包括Limits和Requests的作用,Namespace配额的设定,以及如何为Pod设置合适的资源请求和限制,确保集群高效稳定运行。
部署运行你感兴趣的模型镜像

在k8s的集群环境中,资源的合理分配和使用至关重要。毕竟容器化要解决的问题之一就是资源的充分利用。在集群中分配资源的时候就不得不提到Limits和Requests。

Namespace配额

众所周知,Kubernetes 是允许管理员在命名空间中指定资源 Requests 和 Limits 的,这一特性对于资源管理限制非常有用。但它目前还存在一定局限:如果管理员在命名空间中设置了 CPU Requests 配额,那么所有 Pod 也要在其定义中设置 CPU Requests,否则就无法被调配资源。

apiVersion: v1
kind: ResourceQuota
metadata:
  name: mem-cpu-example
spec:
  hard:
    requests.cpu: 4
    requests.memory: 4Gi
    limits.cpu: 6
    limits.memory: 6Gi

这是一个简单的ResourceQuota类型,也就是针对Namespace的配额。它会针对Namespace做如下限额:

  • 所有 CPU Requests 的总和不能超过 4 个内核
  • 所有 RAM Requests 的总和不能超过 4GiB
  • 所有 CPU Limits 的总和不能超过 6个内核
  • 所有 RAM Limits 的总和不能超过 6GiB

针对Pod的Request和Limit

刚才讲到我们可以针对Pod进行资源限额,同样也可以设置Pod申请资源的Request和Limit。k8s中会将一个CPU分成1000个shares,这和Cgroup中分成1024略有差异。正常情况下requests的数值应该小于limits,那么该Pod获得的资源可以分为两部分:

  • 完全可靠的资源,资源量大小等于requests值
  • 不可靠的资源,资源量最大等于limits和requests的差额,这份不可靠的资源能够申请到多少,取决于当时主机上容器可用资源的余量。
    如下例:
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
 name: redis
 labels:
   name: redis
   app: redis-app
spec:
 replicas: 2
 selector:
   matchLabels:
    name: redis
    role: redisdb
    app: redis-app
 template:
   spec:
     containers:
       - name: redis
         image: redis:5.0.3-alpine
         resources:
           limits:
             memory: 500Mi
             cpu: 1
           requests:
             memory: 250Mi
             cpu: 500m
       - name: busybox
         image: busybox:1.28
         resources:
           limits:
             memory: 100Mi
             cpu: 100m
           requests:
             memory: 50Mi
             cpu: 50m
  • Pod 中共两个容器,的有效 Request 是 300MiB 的内存和 550 毫核(millicore)的 CPU。我们需要一个具有足够可用可分配空间的节点来调度 Pod
  • 如果 Redis 容器尝试分配超过 500MB 的 RAM,就会被 OOM-killer
  • 如果 Redis 容器尝试每 100ms 使用 100ms 以上的 CPU,那么 Redis 就会受到 CPU 限制(如果我们一共有 4 个内核,可用时间为 400ms/100ms),从而导致性能下降
  • 如果 busybox 容器尝试分配 100MB 以上的 RAM,也会引起 OOM
  • 如果 busybox 容器尝试每 100ms 使用 10ms 以上的 CPU,也会使 CPU 受到限制,从而导致性能下降
    需要注意的是,Kubernetes 限制的是每个容器,而不是每个 Pod。其他 CPU 指标,如共享 CPU 资源使用情况,只对分配有参考价值,所以如果遇到了性能上的问题,建议不要在这些指标上浪费时间。

Requests等于Limits 的时候

一般情况下我们设置的Requests值一般都要小于Limits,但是也存在特殊情况。涉及到一个概念就是服务质量等级

  • Guaranteed(完全可靠的);Limits==requests,或者只设置了Limits,此时默认requests等于limits
  • Burstable(弹性波动、较可靠的);分为两种情况:1、Pod中一部分容器在一种或多种资源类型中配置了requests和limits,2、Pod中一部分容器未定义资源配置(requests和limits都未配置)
  • BestEffort(尽力而为、不太可靠的);Pod所有中所有容器都未定义requests和limits

注意:在容器未定义limits时,limits值默认是节点资源容量的上限。

另外,当我们分配CPU的requests和limits相等的时候,就是指该容器独占CPU,需要在kubelet服务的配置中增加--cpu-manager-policy=static

可压缩资源和不可压缩资源

我们上文提到,在容器可使用的资源有CPU和内存。所以我们拓展一下k8s集群中的可压缩资源和不可压缩资源概念。
在k8s中,CPU就是可压缩资源。空闲的CPU资源会按照容器的requests值得比例进行分配,举例说明:容器A requests1 limits 10;容器B requests2 limits 8,假如一开始该节点上可用CPU为3,那么两个容器恰好得到各自requests的量。此时节点又释放了1.5CPU,A和B都需要更多CPU资源,那么这1.5CPU就会按照A和B的requests量按比例分配,最后A得到1.5CPU,B得到3CPU。

目前,k8s支持的不可压缩资源是内存。Pod中可以得到requests的内存量,如果Pod使用小于该值,那么Pod正常运行;如果Pod使用超过了该值极=就有可能被k8s杀掉。比如,Pod A使用了大于requests但是小于limits的内存,此时Pod B使用了小于requests的内存,但是Pod B中的程序突然压力增大,向k8s请求更多的但是不超过自己requests的内存资源,而节点上已没有空闲内存资源,这时候k8s就可能会直接kill Pod A。

选择可靠的Requests和Limits

具备一定 Kubernetes 经验的人都知道正确设置 Request 和 Limit 对于应用程序和集群的性能的重要性。

理想情况下,Pod 请求多少资源,它就用多少资源,但在现实场景下,资源使用是不断变化的,而且它的变化没有规律,不可预测。

如果 Pod 的资源使用量远低于请求量,那会导致资源(金钱)浪费;如果资源使用量高于请求量,那就会使节点出现性能问题。因此在实际操作中,我们可以把 Request 值上下浮动 25% 作为一个良性参考标准。

而关于 Limit,设置合理的 Limit 数值其实需要尝试,因为它主要取决于应用程序的性质、需求模型、对错误的容忍度以及许多其他因素,没有固定答案。
在这里插入图片描述
另一件需要考虑的事是在节点上允许的 Limits 过量使用。

这些 Limits 由用户执行,因为 Kubernetes 没有关于超额使用的自动化机制。

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值