文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

kubernetes资源QOS机制实现原理是什么

2023-06-19 09:28

关注

本篇内容主要讲解“kubernetes资源QOS机制实现原理是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“kubernetes资源QOS机制实现原理是什么”吧!

QOS是k8s中一种资源保护机制,其主要是针对不可压缩资源比如的内存的一种控制技术,比如在内存中其通过为不同的Pod和容器构造OOM评分,并且通过内核的策略的辅助,从而实现当节点内存资源不足的时候,内核可以按照策略的优先级,优先kill掉哪些优先级比较低(分值越高优先级越低)的Pod,今天来分析下背后的实现

1.关键基础特性

kubernetes资源QOS机制实现原理是什么

1.1 一切皆文件

在Linux中一切皆文件,控制CGroup本身也是通过配置文件进行的,这是我创建的一个内存Lmits为200M的Pod的容器的配置

# pwd/sys/fs/cgroup# cat ./memory/kubepods/pod8e172a5c-57f5-493d-a93d-b0b64bca26df/f2fe67dc90cbfd57d873cd8a81a972213822f3f146ec4458adbe54d868cf410c/memory.limit_in_bytes209715200

1.2 内核内存配置

这里我们重点关注内存相关的两个配置:VMOvercommitMemory其值为1,表示运行分配所有的物理内存资源,注意不包括SWAP资源VMPanicOnOOM其值为0:表示当内存不足的时候触发oom_killer进行选择部分进程进行kill,QOS也是通过影响其kill流程来实现的

func setupKernelTunables(option KernelTunableBehavior) error {desiredState := map[string]int{utilsysctl.VMOvercommitMemory: utilsysctl.VMOvercommitMemoryAlways,utilsysctl.VMPanicOnOOM:       utilsysctl.VMPanicOnOOMInvokeOOMKiller,utilsysctl.KernelPanic:        utilsysctl.KernelPanicRebootTimeout,utilsysctl.KernelPanicOnOops:  utilsysctl.KernelPanicOnOopsAlways,utilsysctl.RootMaxKeys:        utilsysctl.RootMaxKeysSetting,utilsysctl.RootMaxBytes:       utilsysctl.RootMaxBytesSetting,}

2.QOS打分机制与判定实现

QOS打分机制主要是根据Requests和limits里面的资源限制来进行类型判定与打分的,我们就来快速看下这部分的实现

2.1 根据容器判定QOS类型

2.1.1 构建容器列表

遍历所有的容器列表,注意这里会包含所有的初始化容器和业务容器

requests := v1.ResourceList{}limits := v1.ResourceList{}zeroQuantity := resource.MustParse("0")isGuaranteed := trueallContainers := []v1.Container{}allContainers = append(allContainers, pod.Spec.Containers...)// 追加所有的初始化容器 allContainers = append(allContainers, pod.Spec.InitContainers...)

2.1.2 处理Requests和limits

这里遍历所有的Requests和Limits限制的资源,分别加入到不同的资源集合汇总,其中判定是不是Guaranteed主要是根据limits里面的资源是否包含CPU和内存两种资源,都包含才可能是Guaranteed

for _, container := range allContainers {// process requestsfor name, quantity := range container.Resources.Requests {if !isSupportedQoSComputeResource(name) {continue}if quantity.Cmp(zeroQuantity) == 1 {delta := quantity.DeepCopy()if _, exists := requests[name]; !exists {requests[name] = delta} else {delta.Add(requests[name])requests[name] = delta}}}// process limitsqosLimitsFound := sets.NewString()for name, quantity := range container.Resources.Limits {if !isSupportedQoSComputeResource(name) {continue}if quantity.Cmp(zeroQuantity) == 1 {qosLimitsFound.Insert(string(name))delta := quantity.DeepCopy()if _, exists := limits[name]; !exists {limits[name] = delta} else {delta.Add(limits[name])limits[name] = delta}}}if !qosLimitsFound.HasAll(string(v1.ResourceMemory), string(v1.ResourceCPU)) {// 必须是全部包含cpu和内存限制isGuaranteed = false}}

2.1.3 BestEffort

如果Pod里面的容器没有任何requests和limits的限制则就是BestEffort

if len(requests) == 0 && len(limits) == 0 {return v1.PodQOSBestEffort}

2.1.4 Guaranteed

要是Guaranteed必须是资源相等,并且限定的数量相同

// Check is requests match limits for all resources.if isGuaranteed {for name, req := range requests {if lim, exists := limits[name]; !exists || lim.Cmp(req) != 0 {isGuaranteed = falsebreak}}}if isGuaranteed &&len(requests) == len(limits) {return v1.PodQOSGuaranteed}

2.1.5 Burstable

如果不是上面两种就是最后一种burstable了

return v1.PodQOSBurstable

2.2 QOS OOM打分机制

2.2.1 OOM打分机制

其中guaranteedOOMScoreAdj是-998其实这跟OOM实现有关系,一台node节点上主要是三部分组成:kubelet主进程、docker进程、业务容器进程,而OOM的打分里面-1000表示该进程不会被oom所kill, 那一个业务进程最少也就只能是-999因为你不能保证自己的业务永远不会出现问题,所以在QOS里面-999其实就是kubelet和docker进程所保留的,剩下的才能作为业务容器分配(分值越高越容易被kill)

// KubeletOOMScoreAdj is the OOM score adjustment for KubeletKubeletOOMScoreAdj int = -999// DockerOOMScoreAdj is the OOM score adjustment for DockerDockerOOMScoreAdj int = -999// KubeProxyOOMScoreAdj is the OOM score adjustment for kube-proxyKubeProxyOOMScoreAdj  int = -999guaranteedOOMScoreAdj int = -998besteffortOOMScoreAdj int = 1000

2.2.2 关键Pod

关键Pod是一种特殊的存在,它可以是Burstable或者BestEffort类型的Pod,但是OOM打分却可以跟Guaranteed一样,这种类型的Pod主要包含三种:静态Pod、镜像Pod和高优先级Pod

if types.IsCriticalPod(pod) {return guaranteedOOMScoreAdj}

判定实现

func IsCriticalPod(pod *v1.Pod) bool {if IsStaticPod(pod) {return true}if IsMirrorPod(pod) {return true}if pod.Spec.Priority != nil && IsCriticalPodBasedOnPriority(*pod.Spec.Priority) {return true}return false}

2.2.3 Guaranteed与BestEffort

这两种类型都有各自默认的值分别为Guaranteed(-998)和BestEffort(1000)

switch v1qos.GetPodQOS(pod) {case v1.PodQOSGuaranteed:// Guaranteed containers should be the last to get killed.return guaranteedOOMScoreAdjcase v1.PodQOSBestEffort:return besteffortOOMScoreAdj}

2.2.4 Burstable

其中关键的一行就是:oomScoreAdjust := 1000 - (1000memoryRequest)/memoryCapacity,从这个计算里面可以看出,如果我们申请的资源越多,那么 (1000memoryRequest)/memoryCapacity这个里面计算出来的时机值就会越小,即最终结果就越大,其实也就表明如果我们占用的内存越少,则打分就越高,这类容器就相对比较容易被kill

memoryRequest := container.Resources.Requests.Memory().Value()oomScoreAdjust := 1000 - (1000*memoryRequest)/memoryCapacity// A guaranteed pod using 100% of memory can have an OOM score of 10. Ensure that burstable pods have a higher OOM score adjustment.if int(oomScoreAdjust) < (1000 + guaranteedOOMScoreAdj) {return (1000 + guaranteedOOMScoreAdj)}// Give burstable pods a higher chance of survival over besteffort pods.if int(oomScoreAdjust) == besteffortOOMScoreAdj {return int(oomScoreAdjust - 1)}return int(oomScoreAdjust)

到此,相信大家对“kubernetes资源QOS机制实现原理是什么”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     807人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     351人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     314人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     433人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     221人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯