4.4 KiB
Kubernetes调度机制
Kubernetes的资源模型与资源管理
所有跟调度和资源管理相关的属性都是属于 Pod 对象的字段,其中最重要的部分,就是 Pod 的 CPU 和内存配置,如下所示:
apiVersion: v1
kind: Pod
metadata:
name: frontend
spec:
containers:
- name: db
image: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: "password"
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
- name: wp
image: wordpress
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"
在Kubernetes 中:
- CPU称为 “可压缩资源” ,可压缩资源不足时,Pod只会“饥饿”,不会退出
- 内存称为“不可压缩资源”,不可压缩资源不足时,Pod会因为OOM(Out-Of-Memory)被内核杀掉
- Pod 可以由多个 Container 组成,所以 CPU 和内存资源的限额,是要配置在每个 Container 的定义上的,而Pod整体资源配置,就由这些 Container 的配置值累加得到
limits 和 requests 的区别很简单:在调度的时候,kube-scheduler 只会按照 requests 的值进行计算。而在真正设置 Cgroups 限制的时候,kubelet 则会按照 limits 的值来进行设置。
requests+limits 的做法,其实是Borg的思想,即,实际场景中,大多数作业使用到的资源其实远小宇它所请求的资源限额,基于这种假设,用户可以声明一个相对小的requests值供调度器使用,而Kubernetes 真正设置给容器 Cgroups 的,则是相对较大的 limits 值。
QoS 模型:
三个级别,衔接上面
- **Guaranteed:**Pod 里的每一个 Container 都同时设置了 requests 和 limits,并且 requests 和 limits 值相等的时候,这个 Pod 就属于 Guaranteed 类别
apiVersion: v1
kind: Pod
metadata:
name: qos-demo
namespace: qos-example
spec:
containers:
- name: qos-demo-ctr
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "700m"
requests:
memory: "200Mi"
cpu: "700m"
- **Burstable:**当 Pod 不满足 Guaranteed 的条件,但至少有一个 Container 设置了 requests。那么这个 Pod 就会被划分到 Burstable 类别
apiVersion: v1
kind: Pod
metadata:
name: qos-demo-2
namespace: qos-example
spec:
containers:
- name: qos-demo-2-ctr
image: nginx
resources:
limits
memory: "200Mi"
requests:
memory: "100Mi"
- **BestEffort:**如果 Pod 既没有设置 requests,也没有设置 limits,那么它的 QoS 类别就是 BestEffort
apiVersion: v1
kind: Pod
metadata:
name: qos-demo-3
namespace: qos-example
spec:
containers:
- name: qos-demo-3-ctr
image: nginx
**QoS 划分的主要应用场景,是当宿主机资源紧张的时候,kubelet 对 Pod 进行 Eviction(即资源回收)时需要用到的。**当Eviction发生时,kubelet 具体会挑 Pod 进行删除操作,按如下级别:
BestEffort < Burstable < Guaranteed
并且,Kubernetes 会保证只有当 Guaranteed 类别的 Pod 的资源使用量超过了其 limits 的限制,或者宿主机本身正处于 Memory Pressure 状态时,Guaranteed 的 Pod 才可能被选中进行 Eviction 操作。
cpuset 的设置
一个实际生产中非常有用的特性,衔接上面
在使用容器时,可以通过设置 cpuset 把容器绑定到某个 CPU 的核上,而不是像 cpushare 那样共享 CPU 的计算能力,这样CPU之间进行上下文切换的次数大大减少,容器里应用的性能会得到大幅提升
实现方法:
- Pod 必须是 Guaranteed 的 QoS 类型
- 将 Pod 的 CPU 资源的 requests 和 limits 设置为同一个相等的整数值
如下例子:
spec:
containers:
- name: nginx
image: nginx
resources:
limits:
memory: "200Mi"
cpu: "2"
requests:
memory: "200Mi"
cpu: "2"
这样,该Pod就会绑定在2个独占的CPU核上,具体是哪两个CPU,由kubelet 分配
基于上面的情况,建议将DaemonSet(亦或者类似的)的 Pod 都设置为 Guaranteed 的 QoS 类型,否则一旦被资源紧张被回收,又立即会在宿主机上重建出来,这样资源回收的动作就没有意义了