资源限制是我们可以向Kubernetes提供的诸多配置之一,它意味着两点:
- 工作负载运行需要哪些资源;
- 最多允许消费多少资源。
第一点对于调度器而言十分重要,因为它要以此选择合适的节点。
第二点对于Kubelet非常重要,每个节点上的守护进程Kubelet负责Pod的运行健康状态。
做k8说中资源限制是通过每个容器containerSpec的resources字段进行设置的,它是v1版本的ResourceRequirements类型的API对象。每个指定了"limits"和"requests"的对象都可以控制对应的资源。
目前只支持CPU和内存两种资源。第三种资源类型,持久化存储仍然是beta版本。
大多数情况下,deployment、statefulset、daemonset的定义里都包含了podSpec和多个containerSpec。这里有个完整的v1资源对象的yaml格式配置:
resources:
requests:
cpu: 50m
memory: 50Mi
limits:
cpu: 100m
memory: 100Mi
这个对象可以这么理解:
这个容器通常情况下,需要5%的CPU时间和50MiB的内存(requests),同时最多允许它使用10%的CPU时间和100MiB的内存(limits)。
对requests和limits有什么区别,但是一般来说,在调度的时候requests比较重要,在运行时limits比较重要。尽管资源限制配置在每个容器上,你可以认为Pod的资源限制就是它里面容器的资源限制之和,我们可以从系统的视角观察到这种关系。
说明:
内存单位后缀Mi表示的是MiB
CPU单位后缀 m 表示千分之一核,也就是说 1 Core = 1000m。
你会注意到除了我们设置的limits外,Pod还增加了requests。当你设置limits而没有设置requests时,Kubernetes默认让requests等于limits。如果你从调度器的角度看这是非常有意义的。
假设你没有配置内存requests来运行Pod,而配置了一个较高的limits。正如我们所知道的Kubernetes默认会把requests的值指向limits,如果没有合适的资源的节点的话,Pod可能会调度失败,即使它实际需要的资源并没有那么多。
另一方面,如果你运行了一个配置了较低requests值的Pod,你其实是在鼓励内核oom-kill掉它。为什么?假设你的Pod通常使用100MiB内存,你却只为它配置了50MiB内存requests。如果你有一个拥有75MiB内存空间的节点,那么这个Pod会被调度到这个节点。当Pod内存消耗扩大到100MiB时,会让这个节点压力变大,这个时候内核可能会选择杀掉你的进程。所以我们要正确配置Pod的内存requests和limits。
网友评论