Koordinator 0.6:企业级容器调度系统解决方案,引入 CPU 精细编排、资源预留与全新的重调度框架
作者: 李涛、曾凡松
阿里云原生开源的混部体系 Koordinator 依据阿里超大规模混部出产实践经验而来,旨在为用户打造云原生场景下接入本钱最低、混部功率最佳的处理计划,助力用户企业完成云原生后提高核算资源利用率、降低 IT 本钱。
经过社区多位成员的奉献,Koordinator 0.6 版别正式发布。相较于上一个版别 0.5 [ 1] ,新版别进一步完善了 CPU 精细化编列才干,更好的兼容原生用法;支撑了资源预留的才干(Reservation),补齐了调度原子语意缺失;发布了全新的重调度结构,支撑用户灵敏的扩展自界说插件。这些特性源自于阿里巴巴内部的出产实践,并结合上游社区规划思考,为用户带来规范、强大、灵敏的调度处理计划。
现代化调度体系的应战
多云、混合云成为事务常态,调度体系有必要适应多样化基础设施
跟着国内外云厂商的不断发展,到 2022 年,大多数企业基础设施将围绕云核算环境构建,企业基础设施以云核算为主,以自建为辅。云核算按需的算力调配特性协助企业完成通用、灵敏、弹性的核算需求,自建部分满意企业传统运用架构过度、定制化或许安全合规诉求。
在企业运用云时,最大的顾虑是运用了厂商确定的技能,因而多云架构是近年企业要点重视的范畴,在多云环境中,不同云厂商的硬件可能存在不同程度的定制差异。调度体系怎么适配多云场景下异构的算力设备,处理好异构资源调度、拓扑感知、运转时 QoS 确保,让用户在不同环境获得一致的体会,是一个很大的应战。
为了协助企业便利地办理云上、线下的算力,也会发展出混合云这样的产品架构,这其间可能呈现一个集群中即包括云上又包括线下的核算节点,基础环境比较杂乱。调度体系怎么适配云上、线下环境,处理好不同环境对资源容量办理、任务编列、存储网络调度的诉求,一同支撑用户在线下场景可以低本钱的扩展自界说特性,让用户在一套调度体系上编列云上、线下的容器资源,是第二大应战。
多种作业负载的混部成为常态,对调度体系才干的要求愈加全面立体
Kubernetes 容器调度编列体系,协助用户在一个节点上运转多个容器,也就供给了将不同事务的容器一同运转到一个节点的可能。也就是说,Kubernetes 天然地就支撑了 “混部”。
跟着企业容器化上云的进程加快,越来越多的运用类型经过 Kubernetes 布置到云基础设施之上。当企业的运用越来越多,为每一种类型的运用独自规划集群,在运维本钱和资源本钱大将不再可行。企业办理不同事务类型的方法逐渐从切分集群到同享集群,从切分节点池到同享节点池这样的方法演进。
不同事务类型的作业负载,对调度体系都有不同的特性需求,调度体系如安在同一个集群、同一个节点上编列不同类型的作业负载,处理好它们各自的运转功率安稳性、对 Kubernetes 管控面性能和节点运转时安稳性的诉求,是现代化调度体系的一个重要课题。
本钱功率成为企业重视的要点方向,调度体系是其间的要害一环
2020 年开始,受全球疫情的影响,企业的出产经营活动或多、或少的受到打击。有 65% 的企业开始考虑经过上云的方法降低企业 IT 信息化本钱,已经上云的企业开始经过更深度的优化来降低 IT 资源本钱。在本钱治理范畴,FinOps 的理念逐渐被企业所接受,在 2021 年 CNCF《FinOps Kubernetes Report》的调研陈述显示,搬迁至 Kubernetes 途径后,68% 的受访者表明所在企业核算资源本钱有所增加,36% 的受访者表明本钱飙升超过 20%。
这一调研成果与大型企业的运用实践天壤之别,Google、微软、Alibaba 等国内外企业已经经过实践证明了企业容器化在本钱上的巨大经济价值。这其间最要害的差别在于大型企业界部通常建造有完备的本钱洞悉才干,知道本钱开支在哪里,一同建造了完备而强大的调度体系,让企业的资源充分的被利用起来。在这其间,调度体系怎么处理好企业界部门间的 Quota 办理、资源借用,处理好上层弹性弹性场景与底层节点池弹性弹性之间的配合,合理的规划底层机型降低资源闲置率,是现代化云原生调度体系有必要要处理的问题。
Koordinator 的解法和途径
打造下一代容器调度体系,咱们这么做:
拥抱上游规范,打造依据 QoS 的闭环调度体系
在学术界,集群资源调度体系的架构规划是一个老话题了,从集中式到分布式,从两层调度到同享状况架构,从失望锁到乐观锁。在工业界前史上,每一种架构都或多或少的有过成功的案例,也正印证了那句话“架构规划没有对错,只有适宜不适宜”。在 Kubernetes 成为简单编列的事实规范之后,在 Kubernetes 之上依然衍生出了多种的调度器规划,他们或是擅长处理某一垂直范畴的问题,或是采用了不同的规划完成,在各自的场景中完成了价值。
打造现代化的云原生调度体系,Koordinator 坚持了如下的规划思路:
-
拥抱 Kubernetes 上游规范,依据 Scheduler-Framework 来构建调度才干,而不是完成一个全新的调度器。构建规范构成共识是困难的,但损坏是简单的,Koordinator 社区与 Kubernetes sig-scheduling 社区相向而行。
-
QoS 是体系的一等公民,与业界大多数调度器更多的重视编列成果(静态)不同,Koordinator 十分重视 Pod 运转时质量(QoS),由于关于调度体系的用户而言,运转时安稳性是其事务成功的要害。
-
状况自闭环,Koordinator 以为调度有必要是一个完好的闭环体系,才干满意企业级运用要求。因而,咱们在第一个版别就引入了状况反馈回路,节点会依据运转时状况调优容器资源,中心会依据节点运转时状况反馈做调度决议计划。
-
智能化、简略化,Koordinator 并不是就所有的挑选露出把问题留给客户,而是依据运用特征智能的为用户供给优化装备主张,简化用户运用 Kubernetes 的本钱。
建造才干强大、灵敏且可插拔的精细化资源编列优化计划
今日,服务器的 CPU 有 Intel、AMD、多家供货商的 ARM 芯片,AI 场景广泛运用的 GPU、FPGA 等,Kubernetes 作为容器编列基础设施,承载着异构硬件的办理作业,如安在规范 Kubernetes 之上供给异构硬件的调度编列,一同支撑用户多样、灵敏的战略控制,Koordinator 遵从了如下的规划思路:
-
兼容 Kubernetes,Kubernetes 为用户供给了 static policy cpu manager,Koordinator 的 CPU 拓扑感知可以在用户启用 static policy 时兼容运转,也支撑接管用户存量的运转时 Pod,便利用户做技能晋级。
-
中心调度 + 单机调度联合决议计划,中心调度看到全局视角,其决议计划可以找到集群中最适宜运用需求的节点,而单机调度可以在节点侧做一定的灵敏度,以应对运用突发的流量颠簸。
-
调度 + 重调度密切配合,调度处理 Pod 一次性放置的问题,而重调度才是驱动集群资源编列长期保持最优化的要害。Koordinator 将建造面向 SLO 的重调度才干,继续的驱动运用的编列契合预界说的 SLO。
打造开箱即用的混部和作业负载弹性处理计划
混部是处理 Kubernetes 集群资源利用率的终极武器,这一点在国内外大型企业中都得到了实践论证,但也只是限于这个小圈子之中。近年跟着国内外厂商的宣传以及要害信息在学术界论文透出,数字化路上的企业特别是云原生化的企业,对混部都有或多或少的了解。但面对混部,用户的心声是有没有一套开箱即用的处理计划,协助用户优化 Kubernetes 集群的资源本钱功率。
企业接入混部最大的应战是怎么让运用跑在混部途径之上,这第一步的门槛往往是最大的绊脚石。Koordinator 针对这一问题,结合内部出产实践经验,规划了“双零侵入”的混部调度体系:
1. 对 Kubernetes 途径的零侵入。 行业界的人大多知道,将 Kubernetes 运用于企业界部的杂乱场景混部时,由于这样或许那样的原因总是需求对 Kubernetes 做一定量的修正,这些修正将导致用户运用混部时呈现厂商确定的危险。而 Koordinator 混部体系,规划之处即确保了不需求对社区原生 Kubernetes 做任何修正,只需求一键安装 Koordinator 组件到集群中,既可以为 Kubernetes 集群带来混部的才干。
2. 对作业负载编列体系的零侵入。 想像一下,在企业界部的 Kubernetes 集群之上供给混部才干之后,将面对的问题是怎么将企业的作业负载接入进来,以混部的方法运转。对作业负载办理逻辑的侵入,乐观是需求付出额定的适配本钱,失望时是这些改动是在云厂商供给的组件内(比方 kcm),将面对厂商确定或许供货商不支撑的危险。
Koordinator 针对运用接入层的改造本钱,规划了独自的作业负载接入层,协助用户处理作业负载接入混部的难题,用户只需求办理混部的装备即可灵敏的调度编列哪些任务以混部的方法运转在集群中,十分的简略且灵敏。
构建作业负载数据剖析体系,供给智能的优化主张
调度体系不止于处理调度、重调度、弹性弹性等范畴问题,一个完好的调度体系,需求具有依据前史数据驱动的自我迭代演进的才干。为作业负载的运转前史状况树立数据仓库,依据这些运转前史的大数据剖析,继续的改善运用间在各个维度的的亲和、互斥关系,才干在用户运转时体会、集群资源利用功率一同到达最佳状况。
Koordinator 针对智能化调度的规划思路如下:
- 智能资源超卖,Koordinator 首先处理的是节点资源充分利用的问题,经过剖析节点容器的运转状况核算可超卖的资源量,并结合 QoS 的差异化诉求将超卖的资源分配给不同类型的任务,大幅提高集群的资源利用率。
-
QoS 感知的重调度,当节点中 Pod 的运转时 QoS 不契合预期时,Koordinator 将智能决议计划抑制更低优先级的任务亦或是搬迁当时收到搅扰的容器,然后处理运用 QoS 不满意导致的问题。
-
更多的才干敬请期待,未来这里将是 Koordinator 要点迭代的范畴。
围绕着这条路,在 0.6 版别中,社区带来了下述更新。
版别功用特性解读
Koordinator 近期发布了 v0.6 版别,包括了以下增强、新增特性:
-
新版别进一步完善了 CPU 精细化编列才干,更好的兼容原生用法。
-
在 Kubernetes 之上引入资源预留的原子才干(Reservation),资源预留在容量办理、碎片优化、调度成功率优化等方面有重要作用。
-
供给了 Pod 腾挪的才干(PodMigrationJob),可以协助用户牢靠地搬迁有问题实例、收拾集群资源碎片等。
-
发布了全新的 Descheduler Framework,支撑用户灵敏的扩展自界说插件,结合 PodMigrationJob 完成安全、牢靠、灵敏的重调度。
-
此外,该版别包括了 GPU、Gang、Elastic Quota 相关的规划。
愈加完善的 CPU 精细化编列 – Fine-grainedCPU Orchestration
跟着资源利用率的提高进入到混部的深水区,需求对资源运转时的性能做更深入的调优,更精细的资源编列可以更好的确保运转时质量,然后经过混部将利用率面向更高的水平。
咱们把 Koordinator QoS 在线运用 LS 类型做了更细致的划分,分为 LSE、LSR 和 LS 三种类型。拆分后的 QoS 类型具有更高的阻隔性和运转时质量,经过这样的拆分,整个 Koordinator QoS 语义愈加准确和完好,而且兼容 K8s 已有的 QoS 语义。而且咱们针对 Koordinator QoS,规划了一套丰厚灵敏的 CPU 编列战略,如下表所示:
咱们可以结合下图,可以更简单了解这一套 QoS 和编列战略:
在之前的《云原生混部体系 Koordinator 架构详解》中,咱们向咱们介绍过当时正在完成CPU 精细化编列计划 [ 2] 规划,并在 Koordinator v0.5 版别中,完成了根本的 CPU 精细化编列才干,用户可以在 Pod 中新增 Koordinator CPU 精细化编列协议,指定期望的 CPU 编列战略辅导 koord-scheduler 在调度时挑选最适宜的节点。koord-scheduler 在分配时优先考虑 NUMA 架构,使得分配的 CPU 尽可能不跨 NUMA Node/Socket,而且为了尽可能防止 NUMA Node/Socket 维度发生碎片,默许运用 MostAllocated 战略挑选剩下 CPU 少的 NUMA Node。
在 Koordinator v0.6 中,进一步完善了 CPU 精细化编列才干,更好的支撑了延迟灵敏型运用关于搅扰阻隔的需求以及更好的兼容原生用法:
-
当 Koordinator QoS 为 LSE/LSR 类型的 Pod 没有设置 CPU 精细化编列协议时,koord-scheduler 运用装备的默许 CPU 编列战略分配 CPU。
-
新增支撑PCPULevel或许 NUMANodeLevel 两种 CPU 互斥战略(CPU Exclusive Policy)。koord-scheduler 会依据用户的装备,尽量的确保具有相同互斥战略的 Pod 在物理核维度(PCPULevel)或许 NUMA Node 维度(NUMANodeLevel)互斥。该机制可以有效的防止 CPU 密集型运用的相互搅扰。
-
支撑 Node CPU Orchestration API,集群办理员或许集群资源运营可以经过该 API 约束节点的 CPU 编列战略。
-
支撑经过标签 node.koordinator.sh/cpu-bind-policy 约束调度时的 CPU 绑定逻辑。当时支撑的战略 FullPCPUsOnly 表明要求 koord-scheduler 在分配 CPU 时,分配的 CPU 数量有必要分配在相同的一批物理核上,而且在 SMT 架构下(例如常见的 x86 架构) 要求 Pod 的 CPU 请求数量有必要是单个物理核内虚拟逻辑核的倍数。FullPCPUsOnly 与 Kubernetes 支撑的 kubelet CPU Manager Policy Option full-pcpus-only=true 等价。
-
支撑经过标签 node.koordinator.sh/numa-allocate-strategy 指定 NUMA Node 维度的分配挑选战略,假如设置 MostAllocated,期望 koord-scheduler 优先从剩下 CPU 最少的 NUMA Node上分配;假如设置 LeastAllocated,期望 koord-scheduler 优先从剩下 CPU 最多的 NUMA Node 上分配。默许运用 MostAllocated 战略。该装备还会作用在后续将要支撑的 NUMA Topology 调度才干。
- 单机侧 koordlet 增强了对 LSE QoS 的支撑,例如 koordlet 启用 CPU Suppress 机制时,在为 BE Pod 分配 CPU 时会排除掉 LSE Pod 绑定的 CPU,完成 LSE QoS 的强确保。
资源预留-Reservation
在 Koordinator v0.6 中 ,咱们依据原有 v0.5 版别完成的资源预留 API 规划计划 [ 3] ,在不侵入 Kubernetes 已有的机制和代码前提下,完成了资源预留的原子才干(Reservation)。资源预留在容量办理、碎片优化、调度成功率和重调度等场景有重要作用:
-
当有重要的作业负载在未来某段时刻需求资源时,可以提前预留资源满意需求。
-
用户在 PaaS 上建议扩容时,可以经过资源预留才干测验预留,预留成功后建议扩容,确保 PaaS 的 SLA。
-
用户在 PaaS 上发布时,假如运用采用了翻滚发布的才干,可以经过资源预留保存行将毁掉的 Pod 持有的资源,在翻滚发布时,新建的 Pod 可以复用预留下来的原有资源,可以有效提高翻滚发布的成功率。
-
碎片优化场景中,可以经过资源预留占住闲暇的碎片资源,并把可被收拾的 Pod 搬迁到这些节点。
-
重调度时在建议驱赶前,先测验预留资源,预留成功后建议驱赶,防止驱赶后无资源可用影响运用的可用性。
Koordinator Reservation API 答运用户不修正 Pod Spec 或许存量的 Workload(例如 Deployment, StatefulSet)即可以预留资源。根本流程如下:
1.当用户期望预留资源时,可以创立一个 Reservation CRD 实例,经过 ReservationSpec.Template 声明未来新建的 Pod Spec , 并声明预留资源的所有权,即填写 ReservationSpec.Owners 字段。
-
koord-scheduler watch 到新建的 Reservation 后,会依据 ReservationSpec 中的信息模拟为一个 Pod(称为 ReservePod) 进行调度找到适宜的节点,并把调度的成果更新回 ReservationStatus。
-
用户创立新的Pod,koord-scheduler 优先为该 Pod 寻找适宜的 Reservation 实例,koord-scheduler 会依据 Reservation 中记载的资源所有权,经过 label selector 机制或许判别 controller ownerReference 的方法判别新 Pod 是否与 Reservation 匹配,假如匹配,则会进行预处理,确保后续的 Reservation 资源定向给该 Pod 运用。并在打分阶段影响调度逻辑,优先完成 Reservation 方针占用的资源。
-
Pod bind 时更新 ReservationStatus,记载该 Reservation 被哪些 Pod 消费了。
-
当 Pod 毁掉时,koord-scheduler 会更新 ReservationStatus 删除 Pod 消费记载,该 Reservation 会被继续运用直到超过设定的过期时刻(BTW: 默许 24 小时过期,假如 TTL 设置为 0,表明不过期)。
- Quick Start
- 运用下面的 YAML 文件创立 Reservation reservation-demo
apiVersion: scheduling.koordinator.sh/v1alpha1
kind: Reservation
metadata:
name: reservation-demo
spec:
template: # set resource requirements
namespace: default
spec:
containers:
- args:
- '-c'
- '1'
command:
- stress
image: polinux/stress
imagePullPolicy: Always
name: stress
resources: # reserve 500m cpu and 800Mi memory
requests:
cpu: 500m
memory: 800Mi
schedulerName: koord-scheduler # use koord-scheduler
owners: # set the owner specifications
- object: # owner pods whose name is `default/pod-demo-0`
name: pod-demo-0
namespace: default
ttl: 1h # set the TTL, the reservation will get expired 1 hour later
- 观察并等候 Reservation reservation-demo 变为 Available 状况
$ kubectl create -f reservation-demo.yaml
reservation.scheduling.koordinator.sh/reservation-demo created
$ kubectl get reservation
NAME PHASE AGE
reservation-demo Available 3h16m
- 运用下面的文件创立 Pod pod-demo-0
apiVersion: v1
kind: Pod
metadata:
name: pod-demo-0 # match the owner spec of `reservation-demo`
spec:
containers:
- args:
- '-c'
- '1'
command:
- stress
image: polinux/stress
imagePullPolicy: Always
name: stress
resources:
limits:
cpu: '1'
memory: 1Gi
requests:
cpu: 200m
memory: 400Mi
restartPolicy: Always
schedulerName: koord-scheduler # use koord-scheduler
$ kubectl create -f pod-demo-0.yaml
pod/pod-demo-0 created
- 检查 Pod pod-demo-0 的调度成果
$ kubectl get pod pod-demo-0 -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
pod-demo-0 1/1 Running 0 32s 10.17.0.123 node-0 <none> <none>
pod-demo-0 被调度到 与 Reservation reservation-demo 相同的节点。
- 检查 Reservation reservation-demo 的状况.
$ kubectl get reservation reservation-demo -oyaml
apiVersion: scheduling.koordinator.sh/v1alpha1
kind: Reservation
metadata:
name: reservation-demo
creationTimestamp: "YYYY-MM-DDT05:24:58Z"
uid: xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx
...
spec:
owners:
- object:
name: pod-demo-0
namespace: default
template:
spec:
containers:
- args:
- -c
- "1"
command:
- stress
image: polinux/stress
imagePullPolicy: Always
name: stress
resources:
requests:
cpu: 500m
memory: 800Mi
schedulerName: koord-scheduler
ttl: 1h
status:
allocatable: # total reserved
cpu: 500m
memory: 800Mi
allocated: # current allocated
cpu: 200m
memory: 400Mi
conditions:
- lastProbeTime: "YYYY-MM-DDT05:24:58Z"
lastTransitionTime: "YYYY-MM-DDT05:24:58Z"
reason: Scheduled
status: "True"
type: Scheduled
- lastProbeTime: "YYYY-MM-DDT05:24:58Z"
lastTransitionTime: "YYYY-MM-DDT05:24:58Z"
reason: Available
status: "True"
type: Ready
currentOwners:
- name: pod-demo-0
namespace: default
uid: yyyyyyyy-yyyy-yyyy-yyyy-yyyyyyyyyyyy
nodeName: node-0
phase: Available
咱们可以观察到 Reservation reservation-demo 预留了 500m CPU 和 800 Mi 内存,而且 Pod pod-demo-0从 Reservation reservation-demo中分配了 200m CPU 和 400Mi 内存。
- 清理 Reservation reservation-demo.
$ kubectl delete reservation reservation-demo
reservation.scheduling.koordinator.sh "reservation-demo" deleted
$ kubectl get pod pod-demo-0
NAME READY STATUS RESTARTS AGE
pod-demo-0 1/1 Running 0 110s
可以观察到 Reservation 删除后,Pod pod-demo-0 还在运转中。
安全牢靠的 Pod腾挪搬迁机制 – PodMigrationJob
腾挪搬迁 Pod 是许多组件(例如 descheduler)所依赖的重要功用,可用于优化调度或协助处理作业负载运转时质量问题。咱们以为 Pod 搬迁是一个杂乱的进程,涉及到审计、资源分配、运用启动等步骤,还夹杂着运用的发布晋级、扩容/缩容场景和集群办理员的资源运维操作。因而,怎么办理 Pod 搬迁进程的安稳性危险,确保运用不会由于 Pod 的搬迁影响可用性,是一个十分要害的有必要处理的问题。
为了让咱们更好的了解,举几个场景:
-
社区的重调度器内置的多个重调度战略依据本身逻辑判别某个 Pod 是否要被搬迁,需求搬迁时调用 K8s Eviction API 建议驱赶。可是这个进程并不重视被驱赶的 Pod 在将来是否可以分配到资源。因而存在许多 Pod 被驱赶后由于没有资源而处于 Pending 状况的情况。假如运用此刻有许多请求进来,又由于没有满意的可用的 Pod 导致可用性反常。
-
别的,社区重调度器调用的 K8s Evcition API 尽管会检查 PDB 确保在安全范围内驱赶,可是众所周知,众多的 workload Controller 在发布和缩容场景都是经过直接调用 Delete API 的方法毁掉 Pod,此刻并不会被 PDB 限制。这就导致重调度时假如遇到上述场景,是很可能引发严重的安稳性问题。
-
咱们以为 Pod 腾挪不是一个简略的后台自动化逻辑,有相当多的场景和用户期望由人工介入手工搬迁 Pod,甚至期望重调度时建议的自动搬迁请求应该被拦截掉,经过批阅决议是否履行。
Koordinator 依据 CRD 界说了一个名为PodMigrationJob API [4 ] 。重调度器或许其他自动化自愈组件经过 PodMigrationJob 可以安全的搬迁 Pod。PodMigrationJob Controller 在处理 PodMigrationJob 时会先测验经过 Koordinator Reservation 机制预留资源,预留失败则搬迁失败;资源预留成功后建议驱赶操作并等候预留的资源被消费。中间的进程都会记载到 PodMigrationJobStatus 中,并发生相关的 Event。
- Quick Start
PodMigrationJob 运用起来也十分简略:
- 运用如下 YAML 文件创立一个 PodMigrationJob migrationjob-demo,搬迁 Pod pod-demo-5f9b977566-c7lvk
apiVersion: scheduling.koordinator.sh/v1alpha1
kind: PodMigrationJob
metadata:
name: migrationjob-demo
spec:
paused: false
ttl: 5m
mode: ReservationFirst
podRef:
namespace: default
name: pod-demo-5f9b977566-c7lvk
status:
phase: Pending
$ kubectl create -f migrationjob-demo.yaml
podmigrationjob.scheduling.koordinator.sh/migrationjob-demo created
- 查询 PodMigrationJob 的搬迁状况
$ kubectl get podmigrationjob migrationjob-demo
NAME PHASE STATUS AGE NODE RESERVATION PODNAMESPACE POD NEWPOD TTL
migrationjob-demo Succeed Complete 37s node-1 d56659ab-ba16-47a2-821d-22d6ba49258e default pod-demo-5f9b977566-c7lvk pod-demo-5f9b977566-nxjdf 5m0s
$ kubectl describe podmigrationjob migrationjob-demo
...
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ReservationCreated 8m33s koord-descheduler Successfully create Reservation "d56659ab-ba16-47a2-821d-22d6ba49258e"
Normal ReservationScheduled 8m33s koord-descheduler Assigned Reservation "d56659ab-ba16-47a2-821d-22d6ba49258e" to node "node-1"
Normal Evicting 8m33s koord-descheduler Try to evict Pod "default/pod-demo-5f9b977566-c7lvk"
Normal EvictComplete 8m koord-descheduler Pod "default/pod-demo-5f9b977566-c7lvk" has been evicted
Normal Complete 8m koord-descheduler Bind Pod "default/pod-demo-5f9b977566-nxjdf" in Reservation "d56659ab-ba16-47a2-821d-22d6ba49258e"
可以观察到,PodMigrationJob Controller 把 Pod pod-demo-5f9b977566-c7lvk 搬迁到了 node-1
,新 Pod 为 pod-demo-5f9b977566-nxjdf.
- 裁定机制
当时版别还暂未完成规划计划中界说的裁定机制,该机制将会在 v0.7 版别中完成。裁定机制是指 PodMigrationJob Controller 在 reconcile 前会挑选最适宜的一批 PodMigrationJob 履行。该进程涉及到 Group、Filter 和 Sort 三个阶段。
- Group 阶段:
会依照 Workload, Namespace 和 Node 三个维度聚合。
- Filter 阶段:
过滤掉危险的 PodMigrationJob。
- 判别 Workload 对应的 PDB 或许 OpenKruise PUB,假如不契合界说的安全阈值,则会过滤掉
- 判别方针 Pod 关联的 Workload 有多少正在履行的 PodMigrationJob,假如到达了装备的最大数量,则会过滤掉。
- 判别 Namespace 维度下正在搬迁的 Pod 数量,超过阈值则过滤掉
- 判别 Node 维度下正在搬迁的 Pod 数量,超过阈值则过滤掉
- Sort 阶段:
对 PodMigrationJob 排序和打散。尽量挑选搬迁代价低的 Pod。
- 用户可以依据实际情况,在 Pod 上追加标签 scheduling.koordinator.sh/eviction-cost标记搬迁代价。
- 让每个Workload、Namespace、Node 尽可能少的驱赶 Pod
全新的重调度结构 – Descheduler Framework
咱们在 Koordinator v0.6 版别中完成了一个全新的重调度器结构 [ 5 ] (Descheduler Framework)。
K8s 社区 descheduler 在过去供给了一些战略处理一些常用的调度编列反常问题。但咱们以为社区的 descheduler 还有许多方面可以提高:
-
K8s 社区 descheduler 只支撑守时履行的机制,不支撑依据 Event 触发的作业模式,无法满意一些期望联动其他组件触发的事件或许期望依据 Pod/Node 事件完成更积极的重调度等场景。
-
别的社区 descheduler 不能很好的扩展完成自界说重调度战略,每次需求完成一个自界说重调度战略时都需求把社区上游的代码拷贝到本地进行修正,然后自己保护起来,当后续社区有变化时,需求花费较大的代价进行兼并。这点与 kube-scheduler 对比来看,kube-scheduler 依据 scheduling framework,支撑用户无需修正上游代码既可以扩展调度才干。
-
不支撑自界说驱赶逻辑。例如当需求完成上面说到的 PodMigrationJob 时,只能 fork 代码后修正适配。
咱们以为重调度场景:
-
需求一个插件化机制完成自界说的重调度战略,但又不期望这个抽象过于杂乱;
-
需求具有根本的插件办理才干,经过装备启用和禁用插件;
-
具有一致的插件装备下发机制,便利插件自界说参数;
-
并可以便利的扩展和运用一致的 Evictor 机制;
-
别的期望用户可以依据 controller-runtime 完成 controller 并归入一致的插件办理机制。
咱们在进行 descheduler framework 的规划时,也留意到 K8s descheduler 社区其实也留意到了这些问题,期望完成一个类似于 K8s scheduling framework 相同的结构(descheduler framework) ,而且也提出了一些针对性的提案探索相关的完成,例如#753Descheduler framework Proposal [ 6] 和PoC #781 [ 7] 。
这个想法与 Koordinator 团队不约而同。纵观 K8s descheduler 社区的提案,根本上处理了咱们关怀的许多问题,例如插件装备、插件抽象等,可是咱们也留意到有许多相关完成还在 PoC 阶段或许部分相关完成还未合入到主干分支。经过 Koordinator 团队的 Review 和评论,咱们以为尽管这些提案中还有一些未处理的问题和未彻底敲定的规划,但咱们相信这是一个正确的方向。
一同依据 Koordinator 拟定的的里程碑,咱们期望赶快建造重调度相关的特性,因而咱们依据上游社区#753 PR [ 8] 的思路,在 Koordinator 中独立完成了一套新的 descheduler framework。咱们期望经过这样独立完成的方法处理 Koordinator 对重调度才干的需求,一同也期望借此推动上游社区 descheduler framework 作业的演进,当上游有新的发展时,咱们将会及时跟进,尽最大可能与上游保持兼容。
Koordinator descheduler framework 供给了插件装备办理(例如启用、禁用,一致装备等)、插件初始化、插件履行周期办理等机制。而且该结构内置了依据 PodMigrationJob 完成的 Controller,并作为 Evictor Plugin 便利被各种重调度插件运用,协助重调度插件安全的搬迁 Pod。
依据 Koordinator descheduler framework,用户可以十分简单的扩展完成自界说重调度战略,就像依据 K8s scheduling framework 的完成自界说的调度插件相同简略。而且用户也可以以插件的方法完成 controller,支撑依据 Event 触发重调度的场景。
当时,咱们已经完成了 descheduler framework 主体部分,整体都是可用的。而且供给了一个示例插件 [9 ] 便利咱们了解和开发。在后续的版别中,咱们将会搬迁社区已有的重调度战略,以插件的方法集成到 Koordinator,作为内置才干的一部分。而且还会针对混部场景,完成针对性的重调度插件处理混部场景下的具体问题,例如负载均衡重调度,处理节点间负载不均衡、热门等问题。
现在结构还处于快速演进的初期阶段,还有许多细节需求完善。欢迎咱们有兴趣一同参与建造。咱们期望更多的人可以更定心、更简略地完成自己需求的去调度才干。
其他改变
关于咱们关怀的 GPU Share Scheduling, Gang Scheduling 和 Elastic Quota Scheduling 等才干也有一些新的发展。
在 v0.6 版别中,Koordiantor社区完成了 GPU Share Scheduling 和 Gang Scheduling 的计划规划作业,相关的 Proposal 已经 Review 经过。Elastic Quota Scheduling 的计划规划也根本完成。这些才干将会在 v0.7 版别中完成。
别的,为了探索 GPU 超卖和 GPU 诊断剖析等场景,在 v0.6 版别中增加了 GPU Metric 上报机制。
你可以经过Github release [ 10] 页面,来检查更多的改动以及它们的作者与提交记载。
社区参与
十分欢迎你经过 Github/Slack/钉钉/微信 等方法参加咱们来参与 Koordinator 开源社区。你是否已经有一些期望与咱们社区沟通的内容呢?可以经过以下途径参与评论:
- 参加社区Slack channel [ 11] (English)
- 参加社区钉钉群:查找群号 33383887 (Chinese) 或许扫描下方二维码
相关链接
[1]版别 0.5 :
github.com/koordinator…
[2] CPU 精细化编列计划:
koordinator.sh/docs/user-m…
[3] 资源预留 API 规划计划
koordinator.sh/docs/design…
[4] PodMigrationJob API:
koordinator.sh/docs/design…
[5] 重调度器结构:
koordinator.sh/docs/design…
[6] #753 Descheduler framework Proposal :
github.com/kubernetes-…
[7] PoC #781:
github.com/kubernetes-…
[8] #753 PR:
github.com/kubernetes-…
[9] 示例插件:
github.com/koordinator…
[10] Github release:
github.com/koordinator…
[11] Slack channel:
koordinator-sh.slack.com/join/shared…