图解 K8S 源码 - QoS 篇
前言
日常使用 Kubernetes 时,时长会出现 Node 节点中的 Pod 被 OOMKill 掉的情况,但 Node 节点中 Pod 众多,为什么单单选中这个 Pod Kill 掉呢?这里就引出了 QoS 的概念,本篇文章就会从源码的角度介绍 QoS 的分类、打分机制,并简单介绍不同 QoS 的本质区别。看看这个机制是如何保证运行在 Kubernetes 中服务质量的。
QoS
QoS(Quality of Service) 即服务质量,是 Kubernetes 中的一种控制机制,其会对运行在 Kubernetes 中的 Pod 进行一个质量划分,根据 Pod 中 container 的 Limit 和 request 将 Pod 分为 Guaranteed
,Burstable
,BestEffort
三类并对所有 Pod 进行一个打分。在资源尤其是内存这种不可压缩资源不够时,为保证整体质量的稳定,Kubernetes 就会根据 QoS 的不同优先级,对 Pod 进行资源回收。这也是有时集群中的 Pod 突然被 kill 掉的原因。
QoS 分类
以下代码用来获取 Pod 的 QoS 类,用于区分不同 Pod 的 QoS。
QoS 打分
QoS 会根据不同的分类进行 OOMScore 打分,当宿主机上内存不足时,系统会优先 kill 掉 OOMScore 分数高的进程。
值得注意的是不久之前 guaranteedOOMScoreAdj
的值还是 -998
,今年 9 月 22 日才合并 PR[1] 将其修改为 -997
,而修改的 PR 及 相关 ISSUE[2] 在 2018 年就已经提出了,感兴趣的同学可以去看看。这里附上源码:
QoS 的本质区别
三种 QoS 在调度和实现都存在着区别:
调度时,调度器只会根据 request 值进行调度,这也就解释了有些 Node 节点 Resource Limit 超出 100% 的情况
当 OOM 时,系统会根据
oom_score
值来选择优先 kill 掉的进程,分数越高越先被 kill 掉。oom_score
由系统计算所得,用户是不能设置的。但是如上文所述,而根据 QoS 的类型,kubelet 会计算出oom_score_adj
的值,通过oom_score_adj
来调整oom_score
的分数,从而影响 OOM 被 kill 进程的优先级。对于资源的限制,是由 CGroup 来完成的。kubelet 会为三种 QoS 分别创建 QoS level CGroup:
Guaranteed
Pod Qos 的 CGroup level 会直接创建在RootCgroup/kubepods
下Burstable
Pod Qos 的创建在RootCgroup/kubepods/burstable
下BestEffort
Pod Qos 的创建在RootCgroup/kubepods/BestEffort
下而在 Pod level CGroup 中还会创建 Container level CGroup,其结构如下图所示:
结语
本文我们讨论了 Kubernetes 中 QoS 机制的分类、打分及其本质,除了这些 QoS 的实现 QOSContainerManager
中还有三种 QoS 以宿主机上 allocatable 资源量为基础为 Pod 分配资源,并通过多个 level cgroup 进行层层限制的逻辑,由于篇幅有限,就不做详细介绍了。
版权声明: 本文为 InfoQ 作者【郭旭东】的原创文章。
原文链接:【http://xie.infoq.cn/article/6cc703a111360ccc97e8b1f72】。文章转载请联系作者。
评论