由于我们使用的是 TKE vpc-cni 的网络模式,这种网络模式依赖节点绑定的弹性网卡数量,所以单个节点上的 pod ip 数量存在上限,节点有几乎一半的 podip 是为定时任务的 pod 保留的,造成ip 浪费,另外定时任务的 pod 运行时间普遍很短,这就导致了集群为定时任务预留的资源产生了较多闲置,不利于整体的机器资源使用率提升。
其他问题:调度速度、服务间隔离性
在某些时段,比如每天 0 点,会同时产生几千个 Job 需要运行。而原生调度器是 K8s 调度 pod 本身对集群资源分配,反应在调度流程上则是预选和打分阶段是顺序进行的,也就是串行。几千个 Job 调度完成需要几分钟,而大部分业务是要求 00:00:00 准时运行或者业务接受误差在 3s 内。有些服务 pod 是计算或者 IO 密集型,这种服务会大量抢占节点 CPU 或者 IO,而 cgroup 的隔离并不彻底,所以会干扰其他正常在线服务运行。
解决思路及方案
所以,对 CronJob 型任务我们需要一个更彻底的隔离方式,更细粒度的节点,更快的调度模式。为解决上诉问题,我们考虑将定时任务 pod 和普通在线服务的 pod 隔离开,但是由于很多定时任务需要和集群内服务互通,还不能通过分集群的方式隔离。腾讯云弹性容器服务 EKS 提供的虚拟节点,给我们解决上诉问题提供了一个新的思路。EKS 的虚拟节点是 serverless 形态的 Kubernetes 服务,可以加入到现有的TKE 集群中,部署在虚拟节点上的 pod 具备与部署在正常 TKE 节点上的 pod 具备一致的网络连通性,但虚拟节点上的pod 是在vm 层面做了隔离,又具有无需预留资源,按量计费的特性,可以很好的满足我们这个场景的需求,所以我们将CronJob 这种类型的业务都调度到了虚拟节点.如图所示:
任务调度器
为解决 K8s 默认串行调度慢的问题,我们针对 job 类任务,开发了任务调度器,所有 CronJob 型 workload 都使用任务调度器,任务调度器批量并行调度任务 pod 到 虚拟 节点,实现大规模 pod 任务 ms 级调度,也支持 虚拟节点故障时或者资源不足时调度回标准 TKE 节点。
解决 TKE 节点和虚拟节点在运维方式上的差异
在使用 虚拟节点前,首先要解决虚拟节点 pod 和运行在标准节点上的 pod 差异,做到对业务研发无感。