陈凯悦,腾讯云高级开发工程师,Crane和SuperEdge项目核心开发。专注于大规模离在线混部和资源调度,目前负责Crane离在线混部和调度相关工作。
孟凡杰,腾讯云容器专家工程师,Crane项目发起人,致力于云原生成本优化,腾讯云降本产品研发负责人。
用户使用云时,为不同特征的业务完成精确的资源配置不是一件容易的事情。FinOps 时代如何玩转应用资源配置 提供了诸多最佳实践。我们再来借助下图的单节点资源使用情况探讨一下资源合理利用的挑战,为简化问题,我们只关注核心资源 CPU。
如下图所示,为回收节点闲置资源,运行在每个节点的 Crane Agent 在初始化时会为每个节点按预定模版创建一个 TimeSeriesPrediction 的 CRD 对象,该对象包含目标节点信息和资源预测算法以及参数信息。为此 Crane 中的资源预测器会拉取该节点的资源用量历史,按既定预测算法进行预测,并将预测结果写入TSP对象的状态属性中。
运行在 Crane Agent 中的 Node Resource Controller 监听 TSP 对象的状态变换,并基于预测结果计算接下来该节点可复用的闲置资源,并将可复用 CPU 更新为节点 Allocatable 中的扩展资源gocrane.io/cpu
,将可复用 Mem 更新为节点 Allocatable 中的扩展资源gocrane.io/mem
。随着节点负载的不断变化,扩展资源的值也会实时调整。
而低优业务可在Pod中声明使用gocrane.io/cpu
这类扩展资源,Kubernetes调度器天然支持扩展资源的调度,而 Crane Agent 确保调度完成后的资源分配和管理。通过以上步骤就完成了闲置资源回收、重新分配、调度、保障的完整闭环。
但是在该能力的规模化推广过程中,我们发现了如下痛点:
gocrane.io/cpu
这种扩展资源形式出现,而众多大数据业务都是以 Operator 启动的作业 Pod,使用扩展资源需要通过修改 Operator 代码或者增加Webhook将cpu修改成gocrane.io/cpu
,侵入性较大。那么,有没有更优雅的做法,既能减少 Crane 能力的侵入性,又能从权限隔离层面天然灵活契合组织的组织架构呢?
基于内部的大量实践,参考了腾讯 IEG 主导开源的 GitHub - virtual-kubelet/tensile-kube: A Kubernetes Provider,我们开创性地提出了基于虚拟节点的离线算力模式。
假设用户有一个在线业务集群 Cluster1,该集群部署了 Crane 套件,默认情况下,每个节点上运行的 Crane Agent 会基于预测结果更新节点状态中的gocrane.io/cpu
和gocrane.io/mem
。
运行一个我们专门为 Crane 闲置资源回收而开发的 Virtual Kubelet Pod。Virtual Kubelet 的工作原理很简单,参考下图,只需完成 NodeProvider、(Pod)Provider和PodMetricsProvider 的接口实现,我们就能构造一个虚拟的 Kubernetes 节点。
NodeProvider 职责包括:
gocrane.io/cpu
,并完成扩展资源到原生资源的转换,以节点可调度资源 cpu, mem 上报。Provider 的主要职责包括:
PodMetricsProvider 的主要职责包括:
Crane 的 Virtual Kubelet Provider 实现了对单集群所有节点闲置资源的监听汇总,并更新至虚拟节点可分配资源中。一个节点就能代表整个集群的所有离线算力。
将一个集群的所有离线算力抽取到一个虚拟节点以后,如何面向离线用户提供服务呢?针对在线、离线集群分离的组织,假设用户 Cluster1 和 Cluster2 是用户在线集群,Cluster3 是用户离线集群。
基于 Crane 虚拟节点的我们就可以很轻易的将所有在线集群(Cluster1和Cluster2)的离线算力抽取出来,并注册到离线集群(Cluster3)中。
这样的体系架构下,在线集群用户是资源供给方,离线集群用户是资源使用方,两个用户群体入口不同,权限完全隔离。而通过 Virtual Kubelet 的虚拟节点,我们以较低成本实现了在线集群闲置资源都离线集群的资源流转,在无侵入的前提下实现了基于混部的在线集群资源利用率提升。
GitHub - virtual-kubelet/tensile-kube: A Kubernetes Provider:
https://github.com/virtual-kubelet/tensile-kube
Crane 已成功加入 CNCF Landscape,欢迎关注项目,合作共建: