作者:国梁
资料来源: https://tech.meituan.com/2019/08/22/kuber ntes-cluster-management-practice.html
背景
作为国内领先的生活服务平台,美团评价多项业务非常显着,具有规律的“高峰”和“谷”特征。 特别是遇到假日和宣传活动,流量会在短时间内爆炸性增加。 这不仅对群集中心资源的灵活性和可用性要求非常高,而且使系统支持业务流量的复杂性和成本支出呈指数级增长。 我们要做的是利用有限的资源最大化集群吞吐量,保障用户体验。
本文介绍美团评价kuberetes的集群管理和使用实践,包括美团评价集群管理和调度系统介绍、kuberetes管理和实践、kuberetes的优化和改造、资源管理和优化等。
美团点评集群管理与调度系统
美团在集群管理和资源最优化的道路上,多年来一直评价“摸索着滚动”。 2013年,基于传统虚拟化技术的资源提供方式开始建立的2015年7月,成立了完整的集群管理和调度系统——HULK,目标是推进美团评价服务的容器化。 2016年,基于Kubernetes实现了基于Docker容器技术的自主灵活伸缩能力、提高交货速度、满足快速扩展需求、实现灵活扩展、缩小、提高资源利用率、提高业务运营效率、合理有效降低企业IT运营成本的2018年
美团评估集群管理与调度平台演进
最初,美团通过基于Docker容器技术的自主研究,实现了灵活的伸缩能力。 主要是基于虚拟化技术的管理和部署机制解决了快速扩展和缩小服务需求时存在的许多不足。 例如,资源实例创建速度慢、运行环境不统一、实例部署和交付过程长、资源回收效率低、灵活性低等。 通过调查和测试,结合行业的实践经验,我们基于Docker容器技术研究了集群管理和调度系统,决定有效应对快速扩大容量的需求,提高资源利用效率。 我们称之为“绿巨人”。 ——HULK,这个阶段可以认为是HULK1.0。
之后,在生产环境中反复摸索和尝试,我们认识到仅仅满足集群的灵活伸缩能力是不够的,成本和效率一定会面临未来,是一个更为棘手的问题。 我们吸取了两年的HULK 1.0开发和运营经验,在体系结构和支持系统层面进一步优化和改进,以生态和开源的力量赋予HULK能力,引进开源的集群管理和调度系统Kubernetes 因此,我们从研究平台转向开源kuberetes系统,基于kuberetes系统构建了更智能的集群管理和调度系统——HULK2.0。
架构列表
在体系结构层面,HULK2.0如何与上层业务和下层Kubernetes平台达成更好的层次和解是设计中首先考虑的问题。 我们希望它对业务友好,能够最大限度地发挥Kubernetes的调度能力,业务层和使用者不必在意资源关系的详细情况,在获得的同时,与基于发行、配置、计费、负荷等逻辑层的kuberetes平台进行非结合分层 因此,符合统一、主流和行业规范的标准可以解决美团评估基础架构面临的复杂、多样和不统一的管理需求。
架构介绍
HULK2.0模式图
从上面看,美团的集群管理和调度平台面向公司整体服务,分为主要业务线、统一的OPS平台和门户平台,HULK应按平台定制界面和解决方案 需要抽象地收敛各种业务和需求,最终通过HULK API切断HULK系统的详细情况,解除HULK和上层业务方的结合。 HULK API是业务层和资源需求的抽象化,是从外部访问HULK的唯一方法。
解决上层问题后,让我们看一下与下层Kubernetes平台的解耦。 HULK收到上层资源请求后,首先进行一系列初始化工作,进行参数检查、资源馀量、IP和主机名称分配等,然后向kuberetes平台实际申请机械资源分配,最终向用户提供资源,Kubernetes API Kubernetes API旨在收敛HULK的资源管理逻辑并将其与业界主流对齐。 另外,由于与Kubernetes API完全兼容,可以借助社区和生态的力量,共同进行建设和探索。
HULK API和Kubernetes API将我们的整个系统分成三个层,可以看出每个层都可以集中在各自的模块上。
Kubernetes的管理与实践
为什么选择Kubernetes? kuberetes不是市场上唯一的群集管理平台(如Docker Swarm和Mesos ),因此它们的体系结构设计非常出色,而且不仅重视kuberetes提供的解决方案,还重视平台和能力。 这种能力我们可以根据美团评价的实际情况来扩展,同时依赖于多年的技术积累,可以给予更多的选择。 例如,我们可以动态扩展应用程序以实现更好的资源分配策略而不面对传统平台的风险。
HULK-Kubernetes模式图
Kubernetes集群作为整个HULK集群的资源管理和平台的基础,需要稳定性和可扩展性、风险控制性和集群吞吐量能力。
集群运营现状
群集规模: 10万+级别的在线实例、多区域部署和快速增长。 业务监视警告:群集收集应用程序的启动和状态数据,container-init自动整合业务监视信息,使业务流程能够插拔和配置,而不会受到关注。 资源健康警告:从资源的角度监视和收集节点、Pod、Container等重要数据,及时发现这些状态信息。 例如,节点不可用,容器继续重新启动。 定时巡逻和会计:每天自动对所有宿主机进行状态检查,同步检查AppKey扩展数据和实际Pod和容器数据,包括剩馀磁盘量(数据卷)、d过程数、宿主机状态等,发现不一致的情况。 集群数据可视化提供了接口化的服务配置、主机离线和Pod迁移操作入口,包括当前集群状态、宿主机资源状态、服务数量、Pod数量、容器化率、服务状态和扩展容量数据等。 容量规划和预测:预感集群资源状态,根据预备资源的规则和机器学习方式感知流量和峰值,保证业务正常、稳定、高效运行。 Kubernetes的优化与改造
kube-scheduler性能优化
我们有一个群集使用的是1.6版本的调度程序,随着群集规模的增加,较旧版本的Kubernetes调度程序(1.10或更早版本)的性能和稳定性问题被强调出来,并且由于调度程序吞吐量较低而导致业务扩展失败 Kubernetes调度器是排队的调度器模型,如果扩展峰值等待的Pod数量过多,则后续Pod的扩展超时。 因此,我们大幅度优化了调度程序的性能,取得了很明显的提高,根据我们实际生产环境的验证,性能比优化的前提提提高了400%以上。
Kubernetes调度程序的工作模式如下
kube -排程器影像
(来自kubernetes调度程序和网络的图像)
预赛失败中断机制
在确定一个节点是否可以充当目标计算机时,一个调度过程主要分为三个阶段
备用阶段:硬件条件、筛选不满足条件的节点的过程称为Predicates。 这是固定优先顺序的一系列过滤条件,如果任何Predicate不符合,则放弃该Node。 优选阶段:软条件,通过的节点按优先顺序排列,称为优先级。 所有优先级都是影响因素,具有一定的权重。 选择阶段:从优先级列表中选择优先级最高的节点,称为选择。 选定的节点是最终部署Pod的计算机。
kube-scheduler调度程序
通过详细分析调度过程,调度器能够连续确定后续的过滤条件是否匹配,即使该调度器知道当前节点不适合于预先确定的过滤条件。 如果您有数万个节点,请考虑这些判断逻辑会浪费大量的计算时间。 这也是调度程序性能下降的重要因素之一。
因此,提出了一种“预选失败中断机制”,即如果不满足某个预选条件,就会立即丢弃,之后的预选条件不再进行判断计算,计算量大幅减少,日程性能也大幅提高。 如下图所示
kube-scheduler的Predicates流程
此优化为Kubernetes社区做出了贡献(请参阅PR ),添加了alwaysCheckAllPredicates策略选项,并开始在Kubernetes版本1.10中作为默认调度策略发布。 当然,也可以通过设置alwaysscheckallipredicates = true来使用原始调度策略。
在实际测试中,调度程序至少可以提高40%的性能。 如果您当前使用的Kube-scheduler版本小于1.10,建议您升级到新版本。
局部最优解
对于优化问题,特别是对于优化问题,我们总是希望寻找全局优化解和策略,但是如果问题太复杂,需要考虑的因素和处理的信息量太多,就倾向于接受局部优化解。 局部最优解的质量不一定差。 特别是在我们有决定的评价基准的时候,如果能够接受已经明确的解答的话,大多会得到局部最佳的结果。 正因如此,从成本、效率等多方面来考虑,才是我们在实际工程中应该采取的战略。
kube-scheduler的局部最优解
(从网络获取图像)
在当前的调度策略中,调度器遍历调度区域中的所有节点,并找到称为BestFit算法的最佳节点。 在生产环境中,我们究竟是选择最佳节点还是辅助节点,实际上并没有太大差异或影响,有时会避免选择最佳节点(例如,我们的集群在解决了新在线机器后,常常在该机器上创建应用程序 也就是说,可以通过找到局部最优解来满足需求。
假定集群共有1000个节点,一次调度进程PodA,其中700个节点能够通过Predicates (预处理),则在所有节点中巡回找到700个节点,并通过评分排名进行最佳节点NodeX 然而,如果发现n个节点并且在这n个节点中选择得分最高的节点,那么采用局部优化算法认为能够满足需求,例如,如果发现100个节点能够默认通过Predicates (预处理阶段),则优化解决方案可以包括 当然,这100个节点中可能没有全局最佳解NodeX,但您可以在这100个节点中选择最佳的NodeY。 最佳情况是通过在100个节点之间查找100个节点,或者在200或300个节点之间查找,显着缩短计算时间,避免对计划结果产生重大影响。
局部最佳策略是与社区合作完成的,包括如何实现公平调度和计算任务优化的细节(请参见PR1、PR2)。 此优化在Kubernetes 1.12发行版中公布,作为当前的默认调度策略,调度性能特别是在大型群集中得到了显着改进,效果非常明显。
库贝托改造
风险控制性
如上所述,稳定性和风险控制性对于大集群管理非常重要。 从组织上看,我们知道Kubelet是与实际业务最接近的群集管理组件,而且社区版本的Kubelet对本地资源管理具有很大的自主性。 如果一个业务正在运行,并且Kubelet因为启动了驱逐战略而杀死了这个业务的容器,那么这在我们的集群中是不可能发生的,所以必须收敛和阻止事件的自我决定能力。 此机器对业务集装箱的所有操作都必须从上层平台开始。
容器重新启动策略
内核升级是一项日常运输工作,如果通过重新启动宿主机来升级内核版本,则由于宿主机重新启动后,上面的容器不能恢复,或者自我恢复后的版本不正确,导致业务不满 然后,我们为Kubelet添加重新启动策略( Reuse ),同时保留原始重新启动策略( Rebuild ),以确保容器系统和数据盘信息可以保留,并且确保容器在宿主机重新启动后仍然可以被恢复
维护IP状态
根据美团评价的网络环境,我们自己开发了CNI插件,根据Pod固有的标志申请IP,并进行了多路复用。 在Pod迁移和容器重新启动后,IP仍然可用,为业务在线和运输带来了许多好处。
限制驱逐政策
事件知道节点有自动修复的能力。 例如,如果发现异常或不合格的容器,然后将它们放弃并删除,那么对我们来说风险太大,允许容器因为某些次要因素而变得不合格。 例如,如果Kubelet发现当前主机上的容器数量大于设置的最大容器数量,则可能会放弃或删除特定容器,但通常并不容易,但是您还需要进行控制以减少这种风险。
可扩展性
资源调配
在Kubelet可扩展性方面,提高了资源可用性,例如绑定容器的Numa以提高应用程序的稳定性。根据应用程序级别,在容器中设置CPUShare,调整调度权重,在容器中设置CPUSet等
扩展容器
我们通过业务,加强了容器的配置能力,在支持业务向自己的容器扩展ulimit、io limit、pid limit、swap等参数的同时,也加强了容器之间的隔离能力。
适用于当场的升级
Kubernetes知道,只要默认情况下Pod的重要信息发生变更,开始Pod的重建和交换就会在生产环境中成本高,IP和主机名发生变化,而频繁的重建也会给集群管理带来很多压力,调度可能不成功 为了解决这个问题,我们可以通过从上而下的应用程序升级功能动态有效地修改应用程序信息并随时(宿主机)进行升级。
镜像分发
镜像分发是影响容器扩展时间的重要环节,我们采用一系列手段进行优化,确保镜像分发有效、稳定
站点间同步-确保服务器始终从附近的镜像仓库中提取扩展镜像,缩短抽取时间并降低站点间带宽消耗。 基本镜像事前分发:美团评价的基本镜像是构筑业务镜像的共通镜像。 业务镜像层是业务的应用程序代码,通常远小于基镜像。 扩展容器时,如果基镜已经位于本地,则只需抽取一些业务镜像,即可显着提高扩展速度。 为了达到这种效果,请将基镜分发给所有服务器。 P2P镜像分发:预分发基本镜像可以在多个场景中同时从镜像仓库中提取数千台服务器的镜像,从而给镜像仓库的服务和带宽带来巨大压力。 因此,我们开发镜像P2P分发的功能,服务器不仅能从镜像仓库抽取镜像,还能从其他服务器取得镜像的片。 资源管理与优化
资源管理与优化
优化关键技术
服务图像:了解应用程序特征、资源规范和类型以及应用程序CPU、内存、网络、磁盘和网络I/O容量和负载图像在不同时间的实际使用情况,从服务角度和时间维进行相关性分析,并进行总体调度 亲和性和排他性:哪种应用结合在一起,总体计算能力较低,吞吐量较高,有一定的亲和性,相反,当应用之间存在资源竞争或相互影响时,它们之间存在互相排他性。 场景优先:美团评价的业务大多是基本稳定的场景,因此场景划分是必要的。 例如,某些业务对延迟敏感,即使在高峰时期也不允许发生大量的资源竞争。 在这种情况下,必须避免资源竞争造成的延迟,减少,保证资源充足的某种业务在某一时间段所需的CPU资源有可能突破配置的上限。 我们以CPU Set化的方式使这些业务共享这一部分资源,能够突破申请标准的机器资源限制,服务不仅能够获得更高的性能表现,还能够利用空闲资源进一步提高资源利用率。 灵活伸缩:引入流量预测、自动伸缩、基于规则的高低峰伸缩、基于机器学习的伸缩机制。 精简资源调配:根据资源共享和隔离技术(如Numa绑定、任务优先级和CPU集)调度和分配细分资源。 优化策略
调度策略的主要作用有两个方面:一是根据默认策略部署目标计算机;二是优化群集资源部署。
亲和性:与调用关系有依赖关系的应用程序,或者将哪个应用程序放在一起,总体计算能力较低,吞吐量较高的应用程序之间存在一定程度的亲和性。 我们的CPU集成利用对CPU优先构建应用的兼容性约束来补充不同CPU优先应用。 排他性:与亲和性相反,在调度时尽量分开部署主要存在竞争关系和业务干扰的应用程序。 应用优先级:应用优先级的划分为我们解决资源冲突提供了前提。 当前,当容器中发生资源竞争时,我们无法决定谁应该获得资源,一旦有了应用优先级的概念,我们就可以在调度层,限制单台主机的重要应用数量,减少单台资源竞争,提供在单台基础上解决资源竞争的可能性 根据应用程序的优先级来分配资源,以确保足够的关键应用程序资源,并且还可以运行低优先级的应用程序。 可分解性:应用程序的分解主要是为了容纳灾难,在此分为不同层次的分解。 我们提供了多种级别的分解粒度,包括宿主机、Tor、房间和Zone。 隔离和独占—这是一个特殊的应用程序,必须单独使用一台主机或虚拟机来隔离环境。 例如,搜索团队的业务。 特殊资源:特殊资源是满足特殊硬件需求的业务,如GPU、固态硬盘和特殊网卡。 在线群集优化
在线集群资源优化问题通过像离线集群一样预测资源需求不能实现非常好的效果。 由于未来需求的未知性,在线集群很难在资源配置中实现脱机集群的效果。 针对在线集群问题,我们采用了从上层调度到下层资源使用的一系列优化。
Numa绑定—主要解决业务反馈服务不稳定的问题,绑定Numa,将同一应用程序的CPU和Memory绑定到最佳的Numa节点,减少节点间访问开销,提高应用程序性能 CPU Set化:将一组功能上互补的应用程序绑定到同一组CPU,以充分利用CPU资源。 应用失误峰值:根据服务图像数据错开应用峰值,减少资源竞争和相互干扰,提高业务SLA。 重新安排:优化资源部署,以较少的资源提高业务性能和SLA;解决碎片问题,提高资源分配率。 干扰分析:根据业务监测数据指标和容器信息判断哪个容器存在异常,提升业务SLA,发现并处理异常应用。 结语
目前,我们正积极探索以下几点
在线-混合部署离线业务,进一步提高资源使用效率。 智能计划、业务流量和资源利用感知计划,以及改进的服务SLA。 高性能、强力隔离、更安全的容器技术。