关于K8s中资源服务质量管理Resource Qos的一些笔记整理
admin
2024-03-14 11:54:17
0

写在前面


  • 分享一些 K8s中资源服务质量管理Resource Qos 的笔记
  • 博文内容涉及:
    • K8s Qos 简单介绍
    • 资源配置的特点: 节点的超用可压缩/不可压缩,完全可靠性等介绍
    • QoS Classes 介绍
    • 三种 Qos 服务质量等级定义的 Demo
  • 理解不足小伙伴帮忙指正

精神的寓所是我们的,不是阴曹地府,不是天上星辰,这两者都是活在我们之中的精神所制作的。 ----《作为意志和表象的事件》


一些名词解释

Qos : Qos 最先是在网络链路中提出的,QoS(Quality of Service)即服务质量。在有限的带宽资源下,QoS 为各种业务分配带宽,为业务提供端到端的服务质量保证。例如,语音、视频和重要的数据应用在网络设备中可以通过配置 QoS 优先得到服务。可以单纯的理解为 服务质量保证、控制、管理

服务质量管理 Qos服务质量协议(SLA)以及服务质量指标(SLI)、服务质量目标(SLO) 都涉及到了 服务质量,但是是不同的, Qos 更多的是对行为的描述, 而 SLA 等是标准,可以这样理解,期望通过 Qos 的管理来观测 SLI 达到 SLO ,从而符合 SLA。关于服务质量目标更多,小伙伴可以看看 《SRE Google 运维解密》 第四章 的部分,这里不多介绍。

K8s Qos 简介

Kubernetes 可以根据 Pod 的 Requests 和 Limits 配置来实现针对 Pod 的不同级别的资源服务质量控制(QoS),之前看到有 小伙伴讲 QoS 才是 Google K8s 的精华所在。

容器中 Requests 是 Kubernetes 调度时能为容器提供的完全可保障的资源量(最低保障),而 Limits 是系统允许容器运行时可能使用的资源量的上限(最高上限)。Pod 级别的资源配置是通过计算 Pod 内所有容器的资源配置的总和得出来的。

资源配置特点

Kubernetes 中 Pod 的 Requests 和 Limits 资源配置有如下特点:

  • 如果 Pod 配置的 Requests 值等于 Limits 值,那么该 Pod 可以获得的资源是完全可靠的。这里的完全可靠单纯可以理解不可变,不会随着 Node 的资源情况发生波动
  • 如果 Pod 的 Requests 值小于 Limits 值,那么该 Pod 获得的资源可分成两部分:
    • 完全可靠 的资源,资源量的大小等于 Requests 值,申请的最少资源,pod任何时候都要有这么多
    • 不可靠的 资源,资源量最大等于 Limits 与 Requests 的差额,这份不可靠的资源能够申请到多少,取决于当时主机上容器可用资源的余量。

通过这种机制,Kubernetes 可以实现节点资源的 超售(Over Subscription),对应的 Pod 可以实现 超用(Over Committed)

节点资源的 Over Subscription

比如在 CPU 完全充足的情况下,某机器共有32GiB内存可提供给容器使用,容器配置为 Requests 值1GiB,Limits 值为2GiB,那么在该机器上最多可以同时运行32个容器,每个容器最多可以使用2GiB内存,如果这些容器的内存使用峰值能错开,那么所有容器都可以正常运行。

超售机制能有效提高资源的利用率,同时不会影响容器申请的完全可靠资源的可靠性。

Kubernetes 根据Pod配置的Requests值来调度Pod,Pod 在成功调度之后会得到 Requests 值定义的资源来运行;

如果 Pod 所在机器上的资源有空余,则 Pod 可以申请更多的资源,最多不能超过 Limits 的值。

Requests和Limits对不同计算资源类型的限制机制

Requests 和 Limits 针对不同计算资源类型的限制机制的差异。这种差异主要取决于计算资源类型是 可压缩资源还是不可压缩资源。这里的压缩即如果资源超出 Cgroup 的限制后的状态,可压缩的资源pod 还可以存活,不可压缩的资源 pod 会被 Kill

可压缩资源

Kubernetes 目前支持的可压缩资源是 CPU。 Pod 可以得到 Pod 的 Requests 配置的 CPU 使用量,而能否使用超过 Requests 值的部分取决于系统的负载和调度。空闲 CPU 资源按照容器 Requests 值的比例分配。即 节点中超过 requests 的资源按照 申请资源的比例分配,如果 Pod 使用了超过在 Limits 中配置的 CPU 用量,那么 cgroups 会对 Pod 中的容器的 CPU 使用进行限流(Throttled)

不可压缩资源

Kubernetes 目前支持的不可压缩资源是内存。Pod 可以得到在 Requests 中配置的内存。如果 Pod 使用的内存量小于它的 Requests 的配置,那么这个 Pod 可以正常运行(除非出现操作系统级别的内存不足等严重问题);如果 Pod 使用的内存量超过了它的 Requests 的配置,那么这个 Pod 有可能被 Kubernetes 杀掉,如果 Pod 使用的内存量超过了它的 Limits 设置,那么操作系统内核会杀掉 Pod 所有容器的所有进程中使用内存最多的一个,直到内存不超过 Limits 为止。

比如 Pod A 使用了超过 Requests 而不到 Limits 的内存量,此时同一机器上另外一个 Pod B 之前只使用了远少于自己的 Requests 值的内存,此时程序压力增大,PodB 向系统申请的总量不超过自己的 Requests 值的内存,那么 Kubernetes 可能会直接杀掉 PodA;另外一种情况是 PodA 使用了超过 Requests 而不到 Limits 的内存量,此时 Kubernetes 将一个新的 Pod 调度到这台机器上,新的 Pod 需要使用内存,而只有 PodA 使用了超过了自己的 Requests 值的内存,那么 Kubernetes 也可能会杀掉 Pod A 来释放内存资源。

对调度策略的影响

Kubernetes的kubelet通过计算Pod中所有容器的Requests的总和来决定对Pod的调度。不管是CPU还是内存,Kubernetes调度器和kubelet都会确保节点上所有Pod的Requests的总和不会超过在该节点上可分配给容器使用的资源容量上限。

服务质量等级(QoS Classes)

在一个超用(Over Committed,容器Limits总和大于系统容量上限)系统中,由于容器负载的波动可能导致操作系统的资源不足,最终可能导致部分容器被杀掉。

在这种情况下,我们当然会希望优先杀掉那些不太重要的容器,那么如何衡量重要程度呢?Kubernetes将容器划分成3个QoS等级,这三种优先级依次递减:

  • Guaranteed(完全可靠的)
  • Burstable(弹性波动、较可靠的)
  • BestEffort(尽力而为、不太可靠的)

当前的 QoS级别 直接由 Requests 和 Limits 来定义。在Kubernetes中容器的QoS级别等于容器所在Pod的QoS级别,而Kubernetes的资源配置定义了Pod的三种QoS级别,如下所述。

创建一个 QoS 类为 Guaranteed 的 Pod

对于 QoS 类为 Guaranteed 的 Pod:

  • Pod 中的每个容器都必须指定内存限制和内存请求。
  • 对于 Pod 中的每个容器,内存限制必须等于内存请求。
  • Pod 中的每个容器都必须指定 CPU 限制和 CPU 请求。
  • 对于 Pod 中的每个容器,CPU 限制必须等于 CPU 请求。
  • 这些限制同样适用于初始化容器和应用程序容器。

如果Pod中的所有容器对所有资源类型都定义了 Limits和Requests,并且所有容器的Limits值都和Requests值全部相等(且都不为0),那么该Pod的QoS级别就是Guaranteed。

在下面这两个例子中定义的Pod QoS级别就是Guaranteed:

┌──[root@vms81.liruilongs.github.io]-[/]
└─$cat qos-pod.yaml
apiVersion: v1
kind: Pod
metadata:name: qos-demonamespace: qos-example
spec:containers:- name: qos-demo-ctrimage: nginxresources:limits:memory: "200Mi"cpu: "700m"requests:memory: "200Mi"cpu: "700m"

创建后可以看到 qosClass 级别为: Guaranteed

┌──[root@vms81.liruilongs.github.io]-[/]
└─$kubectl create namespace qos-example
namespace/qos-example created
┌──[root@vms81.liruilongs.github.io]-[/]
└─$kubectl  apply -f qos-pod.yaml
pod/qos-demo created
┌──[root@vms81.liruilongs.github.io]-[/]
└─$kubectl get pods -n qos-example qos-demo -o json | jq  .status.qosClass
"Guaranteed"

在这种情况下,容器可以不定义Requests,因为Requests值在未定义时默认等于Limits

┌──[root@vms81.liruilongs.github.io]-[/]
└─$cat qos-pod.yaml
apiVersion: v1
kind: Pod
metadata:name: qos-demonamespace: qos-example
spec:containers:- name: qos-demo-ctrimage: nginxresources:limits:memory: "200Mi"cpu: "700m"

创建之后发现一样

┌──[root@vms81.liruilongs.github.io]-[/]
└─$kubectl  apply -f qos-pod.yaml
pod/qos-demo configured
┌──[root@vms81.liruilongs.github.io]-[/]
└─$kubectl get pods -n qos-example qos-demo -o json | jq  .status.qosClass
"Guaranteed"
┌──[root@vms81.liruilongs.github.io]-[/]
└─$kubectl get pods -n qos-example qos-demo -o json | jq  .spec.containers[0].resources
{"limits": {"cpu": "700m","memory": "200Mi"},"requests": {"cpu": "700m","memory": "200Mi"}
}
┌──[root@vms81.liruilongs.github.io]-[/]
└─$

创建一个 QoS 类为 BestEffort 的 Pod

如果Pod中所有容器都未定义资源配置(Requests和Limits都未定义),那么该Pod的QoS级别就是BestEffort。

┌──[root@vms81.liruilongs.github.io]-[/]
└─$cat qos-pod.yaml
apiVersion: v1
kind: Pod
metadata:name: qos-demonamespace: qos-example
spec:containers:- name: qos-demo-ctrimage: nginxresources:

容器没有设置内存和 CPU 限制或请求。

┌──[root@vms81.liruilongs.github.io]-[/]
└─$kubectl  apply -f qos-pod.yaml
pod/qos-demo created
┌──[root@vms81.liruilongs.github.io]-[/]
└─$kubectl get pods -n qos-example qos-demo -o json | jq  .spec.containers[0].resources
{}
┌──[root@vms81.liruilongs.github.io]-[/]
└─$kubectl get pods -n qos-example qos-demo -o json | jq  .status.qosClass
"BestEffort"
┌──[root@vms81.liruilongs.github.io]-[/]
└─$

创建一个 QoS 类为 Burstable 的 Pod

当一个 Pod 既不为 Guaranteed 级别,也不为 BestEffort 级别时,该 Pod 的 QoS 级别就是Burstable。Burstable级别的Pod包括两种情况。

如果满足下面条件,将会指定 Pod 的 QoS 类为 Burstable:

Pod 不符合 Guaranteed QoS 类的标准。即Pod中的一部分容器在一种或多种资源类型的资源配置中定义了Requests值和Limits值(都不为0),且Requests值小于Limits值;

┌──[root@vms81.liruilongs.github.io]-[/]
└─$cat qos-pod.yaml
apiVersion: v1
kind: Pod
metadata:name: qos-demonamespace: qos-example
spec:containers:- name: qos-demo-ctrimage: nginxresources:limits:memory: "200Mi"requests:memory: "100Mi"

Kubernetes 为 Pod 配置的 QoS 类为 Burstable

┌──[root@vms81.liruilongs.github.io]-[/]
└─$kubectl  apply -f qos-pod.yaml
pod/qos-demo created
┌──[root@vms81.liruilongs.github.io]-[/]
└─$kubectl get pods -n qos-example qos-demo -o json | jq  .spec.containers[0].resources
{"limits": {"memory": "200Mi"},"requests": {"memory": "100Mi"}
}
┌──[root@vms81.liruilongs.github.io]-[/]
└─$kubectl get pods -n qos-example qos-demo -o json | jq  .status.qosClass
"Burstable"
┌──[root@vms81.liruilongs.github.io]-[/]
└─$

Pod 中至少一个容器具有内存或 CPU 的请求或限制。Pod中的一部分容器未定义资源配置(Requests和Limits都未定义)。注意:在容器未定义Limits时,Limits值默认等于节点资源容量的上限。

┌──[root@vms81.liruilongs.github.io]-[/]
└─$cat qos-pod.yaml
apiVersion: v1
kind: Pod
metadata:name: qos-demonamespace: qos-example
spec:containers:- name: qos-demo-1image: nginxresources:limits:memory: "200Mi"requests:memory: "100Mi"- name: qos-demo-2image: nginx

创建一个包含两个容器的 Pod

┌──[root@vms81.liruilongs.github.io]-[/]
└─$kubectl  apply -f qos-pod.yaml
pod/qos-demo created

查看对于的资源配置和 Qos 等级,Pod 配置的 QoS 类为 Burstable

┌──[root@vms81.liruilongs.github.io]-[/]
└─$kubectl get pods -n qos-example qos-demo -o json | jq  .spec.containers[0].resources
{"limits": {"memory": "200Mi"},"requests": {"memory": "100Mi"}
}
┌──[root@vms81.liruilongs.github.io]-[/]
└─$kubectl get pods -n qos-example qos-demo -o json | jq  .spec.containers[1].resources
{}
┌──[root@vms81.liruilongs.github.io]-[/]
└─$kubectl get pods -n qos-example qos-demo -o json | jq  .status.qosClass
"Burstable"
┌──[root@vms81.liruilongs.github.io]-[/]
└─$

Kubernetes QoS的工作特点

Pod的CPU Requests无法得到满足(比如节点的系统级任务占用过多的CPU导致无法分配足够的CPU给容器使用)时,容器得到的CPU会被压缩限流。

由于内存是不可压缩的资源,所以针对内存资源紧缺的情况,会按照以下逻辑进行处理。

  • BestEffort Pod的优先级最低,在这类Pod中运行的进程会在系统内存紧缺时被第一优先杀掉。当然,从另外一个角度来看,BestEffort Pod由于没有设置资源Limits,所以在资源充足时,它们可以充分使用所有的闲置资源。
  • Burstable Pod的优先级居中,这类Pod初始时会分配较少的可靠资源,但可以按需申请更多的资源。当然,如果整个系统内存紧缺,又没有BestEffort容器可以被杀掉以释放资源,那么这类Pod中的进程可能会被杀掉。
  • Guaranteed Pod的优先级最高,而且一般情况下这类Pod只要不超过其资源Limits的限制就不会被杀掉。当然,如果整个系统内存紧缺,又没有其他更低优先级的容器可以被杀掉以释放资源,那么这类Pod中的进程也可能会被杀掉。

内存不够 触发 OOM 会被 Cgroup 的 OOM Killer 杀掉,K8s 的打分机制是独立于节点级别的打分机制的,不同 Qos 级别的 OOM 打分规则也不同,考虑版本问题,这里不多介绍,感兴趣小伙可以下去了解下。

博文参考


《Kubernetes 权威指南 第四版 》

《SRE Google 运维解密》

https://info.support.huawei.com/info-finder/encyclopedia/zh/QoS.html

https://kubernetes.io/zh-cn/docs/tasks/configure-pod-container/quality-service-pod/

相关内容

热门资讯

小说《异世灵武天下》全集 小说《异世灵武天下》全集到思路客 更新到三千一百六十七章
湖心亭看雪怎么预习? 湖心亭看雪怎么预习?湖心亭看雪 这篇文章怎么预习希望要快!!!~~~(*^__^*) 嘻嘻……试着翻...
九州缥缈录 Ⅱ苍云古齿 Ⅲ天下... 九州缥缈录 Ⅱ苍云古齿 Ⅲ天下名将 Ⅳ辰月之征有声电子版,不要广播剧版的最快回答那个是对的,太大了传...
《射雕英雄传》中第九回所记的岳... 《射雕英雄传》中第九回所记的岳飞所作的四首词的内容是什么。这四首词分别是《菩萨蛮》、《丑奴儿》、《贺...
网恋让我很痛苦我该怎么办 网恋让我很痛苦我该怎么办其实现实与网络有很大的差别,有些比较喜欢现实一点,有些人则喜欢比较理想化一点...
对于男人来说,爱与性,哪个更重... 对于男人来说,爱与性,哪个更重要?对于男人来说,性肯定比爱重要。性更重要,没事无聊的时候这个可以解决...
老舍的文章有什么风格 老舍的文章有什么风格具有独特的幽默风格和浓郁的民族色彩,以及从内容到形式的雅俗共赏浓郁的地方色彩,生...
和“蓄势待发”意思相近的成语有... 和“蓄势待发”意思相近的成语有哪些? 整装待发;万事俱备只欠东风;箭在弦上不得不发;蓄势待发 发音 ...
梦到老头给自己看病 梦到老头给自己看病梦到老头给自己看病... 梦到老头给自己看病 展开 吉凶指数:96梦见一,新...
只相信自己的儿子。告诉我们一个... 只相信自己的儿子。告诉我们一个什么道理? 告诉我们可能我们只对自己比较亲近的人才会放心,才会对他...
实现了心中真正的渴望,才算到过... 实现了心中真正的渴望,才算到过了天堂 』出处?不算,有些事是难免的
和邪王盛宠·医妃遮天差不多的小... 和邪王盛宠·医妃遮天差不多的小说《帝凰.神医弃妃》《病王绝宠毒妃》最爱这两本,
璁緓鈭圧+涓撺虏+y虏/2=1... 璁緓鈭圧+涓撺虏+y虏/2=1,姹倄鈭你们应该学过求导吧,令x√1+y²=a,平方得x²(1+y²)...
七龙珠邪恶龙篇是什么啊? 七龙珠邪恶龙篇是什么啊?新龙珠GT-超级撒亚人4
白水杜康的“黄河清香”战略 执笔 | 文 清 编辑 | 骆 言 在黄河的奔流声中,一场关于白酒产业的革命正悄然兴起。 7月5日...
和美“香遇”德国,五粮液与世界... 面对全球化浪潮,中国白酒品牌出海,既是酒企创新开拓的战略选择,也是酒类产区融入世界烈酒产业生态的重要...
一颗大豆的 43 年突围:永和... 从1982 年在宝岛台湾成立公司,到1995 年怀揣着 “中国风、台湾味、两岸情”的初心,永和豆浆跨...
原创 去... #《令人难忘的姐夫家丸子,制作方法大揭秘》 作为一名热爱美食、热衷于探索各种美味的“生活记录者”,...
江西风味糖醋荷包蛋,酸甜适中超... 江西糖醋荷包蛋是一道家常又下饭的菜,酸甜开胃,蛋香浓郁,做法简单,适合忙碌的日常。它的味道有点像糖醋...
当企业定制蛋糕成为传递温度的“... 在竞争激烈的商业世界中,企业形象塑造早已不局限于硬性指标。当95后、00后成为职场主力军,如何通过有...