Pod的请求和限制
如果 Pod 运行所在的节点具有足够的可用资源,容器可能(且可以)使用超出对应资源 requests属性所设置的资源量。
例如,如果你将容器的memory的请求量设置为 256 MiB,而该容器所处的 Pod 被调度到一个具有 8 GiB 内存的节点上,并且该节点上没有其他 Pod 运行, 那么该容器就可以尝试使用更多的内存。限制是另一个话题。cpu限制和memory限制都由 kubelet以及容器运行时来实施, 最终由内核强制执行。在 Linux 节点上,Linux 内核通过 CGroup 来强制执行限制。cpu限制和memory限制的执行行为略有不同。cpu限制通过 CPU 节流机制(CPU Throttling)来强制执行。 当某容器接近其cpu限制值时,内核会基于容器的限制值来限制其对 CPU 的访问。 因此,cpu限制是内核强制执行的一个硬性限制。容器不得使用超出其cpu限制所指定的 CPU 核数。限制由内核使用 OOM(内存不足)杀死机制来强制执行。 当某容器使用的内存超过其memory限制时,内核可以终止此容器。 然而,终止操作只会在内核检测到内存压力时才会发生。 因此,内存分配过量的容器可能不会被立即终止。 这意味着memory限制是被动执行的。 某容器可以使用超过其memory限制的内存,但如果这样做了,它可能会被终止。对于一个 Pod,你可以通过包含以下内容来指定 CPU 和内存的资源限制和请求:
spec.resources.limits.cpuspec.resources.limits.memoryspec.resources.limits.hugepages-<size>spec.resources.requests.cpuspec.resources.requests.memoryspec.resources.requests.hugepages-<size>
Kubernetes 中的资源单位
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 表示的是大约相同的算力。
说明:
Kubernetes 不允许设置精度小于 1m 或 0.001 的 CPU 资源。 为了避免意外使用无效的 CPU 数量
内存资源单位
memory 的限制和请求以字节为单位。你可以使用普通的整数, 或者带有以下数量后缀的定点数字来表示内存: E、P、T、G、M、k。你也可以使用对应的 2 的幂数:Ei、Pi、Ti、Gi、Mi、Ki。 Kubernetes API 也允许使用 m 作为后缀(表示毫字节:1/1000 字节), 但这并不实用:你必须始终分配整数个字节,或者有时是更大的块,例如 1 GiB 的倍数。
以下是一些表示近似相同值的内存数量示例:
128974848, 129e6, 129M, 128974848000m, 123Mi
请注意后缀的大小写。如果你请求 400m 临时存储,实际上所请求的是 0.4 字节。 "M" 代表兆字节,"m" 代表毫字节。如果你请求 "400m" 的内存,则表示请求 0.4 字节。 如果有人这样设定资源请求或限制,可能他的实际想法是申请 400Mi 字节(400Mi) 或者 400M 字节。
Pod 资源示例
apiVersion: v1
kind: Pod
metadata:
name: pod-resources-demo
namespace: pod-resources-example
spec:
resources:
limits:
cpu: "1"
memory: "200Mi"
requests:
cpu: "1"
memory: "100Mi"
containers:
- name: pod-resources-demo-ctr-1
image: nginx
resources:
limits:
cpu: "0.5"
memory: "100Mi"
requests:
cpu: "0.5"
memory: "50Mi"
- name: pod-resources-demo-ctr-2
image: fedora
command:
- sleep
- inf
QoS 类(服务质量)
Kubernetes 基于每个 Pod 中容器的资源请求和限制为 Pod 设置 QoS 类。Kubernetes 使用 QoS 类来决定从遇到节点压力的 Node 中驱逐哪些 Pod。可选的 QoS 类有 Guaranteed、Burstable 和 BestEffort。
Guaranteed(保证的)
Guaranteed Pod 具有最严格的资源限制,并且最不可能面临驱逐。 在这些 Pod 超过其自身的限制或者没有可以从 Node 抢占的低优先级 Pod 之前, 这些 Pod 保证不会被杀死。这些 Pod 不可以获得超出其指定 limit 的资源。
判据
- Pod 必须设置 Pod 级别的内存 limit 和内存 request,并且这两个值必须相等。
- Pod 必须设置 Pod 级别的 CPU limit 和 CPU request,并且这两个值必须相等。
Burstable(突发的)
Burstable Pod 有一些基于 request 的资源下限保证,但不需要特定的 limit。 如果未指定 limit,则默认为其 limit 等于 Node 容量,这允许 Pod 在资源可用时灵活地增加其资源。 在由于 Node 资源压力导致 Pod 被驱逐的情况下,只有在所有 BestEffort Pod 被驱逐后 这些 Pod 才会被驱逐。因为 Burstable Pod 可以包括没有资源 limit 或资源 request 的容器, 所以 Burstable Pod 可以尝试使用任意数量的节点资源。
判据
- Pod 不满足针对 QoS 类 Guaranteed 的判据。
- Pod 中至少一个容器有内存或 CPU 的 request 或 limit,或者 Pod 本身设置了 Pod 级别的内存或 CPU 的 request 或 limit。
BestEffort(尽力而为的)
BestEffort QoS 类中的 Pod 可以使用未专门分配给其他 QoS 类中的 Pod 的节点资源。 例如若你有一个节点有 16 核 CPU 可供 kubelet 使用,并且你将 4 核 CPU 分配给一个 Guaranteed Pod, 那么 BestEffort QoS 类中的 Pod 可以尝试任意使用剩余的 12 核 CPU。
如果节点遇到资源压力,kubelet 将优先驱逐 BestEffort Pod。
判据
Pod本身没有设置任何 Pod 级别的内存或CPU的 limit 或 request 时,会被认为是 BestEffort
参考资料