一个计算机技术爱好者与学习者

0%

好好学K8S:K8S中的Request和Limit

1. Pod和容器的资源设置

当我们定义 Pod 时,可以选择性地为每个容器设定所需要的资源数量。最常见的可设定资源是 CPU 和内存(RAM)大小;此外还有其他类型的资源。

当我们为 Pod 中的 Container 指定了资源 request(请求) 时, kube-scheduler 就利用该信息决定将 Pod 调度到哪个节点上。
当我们为 Container 指定了资源 limit(限制) 时,kubelet 就可以确保运行的容器不会使用超出所设限制的资源。
kubelet 还会为容器预留所 request(请求) 数量的系统资源,供其使用。

参考文档:

2. K8S中的资源单位

2.1. CPU资源单位

CPU 资源的限制和请求以 cpu 为单位。
在 Kubernetes 中,一个 CPU 等于 1 个物理 CPU 核 或者 1 个虚拟核, 取决于节点是一台物理主机还是运行在某物理主机上的虚拟机。

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

CPU 资源总是设置为资源的绝对数量而非相对数量值。 例如,无论容器运行在单核、双核或者 48-核的机器上,500m CPU 表示的是大约相同的计算能力。

2.2. 内存资源单位

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

1
128974848、129e6、129M、128974848000m、123Mi

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

2.3. 本地临时性存储单位

ephemeral-storage 本地临时性存储的单位和内存资源的单位相同。

本地临时性存储说明:
节点可以具有本地的临时性存储,由本地挂接的可写入设备或者有时也用 RAM 来提供支持。
临时(Ephemeral)意味着对所存储的数据不提供长期可用性的保证。

Pods 通常可以使用临时性本地存储来实现缓冲区、保存日志等功能。 kubelet 可以为使用本地临时存储的 Pods 提供这种存储空间,允许后者使用 emptyDir 类型的卷将其挂载到容器中。

kubelet 也使用此类存储来保存节点层面的容器日志、 容器镜像文件以及运行中容器的可写入层。

详情参考文档本地临时存储

2.4. GPU资源单位

K8S中,在调度使用GPU资源时,使用不同的 Kubernets Device Plugin,GPU单位也是不同的。

参考文档:

3. 容器资源设置示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
---
apiVersion: v1
kind: Pod
metadata:
name: frontend
spec:
containers:
- name: app
image: images.my-company.example/app:v4
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
- name: log-aggregator
image: images.my-company.example/log-aggregator:v6
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"

上面的 Pod 有两个容器。每个容器的请求为 0.25 CPU 和 64MiB(226 字节)内存, 每个容器的资源限制为 0.5 CPU 和 128MiB 内存。 我们可以认为该 Pod 的资源请求为 0.5 CPU 和 128 MiB 内存,资源限制为 1 CPU 和 256MiB 内存。

4. 设置Request和Limit默认值

可使用 LimitRange 来设置 namespace 的 request 与 limit 默认值,也可设定 request 与 limit 的最大值与最小值。示例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
apiVersion: v1
kind: LimitRange
metadata:
name: cpu-resource-constraint
namespace: test
spec:
limits:
- default: # 此处定义默认限制值
cpu: 500m
defaultRequest: # 此处定义默认请求值
cpu: 500m
max: # max 和 min 定义限制范围
cpu: "1"
min:
cpu: 100m
type: Container

5. 怎样设置合理的Request和Limit?

5.1. 建议设置Request

Request 的值并不代表给容器实际分配的资源大小,而是用于提供给调度器。调度器会检测每个节点可用于分配的资源(节点可分配资源 = 节点资源总额 - 已调度到节点上的 Pod 内容器 request 之和),同时记录每个节点已经被分配的资源(节点上所有 Pod 中定义的容器 request 之和)。如发现节点剩余的可分配资源已小于当前需被调度的 Pod 的 request,则该 Pod 就不会被调度到此节点。反之,则会被调度到此节点。

如果不配置 request,调度器就无法感知节点资源使用情况,无法做出合理的调度决策,可能会造成调度不合理,引起节点状态混乱。建议给所有容器设置 request,使调度器可感知节点资源情况,以便做出合理的调度决策。集群的节点资源能够被合理的分配使用,避免因资源分配不均而导致发生故障。

5.2. 重要应用Request等于Limit

在Kubernetes中,request和limit之间的差异决定了容器的QoS类别。

  • 如果 request == limit,则容器属于Guaranteed QoS类别。
  • 如果 request < limit,则容器属于Burstable QoS类别。
  • 如果没有设置request和limit,则容器属于BestEffort QoS类别。

不同的QoS类别有不同的调度和驱逐策略。
节点资源不足时,会触发自动驱逐和删除,优先删除BestEffort容器,其次是Burstable容器,最后是Guaranteed容器。
同时,request和limit之间的差值越大,Burstable类型的容器被驱逐的风险就越高。

对于生产环境中关键的服务,推荐设置 request == limit ,即Guaranteed QoS类别,以保证在节点故障时关键服务不易被驱逐导致线上业务受到影响。

5.3. 提高资源利用率

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

5.4. 避免Request和Limit值过大

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

5.5. 避免测试 namespace 消耗过多资源

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

1
2
3
4
5
6
7
8
9
10
11
apiVersion: v1
kind: ResourceQuota
metadata:
name: quota-test
namespace: test
spec:
hard:
requests.cpu: "1"
requests.memory: 1Gi
limits.cpu: "2"
limits.memory: 2Gi
  • 本文作者: 好好学习的郝
  • 原文链接: https://www.voidking.com/dev-k8s-request-limit/
  • 版权声明: 本文采用 BY-NC-SA 许可协议,转载请注明出处!源站会即时更新知识点并修正错误,欢迎访问~
  • 微信公众号同步更新,欢迎关注~