原作者 Javier Martínez
背景
在学习 Kubernetes 调度时,有两个重要的概念,“request “与 “limit”,而对应的资源就是“内存” 与 “CPU” ,而这两个决定了 Pod 将如何调度;“request “与 “limit” 也是整个调度系统中的基数因子。
什么是 request 和 limit
在 Kubernetes 中,Limit 是容器可以使用的最大资源量,这表示 “容器” 的内存或 CPU 的使用,永远不会超过 Limit 配置的值。
而另一方面,Request 则是为 “容器” 保留的最低资源保障;换句话来说,Request 则是在调度时,容器被允许所需的配置。
如何配置 request 和 limit
下列清单是 Deployment 的部署清单,他将部署一个 redis 与 一个 busybox
|
|
假设现有集群,具有 4 核CPU 和 16GB RAM 节点。此时可以提取出的信息如下:
Pod Request 是 400 MiB 内存和 600 毫核 CPU (Redis+busybox)。而调度需要一具有足够可用可分配空间的Node
来调度 Pod。
redis的 CPU 为 512,busybox 容器的 CPU 份额为 102,Kubernetes 为每个核心分配 1024 个份额,因此 redis:1024 * 0.5 个核心 ≅ 512 与 busybox:1024 * 0.1 个核心 ≅ 102
如果 Redis 容器尝试分配超过 600MB 的内存,则它会被 OOM 终止
如果 Redis 每 100 毫秒超过超过 100 毫秒时的 CPU,(Node有 4 个核,可用时间为每 100 毫秒 400 毫秒时),Redis 将受到 CPU 限制,从而导致性能下降**。**
如果 Busybox 容器试图分配超过 200MB 的内存,它将被 OOM 终止
如果Busybox尝试每 100 毫秒使用超过 30 毫秒的 CPU
Request
通过上面示例,可以下定义了,Kuberentes 将 Request 定义为容器的 最小资源量。
当一个 Pod 被调度时,kube-scheduler
将检查 Kubernetes 请求,以便将该 Pod 分配到最佳节点,该节点至少可以满足 Pod 中所有容器的数量。如果 Request 的数量高于可用资源,则 Pod 将不会被调度并保持在 Pending 状态。
例如下列例子
|
|
使用请求:
将 Pod 分配给 Node 时,满足 Pod 中容器指示的 Request 。
在运行时,指示的 Request 将保证为该 Pod 中的容器的最小 Request 。
Limit
Limit 在 Kubernetes 为定义容器可以使用的最大资源量。这代表容器永远不会超过 Limit 配置的 内存 或 CPU 。
|
|
- 在调度时,如果没有配置 Request,默认 Kubernetes 将设置 requests = limits。
- 调度后,运行时,kubelet 检查 Pod 中的容器是否消耗了比 Limit 中配置的更多的资源。
CPU 和 内存的特性
CPU 是一种 “可压缩资源”,这意味着它可以被拉伸以满足所有需求。如果进程申请了太多 CPU,其中一些将被限制。
- 可以使用 millicores (m) 来表示比1核心更小的数量
- CPU 最小量为 1m
内存是一种 “不可压缩的” 资源,这意味着内存资源不能像 CPU 资源那样被拉伸。如果一个进程没有足够的内存来工作,这个进程就会被 OOM。
内存资源在 Kubernetes 中的单位是以字节为单位,可以使用大写的 E、P、T、G、M、k 来表示 Exabyte、Petabyte、Terabyte、Gigabyte、Megabyte 和 kilobyte,例如 4G, 500M;也可以使用 Ei、Pi、Ti,例如 500Mi
**G 和 Gi ** 的区别:**G 和 Gi **区别主要在计算方式上,G是按照 2 的 n 次方进行计算,例如 1KB = $2^{10}$,而 Gi 计算方式是按照 10 的 n 次方,例如 1Mi = $10^3$
Note:不要使用小写的 “m” ,这代表 Millibytes
Resource/LimitQuota - 基于名称空间的资源限制
ResourceQuotas 在 Kubernetes 集群中提供了基于名称空间的资源隔离,我们可以将资源隔离到不同的名称空间中,也称为租户;例如可以 为整个命名空间设置内存或 CPU 限制,确保名称空间内的业务不能从使用更多的系统资源。
下列是一个 ResourceQuotas 的配置
|
|
requests.cpu
:名称空间中所有 Request 的最低 CPU 数量requests.memory
:名称空间中所有 Request 的 最低内存数量limits.cpu
:名称空间中所有 Limit 最大 CPU 数量limits.memory
:名称空间中所有 Limit 最大内存量
ResourceQuotas 可限制名称空间的资源总量,如果我们想给里名称空间里的 Pod 配置限制可以使用 “LimitRange”
下列是一个 LimitRanges 的配置
|
|
default
: 如果未指定,创建的容器将具有此值。min
:创建的容器不能有小于此的限制或请求。max
: 创建的容器不能有比这更大的限制或请求。
Note: 在默认情况下,即使未设置
LimitRanges
,Pod 中的所有容器也会有效地请求 100m 的 CPU。
总结
- Request 和 Limit 是在 Kubernetes 集群中控制成本的关键配置
- 只有巧用 Request 和 Limit 才可以为集群提供最佳配额
- 专用的 容器不应该设置 Request 和 Limit,这将导致容器无法正常允许,甚至被驱逐
- 只有对 Request 和 Limit 进行精细的设置才可以使 Kubernetes 集群最佳化,否则 “弊大于利”