一、什么是QoS¶
服务质量类(Quality of Service class,QoS class)Kubernetes 在 Node 资源不足时使用 QoS 类来就驱逐 Pod 作出决定。
K8s集群中的每个Pod,都会有对应的QoS级别(在Kubernetes中通过Resources参数即可配置QoS的级别),可用于决定Pod在资源紧张时的处理顺序,同时可以确保关键服务的稳定性和可靠性。
二、QoS出现背景¶
虽然我们可以给没有配置requests和limits的Pod添加默认值,也可以限制资源请求的范围,但是在使用Kubernetes部署时,应用的部署和更新都会经过一系列的调度策略将应用部署在最合适的节点上,但是随着时间的推移,当时“最优”的节点可能已经不再是最佳选择,因为在该服务器上别的应用或者其他管理员部署的应用可能忘记了配置资源限制,所以在日积月累的消耗中,宿主机一些不可压缩的资源(比如内存、磁盘)的使用率将达到最高峰。假如内存达到最高峰时会引起OOMKilled故障,此时Kubelet会根据某些策略重启上面的容器用来避免宿主机宕机引来的风险,但是重启容器难免会带来服务中断的现象,如果重启的是比较重要的业务应用,这将是一个非常不好的体验。QoS就应运而生,可以保证在系统资源不够的情况下尽量保证一些比较重要的Pod不被杀死。
三、QoS分类¶
Kubernetes为我们提供了3种级别的服务质量,分别是:
- Guaranteed:最高服务质量,当宿主机内存不够时,会先杀死QoS为BestEffort和Burstable的Pod,如果内存还是不够,才会杀死QoS为Guaranteed的Pod,该级别Pod的资源占用量一般比较明确,即requests字段的cpu和memory与limits字段的cpu和memory配置的一致。
- Burstable:服务质量低于Guaranteed,当宿主机内存不够时,会先杀死QoS为BestEffort的Pod,如果内存还是不够,就会杀死QoS级别为Burstable的Pod,用来保证QoS质量为Guaranteed的Pod,该级别的Pod一般知道最小资源使用量,但是当机器资源充足时,还是想尽可能使用更多的资源,即limits字段的cpu和memory大于requests字段的cpu和memory的配置。
- BestEffort:尽力而为,当宿主机内存不够时,首先杀死的就是该QoS的Pod,用以保证Burstable和Guaranteed级别的Pod正常运行。
实现不同级别的服务质量是根据requests和limits的配置决定的,在宿主机资源不够时会先杀死服务质量为BestEffort的Pod,然后杀死服务质量为Burstable的Pod,最后杀死服务质量为Guaranteed的Pod。所以在生产环境中比较重要的应用最好设置为Guaranteed,当然如果集群资源足够使用,可以都设置为Guaranteed。
下面总结一下,关于这3种级别的服务质量满足条件:
- Guaranteed:
- Pod中的每个容器必须指定limits.memory和requests.memory, 并且两者需要相等;
- Pod中的每个容器必须指定limits.cpu和limits.memory,并且两者需要相等
- Burstable:
- Pod不符合Guaranteed的配置要求
- Pod中至少有一个容器配置了requests.cpu或requests.memory
- BestEffort:
- 不设置resources参数