作业帮上万个 CronJob 和在线业务混部,如何解决弱隔离问题并进一步提升资源利用率?

此账号已注销
• 阅读 5620

作者

吕亚霖,作业帮基础架构 - 架构研发团队负责人。负责技术中台和基础架构工作。在作业帮期间主导了云原生架构演进、推动实施容器化改造、服务治理、GO 微服务框架、DevOps 的落地实践。

别路,作业帮基础架构-高级研发工程师,在作业帮期间,负责多云 K8s 集群建设、K8s 组件研发、Linux 内核优化调优相关工作。

背景

作业帮在云原生容器化改造的过程中,随着集群规模越来越大、业务混合部署的场景越来越复杂,面临的集群问题也越来越多,走到了 Kubernetes 及容器化的深水区, 尤其是在上万个 CronJob 容器化,和在线业务混合部署在同一个生产集群后,问题就更加明显。

作业帮在线的生产业务使用 TKE 部署在黑石2.0 物理机上,单个机器规格比较大,部署的pod 也就比较多,而 cronjob 的特性是频繁、定时启动和销毁,同时也需要给这部分业务预留一定的固定资源,所以这块主要有 2 个问题;一是在大规模pod 频繁创建销毁场景下,cgroup 弱隔离性导致的节点稳定性问题,从而影响同一节点其他业务,二是资源预留导致的资源利用率低的问题。这两个问题其实已经超出了 原生 Kubernetes 的能力覆盖范围,我们需要新的思路来解决。

下面将详细介绍这两个问题产生的原因及解决办法。

问题一:集群内节点稳定性

由于业务上存在很多分钟级执行的定时任务,导致 pod 的创建和销毁非常频繁,单个节点平均每分钟有上百个容器创建和销毁,机器的稳定性问题频繁出现。

一个典型的问题是频繁创建 pod 导致节点上 cgroup 过多,特别是 memory cgroup 不能及时回收,读取/sys/fs/cgroup/memory/memory.stat 变慢,由于 kubelet 会定期读取该文件来统计各个 cgroup namespace 的内存消耗,CPU 内核态逐渐上升,上升到一定程度时,部分 CPU 核心会长时间陷入内核态,导致明显的网络收发包延迟。

在节点 perf record cat /sys/fs/cgroup/memory/memory.stat 和 perf report 会发现,CPU 主要消耗在 memcg_stat_show 上:

作业帮上万个 CronJob 和在线业务混部,如何解决弱隔离问题并进一步提升资源利用率?

而 cgroup-v1 的 memcg_stat_show 函数会对每个 CPU 核心遍历多次 memcg tree,而在一个 memcg tress 的节点数量达到几十万级别时,其带来的耗时是灾难性的。

为什么 memory cgroup 没有随着容器的销毁而立即释放呢?主要是因为 memory cgroup 释放时会遍历所有缓存页,这可能很慢,内核会在这些内存需要用到时才回收,当所有内存页被清理后,相应的 memory cgroup 才会释放。整体来看,这个策略是通过延迟回收来分摊直接整体回收的耗时,一般情况下,一台机器上创建容器不会太多,通常几百到几千基本都没什么问题,但是在大规模定时任务场景下,一台机器每分钟都有上百个容器被创建和销毁,而节点并不存在内存压力,memory cgroup 没有被回收,一段时间后机器上的 memory cgroup 数量达到了几十万,读取一次 memory.stat 耗时达到了十几秒,CPU 内核态大幅上升,导致了明显的网络延迟。

作业帮上万个 CronJob 和在线业务混部,如何解决弱隔离问题并进一步提升资源利用率?

除此之外,dockerd 负载过高、响应变慢、kubelet PLEG 超时导致节点 unready 等问题。

问题二:集群的节点资源利用率

由于我们使用的是 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 这种类型的业务都调度到了虚拟节点,如图所示:

作业帮上万个 CronJob 和在线业务混部,如何解决弱隔离问题并进一步提升资源利用率?

任务调度器

为解决 K8s 默认串行调度慢的问题,我们针对 job 类任务,开发了任务调度器,所有 CronJob 型 workload 都使用任务调度器,任务调度器批量并行调度任务 pod 到 虚拟 节点,实现大规模pod 任务 ms 级调度,也支持 虚拟节点故障时或者资源不足时调度回标准 TKE 节点。

解决 TKE 节点和虚拟节点在运维方式上的差异

在使用 虚拟节点前,首先要解决 虚拟节点 pod 和运行在标准节点上的 pod 差异,做到对业务研发无感。

日志采集统一

在日志采集方面,由于 EKS 这种 nodeless 的形态,无法运行 DaemonSet,而我们的日志采集组件是以 DaemonSet 形式运行的,这就需要对虚拟节点上的日志做单独的采集方案。EKS 虚拟节点 本身提供日志采集agent, 可以将容器的标准输采集并吐到一个 Kafka topic,然后我们统一在这个 topic 里消费。

监控报警统一

在监控方面,我们对 虚拟节点 上的 pod 做了实时 CPU/内存/磁盘/网络流量等监控,做到了和普通节点上的 pod 一致,暴露 pod sanbox 的 export 接口,promethus 负责统一采集,迁移到 虚拟节点 时做到了业务完全无感。

提升启动性能

虚拟节点上的 Job 需要具备秒级的启动速度才能满足定时任务对启动速度的要求,比如业务要求 00:00:00 准时运行或者业务接受误差在 3s 内。

主要耗时在以下两个步骤:

  1. 业务镜像拉取加速

  2. 虚拟节点 pod 创建和初始化加速

针对第一个问题:EKS 提供镜像缓存的功能,第一次拉取的时候稍微慢一些,拉下来后默认会缓存一段时间,同一个业务第二次启动就不需要再拉取镜像,所有镜像下载慢的问题基本就没有了。

针对第二个问题:业务要求的启动时间误差在 3s 内,所以我们和 腾讯云 EKS 团队沟通后,为这种大规模、高频、短时的计算作业场景进行了针对性优化,提升了频繁启动的效率并降低了运行环境初始化的时间。

最终实现了虚拟节点上的 Pod 秒级启动。

总结

通过 TKE + EKS 虚拟节点的方式,我们将正常在线任务和定时任务隔离开,有效保障了在线业务的稳定性,结合 自研 Job 任务调度器、EKS 镜像缓存、pod 启动加速等能力,实现 任务pod 秒级调度并启动,同时 TKE + 虚拟节点 都是标准的 K8s API ,做到了业务平滑迁移。最终要的是,我们固定的集群不需要再为 CronJob 类任务预留资源,释放了集群里 10% 的资源,结合 EKS 随用随取、按量计费的特性,定时任务的资源成本降低了 70%左右。

关于我们

更多关于云原生的案例和知识,可关注同名【腾讯云原生】公众号~

福利:

①公众号后台回复【手册】,可获得《腾讯云原生路线图手册》&《腾讯云原生最佳实践》~

②公众号后台回复【系列】,可获得《15个系列100+篇超实用云原生原创干货合集》,包含Kubernetes 降本增效、K8s 性能优化实践、最佳实践等系列。

③公众号后台回复【白皮书】,可获得《腾讯云容器安全白皮书》&《降本之源-云原生成本管理白皮书v1.0》

点赞
收藏
评论区
推荐文章
作业帮 Kubernetes 原生调度器优化实践
作者吕亚霖,2019年加入作业帮,作业帮架构研发负责人,在作业帮期间主导了云原生架构演进、推动实施容器化改造、服务治理、GO微服务框架、DevOps的落地实践。简介调度系统的本质是为计算服务/任务匹配合适的资源,使其能够稳定高效地运行,以及在此的基础上进一步提高资源使用密度,而影响应用运行的因素非常多,比如CPU、内存、IO、差异化的资源设备等等一系列因
光速从0到1掌握Prometheus和Grafana,腾讯云专家5万字精华教程免费送
作者黄雷,腾讯云高级工程师,曾负责构建腾讯云云监控新一代多维业务监控系统,擅长大规模分布式监控系统设计,对golang后台项目架构设计有较深理解,后加入TKE团队,致力于研究Kubernetes相关运维技术,拥有多年Kubernetes集群联邦运维管理经验,目前在团队主要负责大规模集群联邦可观测性提升,主导研发了腾讯云万级Kubernetes
TKE用户故事 | 作业帮检索服务基于Fluid的计算存储分离实践
作者吕亚霖,2019年加入作业帮,作业帮基础架构架构研发团队负责人,在作业帮期间主导了云原生架构演进、推动实施容器化改造、服务治理、GO微服务框架、DevOps的落地实践。张浩然,2019年加入作业帮,作业帮基础架构高级架构师,在作业帮期间,推动了作业帮云原生架构演进、负责多云k8s集群建设、k8s组件研发、linux内核优化调优、底层服务容器化相关工作。
虚拟节点轻松应对 LOL S11 百万并发流量——腾竞体育的弹性容器实践
作者刘如梦,腾竞体育研发工程师,擅长高并发、微服务治理、DevOps,主要负责电竞服务平台架构设计和基础设施建设。詹雪娇,腾讯云弹性容器服务EKS产品经理,主要负责EKS虚拟节点、容器实例相关的产品策划。业务介绍自2019年,腾竞整个电竞赛事数据服务完全由腾讯云TKE容器服务承载。腾竞赛事数据开放平台目前主要提供职业赛事数据的授权与查询,随着斗
TKE 用户故事 - 作业帮 PB 级低成本日志检索服务
作者吕亚霖,2019年加入作业帮,作业帮架构研发负责人,在作业帮期间主导了云原生架构演进、推动实施容器化改造、服务治理、GO微服务框架、DevOps的落地实践。莫仁鹏,2020年加入作业帮,作业帮高级架构师,在作业帮期间,推动了作业帮云原生架构演进,负责作业帮服务治理体系的设计和落地、服务感知体系建设以及自研mesh、MQproxy研发工作。摘要日志是服务
Stella981 Stella981
2年前
QCon技术干货:个推基于Docker和Kubernetes的微服务实践
2016年伊始,Docker无比兴盛,如今Kubernetes万人瞩目。在这个无比需要创新与速度的时代,由容器、微服务、DevOps构成的云原生席卷整个IT界。在近期举办的QCon全球软件开发大会上,个推应用平台基础架构高级研发工程师王志豪,基于他在基础架构方面多年的经验,分享了《个推基于Docker和Kubernetes的微服务实践》。!QCon技术
Wesley13 Wesley13
2年前
AI云原生浅谈:好未来AI中台实践
AI时代的到来,给企业的底层IT资源的丰富与敏捷提出了更大的挑战,利用阿里云稳定、弹性的GPU云服务器,领先的GPU容器化共享和隔离技术,以及K8S集群管理平台,好未来通过云原生架构实现了对资源的灵活调度,为其AI中台奠定了敏捷而坚实的技术底座。在2020年云栖大会上,好未来AI中台负责人刘东东,分享了他对AI云原生的理解与好未来的AI中台实践,本文为演
Easter79 Easter79
2年前
Tedis:基于 TiKV 构建的 NoSQL 数据库
作者介绍:陈东明,饿了么北京技术中心架构组负责人,负责饿了么的产品线架构设计以及饿了么基础架构研发工作。曾任百度架构师,负责百度即时通讯产品的架构设计。具有丰富的大规模系统构建和基础架构的研发经验,善于复杂业务需求下的大并发、分布式系统设计和持续优化。个人微信公众号dongming\_cdm。Tedis(https://github.
AMS 新闻视频广告的云原生容器化之路
作者卓晓光,腾讯广告高级开发工程师,负责新闻视频广告整体后台架构设计,有十余年高性能高可用海量后台服务开发和实践经验。目前正带领团队完成云原生技术栈的全面转型。吴文祺,腾讯广告开发工程师,负责新闻视频广告流量变现相关后台开发工作,熟悉云原生架构在生产实践中的应用,拥有多年高性能高可用后台服务开发经验。目前正推动团队积极拥抱云原生。陈宏钊,腾讯广告高级开发工程
Kubernetes 资源拓扑感知调度优化
作者星辰算力团队,星辰算力平台基于深入优化云原生统一接入和多云调度,加固容器运行态隔离,挖掘技术增量价值,平台承载了腾讯内部的CPU和异构算力服务,是腾讯内部大规模离线作业、资源统一调度平台。背景问题源起近年来,随着腾讯内部自研上云项目的不断发展,越来越多的业务开始使用云原生方式托管自己的工作负载,容器平台的规模因此不断增大。以Kubernetes