共计 3947 个字符,预计需要花费 10 分钟才能阅读完成。
随着云计算和容器技术的倒退,以 docker 为外围的容器技术迅速在开发者和科技公司中利用,Kubernetes 凭借丰盛的企业级、生产级性能成为事实上的容器集群管理系统。可是 k8s 的 通用性
减弱了调度算法的 定制性
,本文将调研定制化调度算法的办法,并且给出一个开源实现 Demo。
k8s 与调度器架构
下图 1 - 1 是 Kubernetes 的整体架构图,集群节点分为两种角色:Master 节点
和Node 节点
。Master 节点是整个集群的管理中心,负责集群治理、容器调度、状态存储等组件都运行在 Master 节点上;Node 节点是实际上的工作节点,负责运行具体的容器。
Kubernetes 调度器是独立运行的过程,外部运行过程从逻辑上能够分为多个模块。图 1 - 2 展现了默认调度器外部蕴含的具体模块,配置模块负责读取调度器相干配置信息,并且依据配置内容初始化调度器。
- 优先队列模块是一个优先堆数据结构,负责将待调度 Pod 依据优先级排序,优先级高的 Pod 排在后面,调度器会轮询优先队列,当队列中存在待调度 Pod 时就会执行调度过程。
- 调度模块由
算法模块
、Node 缓存
和调度扩大点
三局部组成,算法模块提供对 Node 进行评分的一系列根底算法,比方平衡节点 CPU 和内存使用率的 NodeResourcesBalancedAllocation 算法,算法模块是可扩大的,用户能够批改和增加本人的调度算法;Node 缓存模块负责缓存集群节点的最新状态数据,为调度算法提供数据撑持;调度扩大点由一系列扩大点形成,每个扩大点负责不同的性能,最重要的扩大点是 Filter、Score 和 Bind 这三个扩大点。 - 最初是绑定模块,负责将调度器抉择的 Node 和 Pod 绑定在一起。
Kubernetes 调度器代码采纳可插拔的插件化设计思路,包含外围局部和可插拔局部。图 1 - 2 中的配置模块、优先队列和 Node 缓存是外围局部,算法模块、调度扩大点属于可插拔局部。这种插件化设计容许调度器一些性能通过插件的形式实现,不便代码批改和性能扩大,同时放弃调度器外围代码简略可保护。
下图 1 - 3 列出了调度器扩大点模块中蕴含的具体扩大点。Pod 的调度过程分为 调度周期
和绑定周期
,调度和绑定周期独特形成 Pod 的调度上下文。调度上下文由一系列扩大点形成,每个扩大点负责一部分性能,最重要的扩大点是调度周期中的预选(Filter) 和优选 (Score) 扩大点和绑定周期中的绑定 (Bind) 扩大点。预选扩大点负责判断每个节点是否可能满足 Pod 的资源需要,不满足就过滤掉该节点。优选扩大点局部会对每个 Pod 运行默认的评分算法,并且将最终评分加权汇总,失去最初所有节点的综合评分;调度器会抉择综合评分最高的节点,如果有多个节点评分雷同且最高,调度器会通过水塘采样算法在多个节点中随机抉择一个作为调度后果,而后将该节点上 Pod 申请的资源用量进行保留操作,避免被其它 Pod 应用。在绑定周期中,调度器将 Pod 绑定到评分最高的节点上,这一步实质是批改 Pod 对象中节点相干的信息,并且更新到存储组件 etcd 中。
定制化算法计划
如果要实现自定义调度算法,次要有三种计划:
- 批改默认调度器的源代码,退出本人的调度算法,而后从新编译和部署调度器,论文 kcss 和 kubecg 中的调度器钻研基于此计划实现;
- 开发本人的调度器,和默认调度器同时运行在集群中;
- 基于 Kubernetes Scheduler Extender 机制,在扩大调度器中实现自定义算法,论文 dynamic IO 中的算法实现基于这种计划。
上述三种自定义调度算法实现计划的优缺点见表 2 -1。综合来讲,
- 计划 1 改变最小,然而这样做会毁坏开源软件的可维护性,当 Kubernetes 骨干代码更新时,改变后的调度器要和上游代码保持一致,这会带来大量的保护和测试工作。
- 计划 2 是实现本人的调度器,并且在集群中运行多个调度器,多个调度器之间没有集群资源数据同步,存在并发调度数据竞争和数据不统一的问题。
- 计划 3 须要默认调度器通过 API 和 Extender 交互,新增的网络申请会减少整个调度过程的耗时。
2-1 自研调度算法计划比照
计划 | 长处 | 毛病 |
---|---|---|
计划 1:批改调度器源代码 | 改变小 | 毁坏源代码、不好保护 |
计划 2:运行多个调度器 | 不改变源代码 | 存在数据竞争、不统一 |
计划 3:开发扩大调度器 | 不改变源代码 | 存在网络耗时 |
本文的调度器实现采纳计划 3,设计并开发合乎 Scheduler Extender 机制和 API 标准的扩大调度器,将其命名为Liang。代码 2 - 1 是扩大调度器 JOSN 格局的策略配置文件,通过配置文件参数将该策略文件传递给 Kubernetes 默认调度器,其中 urlPrefix 示意扩大调度器 Liang 运行后监听的 API 地址,prioritizeVerb 示意优选扩大点在扩大调度器中的路由。当默认调度器在优选扩大点运行完评分插件后会发送 HTTP POST 网络申请到 Liang 的 API 地址,并将 Pod 和候选节点信息放在 HTTP Body 中一起传递过来。接管到 POST 申请后,扩大调度器 Liang 会依据评分算法对节点进行评分并将后果返回给默认调度器。
{
"kind": "Policy",
"apiVersion": "v1",
"extenders": [
{
"urlPrefix": "http://localhost:8000/v1",
"prioritizeVerb": "prioritizeVerb",
"weight": 1,
"enableHttps": false,
"httpTimeout": 1000000000,
"nodeCacheCapable": true,
"ignorable": false
}
]
}
图 2 - 1 是带扩大的默认调度器 (kube-scheduler) 启动过程,通过 kube-policy.json 配置文件将扩大调度器 Liang 的配置信息通知默认调度器。
扩大调度器 Liang
扩大调度器 Liang 独立于 Kubernetes 默认调度器,Liang 的模块设计和组织架构如图 3 - 1 所示,包含多维资源采集存储和 API 服务两大部分。多维资源数据采集通过在集群中运行 Prometheus 和 node-exporter 实现,扩大调度器 Liang 负责从 Prometheus 获取多维指标而后使用调度算法,将后果返回给默认调度器。
- api server 模块,负责实现合乎扩大调度器数据格式和传输标准的 API 接口,Liang 接管到 Kubernetes 的评分申请后,解析失去申请中的 Pod 和候选节点信息,作为参数传递给外部的调度算法,失去候选节点的评分后果并返回给默认调度器。
- 调度算法模块,扩大调度器 Liang 的外围模块,负责实现自定义的调度算法。得益于扩大调度器机制,Liang 中能够实现多个自定义调度算法。本文次要设计并实现了 BNP 和 CMDN 两个调度算法。
-
数据缓存模块,次要性能有两个:
- 通过申请 Prometheus 的 API 失去整个 Kubernetes 集群中所有节点的状态数据。
- 实现基于内存的指标数据缓存机制,提供指标数据的写入和读取接口,进步算法运行时获取多维指标数据的速度。
Liang 应用 Go 语言开发,代码量约 3400 行,开源网址为 Liang 开源地址。
表 3 - 1 是扩大调度器是否应用缓存机制和默认调度器做出调度决策的耗时比照,调度耗时通过在 Kubernetes 调度器源代码中打印工夫戳的形式获取,别离运行 9 次而后计算平均值。从表 3 - 1 中能够看到,默认调度器做出调度决策的耗时十分小,不到 1ms。加上扩大调度器和缓存机制的状况下,均匀调度决策耗时为 4.439ms,比默认调度器减少了约 3ms,减少的工夫次要是默认调度器与扩大调度器 Liang 之间网络申请耗时以及 Liang 运行调度算法所需的工夫。当扩大调度器不加缓存机制时,每次做出调度决策的均匀耗时为 1110.439ms,调度耗时迅速减少超过 100 倍,次要是每次做出调度决策都要申请 Prometheus 计算和获取集群中的指标数据。因而,扩大调度器加上缓存机制能够防止申请 Prometheus 带来的网络申请工夫,升高扩大调度器的决策工夫,晋升了扩大调度器的性能。
3-1 不同调度器架构决策耗时
调度类型 | 均匀决策耗时 |
---|---|
默认调度器 | 0.945ms |
扩大调度器 - 应用缓存 | 4.439ms |
扩大调度器 - 不应用缓存 | 1110.439ms |
BNP 算法
BNP 算法在 Liang 中实现,它将网络 IO 应用状况纳入 k8s 调度算法的考量,可能平衡集群中的网络 IO 用量。
图 3 - 2 是试验中默认调度算法和 BNP 算法中,整个集群中网络 IO 资源的变动状况,每部署一个 Pod 统计一次数据,共部署九个 Pod。能够显著看到,BNP 试验中网络 IO 资源要比默认调度算法调配更平衡。
CMDN 算法
CMDN 算法在 Liang 中实现,它的指标是让集群中的多维资源分配更加平衡或者更加紧凑,外围步骤是针对 CPU、内存、磁盘 IO 和网络 IO 以及网卡带宽这五个指标进行综合排序,抉择最佳 Node 部署 Pod。图 3 - 3 是试验中 CPU 使用率变动比照状况,能够显著看到,CMDN 平衡策略下 CPU 使用率平衡水平要比默认调度算法调配更平衡。
总结
Kubernetes 调度算法的通用性减弱了算法的定制性 。本文钻研了 k8s 调度器架构和扩大机制,比照了三种定制化调度算法计划,抉择扩大计划实现 扩大调度器 Liang
,并在 Liang 中实现了两个调度算法 BNP 和 CMDN 用于展现定制化算法能力。
扩大计划极大丰富了定制化调度算法的能力,能够满足十分多定制化场景的需要。同时也须要留神,定制调度算法往往须要更多的数据,这就须要在 k8s 集群中额定部署数据采集模块,减少了运维老本,升高了定制化调度算法的通用性。
原文链接,文章继续更新,能够微信搜寻「机器学习与零碎 」浏览最新内容,回复 材料 、 内推 、 考研 获取相干内容。