QOS
Qos
(Quality of Service),k8s
会根据Pod
容器中指定的资源约束为每个Pod
设置QoS
类。k8s
依赖这种分类来决定当Node
上没有足够可用资源时要驱逐哪些 Pod
。
QoS
类k8s
对你运行的 Pod
进行分类,并将每个 Pod
分配到特定的 QoS
类中。 k8s
使用这种分类来影响不同 Pod
被处理的方式。k8s
基于 Pod
中容器的资源请求进行分类, 同时确定这些请求如何与资源限制相关。 这称为服务质量 (QoS) 类。 k8s
基于每个 Pod 中容器的资源请求和限制为 Pod
设置 QoS
。k8s
使用 QoS
类来决定从遇到节点压力的 Node
中驱逐哪些 Pod
。可选的 QoS
类有 Guaranteed
、Burstable
和 BestEffort
。 当一个 Node
耗尽资源时,k8s
将首先驱逐在该 Node
上运行的 BestEffort Pod
, 然后是 Burstable Pod
,最后是 Guaranteed Pod
。当这种驱逐是由于资源压力时, 只有超出资源请求的 Pod
才是被驱逐的候选对象。
Guaranteed
Guaranteed Pod
具有最严格的资源限制,并且最不可能面临驱逐。 在这些 Pod
超过其自身的限制或者没有可以从 Node
抢占的低优先级 Pod
之前, 这些 Pod
保证不会被杀死。这些 Pod
不可以获得超出其指定 limit
的资源。这些 Pod
也可以使用 static CPU
管理策略来使用独占的 CPU
。
Pod
被赋予 Guaranteed QoS
类的几个依据:
Pod
中的每个容器必须有内存limit
和内存request
。- 对于
Pod
中的每个容器,内存limit
必须等于内存request
。 Pod
中的每个容器必须有CPU limit
和CPU request
。- 对于
Pod
中的每个容器,CPU limit
必须等于CPU request
。
Burstable
Burstable Pod
有一些基于 request
的资源下限保证,但不需要特定的 limit
。 如果未指定 limit
,则默认为其 limit
等于 Node
容量,这允许 Pod
在资源可用时灵活地增加其资源。 在由于 Node
资源压力导致 Pod
被驱逐的情况下,只有在所有 BestEffort Pod
被驱逐后 这些 Pod
才会被驱逐。因为 Burstable Pod
可以包括没有资源 limit
或资源 request
的容器, 所以 Burstable Pod
可以尝试使用任意数量的节点资源。
Pod
被赋予 Burstable QoS
类的几个依据:
Pod
不满足针对 QoS 类Guaranteed
的判据。Pod
中至少一个容器有内存或CPU
的request
或limit
。
BestEffort
BestEffort QoS
类中的 Pod
可以使用未专门分配给其他 QoS
类中的 Pod
的节点资源。 例如若你有一个节点有 16 核 CPU 可供 kubelet 使用,并且你将 4 核 CPU 分配给一个 Guaranteed Pod
, 那么 BestEffort QoS
类中的 Pod
可以尝试任意使用剩余的 12 核 CPU。
如果节点遇到资源压力,kubelet 将优先驱逐 BestEffort Pod
。
如果 Pod 不满足 Guaranteed
或 Burstable
的判据,则它的 QoS
类为 BestEffort
。 换言之,只有当 Pod
中的所有容器没有内存 limit
或内存 request
,也没有 CPU limit
或 CPU request
时,Pod
才是 BestEffort
。Pod
中的容器可以请求(除 CPU 或内存之外的) 其他资源并且仍然被归类为 BestEffort
。
以上来自k8s文档
Qos与cgroup的关系
创建不同Qos的pod
使用下面的yaml
文件创建对应的`pod1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37apiVersion: v1
kind: Pod
metadata:
name: guaranteed
spec:
containers:
- name: app
image: hysyeah/my-curl:v1
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "64Mi"
cpu: "250m"
--
apiVersion: v1
kind: Pod
metadata:
name: burstable
spec:
containers:
- name: app
image: hysyeah/my-curl:v1
resources:
requests:
memory: "64Mi"
cpu: "250m"
apiVersion: v1
kind: Pod
metadata:
name: besteffort
spec:
containers:
- name: app
image: hysyeah/my-curl:v1
当我们apply
这个yaml
文件后,Pod
会被调度到对应的Node
,kubelet
会将PodSpec
中的内容传递给CRI
,CRI
再将这此内容翻译成
更底层的OCI JSON Spec描述容器创建的信息。
crictl inspect <containerID>
查看对应的资源信息1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21// 0e5962a09e2d3的部分内容
// 包括了资源的限制信息及cgroupsPath
"linux": {
"resources": {
"devices": [
{
"allow": false,
"access": "rwm"
}
],
"memory": {
"limit": 67108864 // 64M
},
"cpu": {
"shares": 256,
"quota": 25000,
"period": 100000
}
},
"cgroupsPath": "/kubepods/pod21ef5ccc-a09d-4754-aa1e-a65820d572cc/0e5962a09e2d3840e4f6ae1a3750136ad578c3df026a8dd64b175f8e33570823",
}
创建完成后你可以查看对应pod
的Qos
。k describe pod <pod-name>
查看系统中的cgroups
节点系统信息
1
2
3
4
5
6
7
8✗ uname -a
Linux hysyeah 5.15.0-72-generic #79~20.04.1-Ubuntu SMP Thu Apr 20 22:12:07 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
cgroups版本
对于 cgroup v2,输出为 cgroup2fs
对于 cgroup v1,输出为 tmpfs
➜ stat -fc %T /sys/fs/cgroup/
tmpfs查看容器相关信息
crictl ps
,对应的PodID
和ContainerID
下面我们会使用到cgroups
的目录为/sys/fs/cgroup
,我们只关注cpu
和memory
。1
2➜ cgroup ls
blkio cpu cpuacct cpu,cpuacct cpuset devices freezer hugetlb memory misc net_cls net_cls,net_prio net_prio perf_event pids rdma systemd unified
可以看到cpu
和memory
目录下都有一个名为kubepods
的目录,k8s
相关的cgroups
就是放在这个目录下的。
以memory/kubepods
为例:
其中Qos
为burstable
和besteffort
的Pod
的cgroup
信息分别放在目录burstable
,besteffort
下。Qos
为guaranteed
的pod
的cgroup
信息放在
查看burstable
目录下的cgroups
,有两个目录分别是container
和pod
对应的cgroups
posSpec中的resources与cgroup的映射关系
podSpec | cgroup |
---|---|
limits.cpu | cpu.cfs_period_us, cpu.cfs_quota_us, cpu.shares |
limits.memory | memory.limit_in_bytes |
cpu.cfs_period_us
: 表示cfs调度时间周期,默认值为100000us(100ms)cpu.cfs_quota_us
: 表示在一个调度周期内允许执行的时间。-1表示不限制cpu.shares
:表示cpu group对控制组之间的cpu分配比例memory.limit_in_bytes
: 使用的最大内存量cpu.cfs_quota_us/cpu.cfs_period_us
表示这个控制组允许使用的cpu
最大值。
如上我们设置limit.cpu=250m,则cpu.cfs_quota_us=25000,cpu.cfs_period_us=100000。cpu.cfs_quota_us/cpu.cfs_period_us=0.25
,也就是podSpec
中的250m
。
REF:
1.https://kubernetes.io/zh-cn/docs/concepts/workloads/pods/pod-qos/
2.https://docs.kernel.org/admin-guide/cgroup-v1/memory.html