qos-in-k8s
一直感觉对kubernetes中的qos是一个盲点, 借着复习下scheduler的一些资源调度策略来学习下k8s中的qos策略, 然后再辐射到一般性的qos策略.
动机:
k8s 用非常简单的方式分配资源. 用户能够指定容器的资源限制. 比如一个用户能够指定某个container 只能使用1GB的内存. scheduler通过资源限制去调度容器. 如果某个节点的内存只有4GB, 那个一个有5Gb请求的容器就将不能调度到这个节点. 目前, k8s不能保证容器在一个超卖的系统中运行稳定.
目前的实现中, 如果用户指定limts给所有的container, 那么集群资源的利用率将会非常低下. 因为容器往往无法充分使用用户指定的那些资源. 一个可能的方式是不指定limits, 这样container就可以无限制的使用, 但是如果这些container无限制的使用资源, 就可能使得指定了limits的容器由于机器资源不够而被杀掉. 这是用户不愿意看到的, 他们希望自己指定了某个大小, 那么启动之后系统就应该保证这个容器的顺利运行.
qos机制就是在节点资源超卖的环境下, 通过提供不同级别的保证来满足资源的需求. 容器可以用request请求一个最小资源, request与limit不同, container可以使用超过request的值. best-effort级别的container相当于request为0的container. Best-effort container只使用那些其他container没有使用的资源, 可以用于资源清理(这个没看懂).
Request and limits
对于每种资源, container可以指定request和limits, 0 <= request <= limit <= infinity. 如果container成功调度, 意味着container能够保证至少有request的值的资源. container不能超过limit的值. 而request 和 limit 如何执行要看资源是compressible还是incompressible.
Compressible Resource Guarantees
- 目前只有cpu
- container至少得到request的cpu请求
- 剩余的cpu会按照cpu request比例分配给container. 比如container A request 60%, container B request 30%. 假设两个container都尝试拿到更多的cpu, 那么剩余的10%将按照2:1的比例分配.
- 如果超过limits, Containers 会被节流(不是被杀死).
Incompressible Resouce Guarantees
- 目前只有内存. (我认为本地存储也在这一类)
- Containers能够得到request的大小, 如果超过这个大小, 它们可能会被杀掉(如果其他container需要内存), 但是如果containers消耗的少于request值, 他们不会被删除(除非系统任务或者daemonset需要更多的内存)
- Containers会被杀掉如果他们使用了超过limit的内存.
Kubelet admission 策略
kubelet通过统计containers的request来确保系统资源不会被超载.
QoS 分级
概述
k8s Qos 分成三个等级:
- Guaranteed
- Burstable
- BestEffort
理论上QoS与limit, request应该是互不干扰的, 但实际上他们的联系非常紧密. QoS class不是自己设置的, 而是在创建pod的时候, 根据limit和request系统自动确认的.
Guaranteed
这是级别最高的, 他的触发条件是:
- 每个pod中container必须有内存的limit和request, 而且必须相同
- 每个pod中cpu必须有内存的limit和request, 而且必须相同
效果: 这些containers是最高优先级
注意: 如果设置了limit没有设置request, 系统将会自动填充request跟limit相同.
####Burstable
这个的触发条件是:
- pod不满足Guaranteed
- pod中至少一个container有内存或者cpu的请求.
效果: 能够保证request的请求, 但是不保证limit, 如果超出request请求的内存大小, 发生oom时可能会被杀死.
BestEffort
触发条件: 很明显, 没有指定任何request和limit或者值都是0就是BestEffort级别.
效果: 这些containers没有请求资源保障, 会被认为是最低优先级的, 如果系统发生oom, 他们会被首先杀死. 他们只会使用集群中没有被使用的那部分资源.
总结
所以k8s的qos主要是通过两方面: request,limit 和 qos class来实现的. 这两方面又有很多交叉的地方. 而且在面对不同的资源的时候, 他们的策略是不一样的.
Storage QoS
由于k8s中没有关于存储的qos机制, 于是关于存储的qos, 查看了一些文档.