目录
一、QoS原理与使用
1、QoS原理
2、资源类型
1. CPU
2. Memory
3、可压缩与不可压缩资源
4、节点资源
5、定义Pod的资源使用
6、Kubernetes Pod Qos 分类
7、QoS等级为 Guaranteed
8、QoS等级为Burstable
9、QoS等级为 BestEffort
10、超出容器的内存限制
11、超出节点可用资源
1. Kubernetes 集群中运行大量的容器,
如果容器数量过多,负载过大时,会陷入无资源可用的情况。
因此需要一定的机制来确保重要的容器拥有足够的资源,甚至不惜杀死一部分容器。
2. 服务质量(QoS)就是这样一种机制 ,
它用于确定哪些容器可以使用多少资源,哪些容器的优先级又比较高
一个单位的CPU资源都会被标准化为一个标准的 “Kubernetes Compute Unit”,
大致和x86处理器的一个单个超线程核心是相同的CPU
CPU资源的基本单位是millicores(千分之一核),
因为CPU资源其实准确来讲,指的是CPU时间所以它的基本单位是millicores
1个核等于 1000 millicores
内存的限制和请求以字节为单位。可以用T、G、M、K等形式表示,也可用Ti、Gi、Mi、Ki等形式表示。
如100M内存,表示100*1000*1000字节内存,
而100Mi表示100*1024*1024字节内存
Kubernetes 中资源可以分为两类,可压缩资源和不可压缩资源
①. CPU 是可压缩资源,
如果CPU不足了,可以通过减少分配给现有业务的时间分片来腾出一部分资源,
也许现有业务会变慢,但仍然能运行。
能做到这个也取决于CPU无状态的特点
②. 内存和硬盘之类的资源是不可压缩资源,
一旦一块内存或硬盘空间分配给了现有业务,
除非Pod结束了使命,否则这些资源不能被释放给其它Pod。
不可压缩资源的使用一旦超限,就意味着有Pod将被停止
1. 使用kubectl get node k8s-worker1 -o yaml 命令,可以查看节点k8s-worker1的详细情况。
allocatable 字段指这台机器可以被容器所使用的资源量
Capacity 字段表示这台 node 的资源真实量
2. 我们主要关注其中的cpu 和内存资源,可以看到,
使用的节点上有4个cpu(其实是线程)和大约4G的内存
allocatable: cpu: "4" ephemeral-storage: "35975901944" hugepages-1Gi: "0" hugepages-2Mi: "0" memory: 3880784Ki pods: "110" capacity: cpu: "4" ephemeral-storage: 39036352Ki hugepages-1Gi: "0" hugepages-2Mi: "0" memory: 3983184Ki pods: "110"
Kubernetes 中 pod 对资源的申请是以容器为最小单位进行的,针对每个容器,它都可以通过如下两个信息指定它所希望的资源量:
①. request
request指针对这种资源,这个容器希望能够保证获取到的最少的量。
只有节点上的富余资源大于request值时,容器才会被调度到该节点
②. limit
limit对于CPU,还有内存,指的是容器对这个资源使用的上限
对CPU来说,容器使用CPU过多,内核调度器就会切换,使其使用的量不会超过limit。
对内存来说,容器使用内存超过limit,容器就会被OOM kill掉,从而发生容器的重启
1. kubernetes 支持用户容器通过 request、limit 两个字段指定自己的申请资源信息。
那么根据容器指定资源的不同情况,Pod也被划分为3种不同的QoS级别。分别为:
Guaranteed 保证(两个都限定了,值的限制和需求相等)
Burstable 爆发(限制其中一个,至少有CPU或内存)
BestEffort 尽力(都不限制)
2. 优先级 Guaranteed > Burstable > Best-Effort
参考资料: 配置 Pod 的服务质量 | Kubernetes
1. 想要给 Pod 分配 QoS等级为 Guaranteed:
①. Pod里的每个容器都必须有内存限制和请求,而且必须是一样的
②. Pod里的每个容器都必须有CPU限制和请求,而且必须是一样的
2. Guaranteed level 的 Pod是优先级最高的,系统管理员一般对这类 Pod 的资源占用量比较明确
3. 案例
$ kubectl apply -f- <
$ kubectl get pods qos-demo NAME READY STATUS RESTARTS AGE qos-demo 1/1 Running 0 25s $ kubectl get pods qos-demo -o yaml | grep qosC qosClass: Guaranteed #服务质量类型为Guaranteed
1. 当出现下面的情况时,则是一个 Pod 被分配了QoS等级为Burstable:
①. 该 Pod 不满足 QoS等级 Guaranteed 的要求
②. Pod 里至少有一个容器有内存或者CPU 请求
2. Burstable level 的Pod 优先级其次,管理员一般知道这个 Pod的资源需求的最小量,但是当机器资源充足的时候,还是希望他们能够使用更多的资源,所以一般 limit > request
3. 案例
$ kubectl apply -f- <
$ kubectl get pod qos-demo-2 -o yaml | grep qosC qosClass: Burstable #服务质量为Burstable
1. Pod里的容器 必须没有任何内存或者CPU的限制或请求
2. BestEffor level 的 Pod 优先级最低。
当机器资源充足的时候,它可以充分使用,但是当机器资源被Guaranteed、Burstable的Pod所抢占的时候,它的资源也会被剥夺,被无限压缩
3. 案例
$ kubectl apply -f- <
$ kubectl get pod qos-demo-3 -o yaml | grep qosC qosClass: BestEffort #服务质量为BestEffort
1. 使用polinux/stress 容器测试Kubernetes 在容器运行时资源使用超过限制值时的表现。
容器的内存限额是100Mi
但运行时实际使用150M
$ kubectl apply -f- <
2. 查看Pod的状态:已被OMMKilled
$ kubectl get pod memory-demo NAME READY STATUS RESTARTS AGE memory-demo 0/1 `OOMKilled` 0 20s $ kubectl describe pod memory-demo | grep -A 2 Last Last State: Terminated Reason: OOMKilled Exit Code: 1
3. 参考资料: 为容器和 Pod 分配内存资源 | Kubernetes
1. 申请Guaranteed 类型的Pod,内存1000G。
由于节点并没有如此大量的资源,因此Pod会处于Pending状态
kubectl apply -f- <
2. 从该Pod的详细信息可用看到:
$ kubectl get pods memory-demo2 NAME READY STATUS RESTARTS AGE memory-demo2 0/1 Pending 0 91s $ kubectl describe pod memory-demo2 | tail -n 1 Warning FailedScheduling 3m6s default-scheduler 0/3 nodes are available: 1 node(s) had untolerated taint {node-role.kubernetes.io/master: }, 3 Insufficient memory. preemption: 0/3 nodes are available: 1 Preemption is not helpful for scheduling, 2 No preemption victims found for incoming pod.