kubernetes的调度 资源管理(QoS, Pod亲和度, 资源优先级)
kubernetes的调度过程
kubernetes的调度过程简单而言,就是将颇多创建并调度到合适的node节点上去。
1. 首先是一个Yaml的文件
如图所示,和之前提到的是一样的,我们先讲整个的k8s集群的图表示出来,上方是master节点,下面是nobe的节点。master的节点主要是有api-server,controller 和 scheduler三个部分。
当我们给定一个Yaml 文件时,它以最小单位 Pod 发送给 api-server 访问端口。
2. API-server 把 pod 申请传递给 controllers
API-server会把pod的创建请求发送给controllers,让controller审核
3. 审核通过以后,再交付给 API-server
生成pod以后,此时的 pod 的node name是空的,状态时pending,也就是说,虽然生成了,但是还没有被分配到合适的node节点上。
4. 将 pod 文件发送到 scheduler 调度
scheduler根据一系列算法,包括资源的容纳量,亲和度等因素,给pod文件分配 node 节点消息。
5. 调度器找到合适节点,返回到 API-server上,并更新 pod 状态
此时的 pod 的状态没变,仍然在等候之中,但它的node信息已被更新。
6. 节点上的kubelet感应到pod,将其拉到自己的node上部署
给 pod 配置资源,更新状态为 running
资源调动
正如前面所说,kubernetes的调度过程就是将合适的pod调度到合适的node节点上去,那如何调度他们,如何配置资源,主要可以从三个角度来讲。
从 Pod 角度来讲
要满足pod对于资源的需求
要满足pod的特殊关系需求
从 node 的角度讲
要满足 node 的限制条件
从集群整体资源来看
要满足集群资源的合理利用
所以接下来,主要围绕这些来展开。
资源调度 - 满足pod的资源需求
要想了解资源调度,首先要先明晰有哪些资源,可调用的资源类型是什么。
CPU 处理器
memory 内存
Storage 临时存储
extended-resource 扩展资源(类似于GPU等)
我们可以看一个例子,看一个 pod 对这些资源的调动和需求:
在如图所示的demo中,对于 resources 的资源列表里,有两个模块,写着对于 CPU 和 memory 的需求,其中,
requests 是对于pod能运行的最低资源需求
limit 是对 pod 使用资源的上限限制
Pod QoS
QoS 是 Quality of Service 的简称,QoS 有三种级别:
Guaranteed
高 必须保障
Burstable
中 弹性需求
BestEffort
低 尽力而为、
事实上,Pod 中并没有直接对于 QoS 的规定,而是利用资源下限和资源上限的阈值(requests 和 limit )来给定不同级别,
我们可以先看第一类
Guaranteed
requests 和 limit 相等,直接将资源给定并限制。
Burstable
此时requests 和 limits 不等,可以再一定弹性限度中自由调配资源。
BestEffort
此时request和limits都不给定,只有有空闲资源的时候才会分配。
不同 QoS 的表现
-
调度不表现不同
调度器会根据 requests 来进行调整 -
底层表现的不同
CPU: 按照 requests 的不同来划分权重。
Guaranteed整数会绑核,假设有Guaranteed pod 需要两个cpu,则其余的pod(包括Guaranteed非整数的以及其他级别的)将使用一个 CPUshare pool,如图:
memory: 按照 QoS 来划分 OOMscore
OOM 是Linux内核分配资源的一种手段,OOM 的全称是 over-commit memory,是当应用程序没有使用完自己的内存的时候,将自己内存移作他用,但如果所有应用程序都用完了自己的内存,OOM killer将杀掉一些进程, OOMscore就是衡量这些进程的一个评判标准,如下:
Guaranteed
-998
Burstable
2-999
BestEffort
1000(最容易被杀死)
Eviction
优先BestEffort
kubelet -CPU Manager
资源Quota
限制每个namespace资源用量,具体 demo 如下:
关系调度
Pod 亲和调度 PodAffinity
- 必须和某些 pod 放在一起
requiredDuringSchedulingIgnoredDuringExectuion
比如必须调度到带有 k1 = v1 标签的 pod 所在的节点上:
- 优先调度到某些pod所在的节点上
perferingDuringSchedulingIgnoredDuringExectuion
反亲和调度同上 PodAntiAffinity
node 亲和调度 NodeAffinity
在NodeSelector中设置
- 必须调度到某种标签的node上
requiredDuringSchedulingIgnoredDuringExectuion
2. 优先调度到某些Node上
perferingDuringSchedulingIgnoredDuringExectuion
Node Taints 和 Pod tolerations 限制调度
类似于反亲和调度,限制某些 pod 部署上来
高级调度
以上所有的是基于单个的 pod 或 node 节点进行的一些基础调度,但如果集群资源不够用的时候怎么办,主要有两种:
FIFO
优先级策略
优先级 Priority
- 优先级调度配置
创建PriorityClass,为其设定不同的得分,配置不同的PriorityClassName,如下图: - 优先级调度(未开启抢占)
有两个 pod 在调度序列中,优先级较大的会先行被调度,然后优先级较小的 pod 被调度,具体流程如图:
抢占 preemption
假设 node 中已经部署了一个优先级较大的 pod 0,剩余资源不足以让两个 pod 进去,此时 pod 2 先进行调度,pod 1 后调度。
经过抢占算法, pod 1 抢占成功,则 pod 2 为让渡者,则驱逐 node 节点上 pod 2,将 pod 1 调度到 node 1 上,具体流程如图: