当前位置: 首页 > 科技观察

美团点评Kubernetes集群管理实践

时间:2023-03-20 01:19:07 科技观察

背景作为国内领先的生活服务平台,美团点评的多项业务都具有非常显着且有规律的“波峰”和“波谷”特征。尤其是遇到节假日或者促销活动的时候,流量也会在短时间内出现爆发式增长。这对集群中心的资源弹性和可用性有非常高的要求,同时在支撑业务流量时也会成倍增加系统的复杂度和成本。我们要做的是利用有限的资源,最大化集群的吞吐量,保证用户体验。本文将介绍美团点评Kubernetes的集群管理与使用实践,包括美团点评集群管理与调度系统介绍、Kubernetes管理与实践、Kubernetes优化与改造、资源管理与优化。美团点评集群管理与调度系统美团点评多年来一直在集群管理和资源优化的道路上前行。2013年,开始构建基于传统虚拟化技术的资源交付方式;2015年7月,开始建立完整的集群管理和调度系统——HULK,目标是推动美团点评服务容器化;2016年完成基于Docker容器的自研技术实现弹性伸缩提高交付速度和应对快速扩容需求,实现弹性扩缩容,提高资源利用率,提升业务运维效率,以及合理有效降低企业IT运维成本;2018年开始基于Kubernetes进行资源管理和调度,进一步提升资源使用效率。美团点评集群管理与调度平台演进最初,美团点评基于Docker容器技术通过自研实现弹性扩展,主要是解决基于虚拟化技术的管理部署机制在应对快速扩缩容需求时存在诸多不足.例如资源实例创建速度慢,运行环境无法统一,实例部署交付流程长,资源回收效率低,弹性差等。经过研究测试,结合实际经验面向行业,我们决定基于Docker容器技术自主研发集群管理调度系统,有效满足快速扩缩容的需求,提高资源利用效率。我们称之为“绿巨人”——HULK,这个阶段可以看作是HULK1.0。后来经过生产环境的不断摸索和实验,我们逐渐意识到仅仅满足于集群的弹性扩展是远远不够的。成本和效率肯定是我们未来面临的更棘手的问题。我们吸收了近两年HULK1.0的开发和运维经验,进一步优化完善了架构和支撑体系,借助生态和开源为HULK赋能,即引入了开源的集群管理和调度系统Kubernetes有望进一步提高集群管理和运行的效率和稳定性,同时降低资源成本。于是我们从自研平台切换到开源的Kubernetes系统,并基于Kubernetes系统构建了更加智能的集群管理和调度系统——HULK2.0。架构概览在架构层面,HULK2.0如何更好的与上层业务、下层Kubernetes平台分层解耦,是我们在设计之初的首要任务。我们期望它对业务使用友好,最大化Kubernetes的调度能力,让业务层和用户无需关注资源关系的细节,有求必应;逻辑层与底层Kubernetes平台解耦,保持兼容原生KubernetesAPI访问Kubernetes集群。这样一来,美团点评基础设施面临的复杂、多样、不统一的管理需求,就可以借助统一、主流、符合行业的标准来解决。架构介绍HULK2.0架构图自上而下,美团集群管理调度平台是面向全公司的。拥有多个主营业务线,统一的OPS平台,Portal平台。HULK不可能为每个平台定制接口和接口。解决方案,因此需要对各种服务和需求进行抽象和汇聚,最终通过HULKAPI统一屏蔽HULK系统的细节,实现HULK与上层业务端的解耦。HULKAPI是对业务层和资源需求的抽象,是外界访问HULK的唯一途径。解决了上层的问题,再来看与下层Kubernetes平台的解耦。HULK收到上层的资源请求后,首先要进行一系列初始化工作,包括参数校验、资源余量、IP和Hostname分配等,然后向Kubernetes平台申请分配机器资源,最终将资源交付给用户,KubernetesAPI进一步对资源需求进行汇聚和转化,让我们可以利用Kubernetes的资源管理优势。KubernetesAPI旨在汇聚HULK的资源管理逻辑,并与业界主流接轨。另外,由于完全兼容KubernetesAPI,我们可以借助社区和生态的力量,共同建设、共同探索。可以看到,HULKAPI和KubernetesAPI将我们整个系统分为三层,让每一层都可以专注于自己的模块。Kubernetes管理与实践为什么选择Kubernetes?Kubernetes并不是市面上唯一的集群管理平台(其他如DockerSwarm或Mesos),我们之所以选择它,除了其优秀的架构设计外,我们更看重的是Kubernetes提供的不是一个解决方案,而是一个平台和一种能力。这种能力让我们能够真正根据美团点评的实际情况进行扩展,同时能够依赖和复用多年积累的技术,给我们更多的选择自由,包括我们可以快速部署应用,而不必面对风险与传统平台相关联,动态扩展应用程序和更好的资源分配策略。HULK-Kubernetes架构图Kubernetes集群是整个HULK集群资源管理和平台的基础。需求是稳定性和可扩展性、风险可控性和集群吞吐量。集群运行状况集群规模:10万+在线实例,部署在多个地域,还在快速增长。业务监控告警:集群采集应用启动和状态数据,container-init自动整合业务监控信息,业务程序无需关注,可插拔可配置。资源健康告警:从资源的角度,监控采集Node、Pod、Container等重要数据,及时发现它们的状态信息,如Node不可用、Container重启等。每天所有主机的状态,包括剩余磁盘量(数据量)、D进程数、主机状态等,并将AppKey扩展数据与实际Pod和容器数据同步,及时发现不一致。集群数据可视化:可视化当前集群状态,包括主机资源状态、服务数量、Pod数量、容器化率、服务状态、伸缩数据等;并提供基于接口的服务配置、主机下线和Pod迁移操作入口。容量规划与预测:提前感知集群资源状态,提前准备资源;基于规则和机器学习感知流量和峰值,保障业务正常、稳定、高效运行。Kubernetes优化改造kube-scheduler性能优化我们有集群使用1.6版本的scheduler。随着集群规模的不断增长,旧版本Kubernetes调度器(1.10之前)的性能和稳定性问题逐渐凸显。由于调度器吞吐量低,导致业务扩展超时失败。在近3000台机器规模的集群上,调度一个Pod大约需要5秒。Kubernetes的调度器是一个队列调度器模型。一旦等待扩容高峰的Pod过多,后续Pod的扩容就会超时。为此,我们对调度器的性能进行了极大的优化,取得了非常显着的提升。根据我们实际生产环境验证,性能较优化前提升了400%以上。Kubernetes调度器的工作模型如下:kube-scheduler示意图(kubernetes调度器,图片来自网络)预选失败中断机制判断一个Node是否可以调度的过程主要分为三个阶段用作目标机:预选阶段:hardConditions,过滤掉不满足条件的节点,这个过程称为Predicates。这是一系列固定顺序的过滤条件。如果任何Predicate不匹配,则该Node将被丢弃。优化阶段:软条件,根据优先级对通过的节点进行排序,称为Priorities。每个Priority都是一个影响因素,具有一定的权重。Selected阶段:从preferred列表中选择优先级最高的节点,称为Select。选择的Node就是最终部署Pod的机器。通过深入分析调度过程,可以发现kube-scheduler的调度过程。即使调度器在预选阶段知道当前Node不满足某个过滤条件,也会继续判断是否满足后续的过滤条件。试想一下,如果有几万个Node节点,这些判断逻辑会浪费大量的计算时间,这也是造成调度器性能低下的一个重要因素。为此,我们提出一种“预选失败中断机制”,即一旦某个预选条件不满足,该Node将立即被放弃,后面的预选条件将不再进行判断和计??算,从而大大降低了计算量和调度性能。巨大的改进。如下图所示:kube-scheduler的Predicates进程我们把这个优化贡献给了Kubernetes社区(详见PR),增加了alwaysCheckAllPredicates策略选项,并在Kubernetes1.10版本发布并开始使用它作为默认调度策略。当然你也可以通过设置alwaysCheckAllPredicates=true来使用原来的调度策略。在实际测试中,调度器至少可以提升40%的性能。如果您当前使用的Kube-scheduler版本低于1.10,建议您尝试升级到新版本。局部最优解对于优化问题,尤其是优化问题,我们总是希望找到全局最优解或策略,但是当问题的复杂度太高,需要考虑的因素太多,需要处理的信息量太大时,我们倾向于倾向于接受局部最优解更好,因为局部最优解的质量不一定不好。特别是当我们有明确的判断标准,同时表明所得到的解是可以接受的时候,我们通常会接受局部最优结果。这样,从成本、效率等多方面考虑,才是我们在实际工程中真正会采用的策略。kube-scheduler的局部最优解(图片来自网络)在目前的调度策略中,调度器每次调度时都会遍历集群中的所有Nodes,寻找最优节点,称为BestFit算法调度字段。但是在生产环境中,我们选择最优Node还是次优Node,并没有特别大的区别和影响。有时候我们还是会避免选择最优的Node(比如我们的集群经常使用在本机上创建应用的问题随机化最优解)。换句话说,找到一个局部最优就可以满足要求。假设集群一共有1000个Node,有一个调度进程PodA,其中700个Node可以通过Predicates(预选阶段),那么我们遍历所有的Node,找出这700个Node,然后通过打分最好的Node节点NodeX。但是这里使用的是局部最优算法,即我们认为只要能找到N个Node,并在N个Node中选出得分最高的Node,就可以满足需求。例如,默认情况下,可以找到100个可以通过Predicates(预选阶段)的节点。即在这100个节点中选出最优解。当然,全局最优解NodeX不一定在这100个Node中,但是我们也可以通过在这100个Node中选择最优的NodeY来满足要求。最好的情况是遍历100个Node就找出这100个Node,也可能遍历200、300个Node等等,这样我们可以大大减少计算时间,同时又不会有太大的影响对我们调度结果的影响。局部最优策略是我们与社区合作完成的,其中也涉及到如何实现公平调度和计算任务优化的细节(详见PR1、PR2)。这个优化是在Kubernetes1.12版本发布的,作为当前默认的调度策略,可以极大的提升调度性能,尤其是在大规模集群中,效果非常明显。Kubelet改造风控可控前面提到,稳定性和风控对于大规模集群管理来说非常重要。从架构的角度来看,Kubelet是最接近真实业务的集群管理组件。我们知道,社区版的Kubelet在管理本地资源方面有很大的自主权。试想一下,如果一个业务正在运行,但是Kubelet发起了一个驱逐策略,而这个业务的容器被杀死了会怎样?这在我们的集群中是不应该发生的,所以需要收敛和阻断Kubelet的自主决策能力。它对本机业务容器的操作应该从上层平台发起。容器重启策略内核升级是日常运维操作。在通过重启宿主机升级Kernel版本的时候,我们发现宿主机重启后,上面的容器无法自愈或者自愈后版本不对,会引起业务的不满,也给我们造成了很大的困扰运维压力。后来,我们在Kubelet中加入了重启策略(Reuse),同时保留了原有的重启策略(Rebuild),保证容器系统盘和数据盘上的信息可以保留下来,并且容器在重启后也可以自愈主机重启。IP状态维护根据美团点评的网络环境,我们开发了CNI插件,根据Pod的唯一标识申请和复用IP。应用IP在Pod迁移和容器重启后可以复用,为业务上线和运维带来很多好处。限制驱逐策略我们知道,Kubelet具有自动修复节点的能力,比如在发现异常容器或不合规的容器后,将其驱逐删除。这对我们来说太冒险了。方面可能不合规。例如,当Kubelet发现当前主机上的容器数量大于设置的最大容器数量时,它会选择驱逐和删除部分容器。虽然这个问题一般情况下不容易出现,但是我们也需要对此进行控制,以降低此类风险。可扩展性资源分配在Kubelet可扩展性方面,我们增强了资源的可操作性,比如为容器绑定Numa,提高应用稳定性;根据应用级别为容器设置CPUShare,调整调度权重;容器CPUSet等的绑定。增强容器,我们开放并增强了业务配置容器的能力,支持业务为自己的容器扩展ulimit、iolimit、pidlimit、swap等参数,也增强了与业务之间的隔离容器。大家都知道,应用就地升级。默认情况下,只要Pod的关键信息发生变化,比如镜像信息,Kubernetes就会开始重建和替换Pod。这在生产环境中是非常昂贵的。一方面,IP和HostName会发生变化,另一方面,频繁的rebuild也给集群管理带来了更大的压力,甚至可能导致无法调度成功。为了解决这个问题,我们开放了自上而下的应用就地升级功能,即可以动态高效的修改应用信息,进行就地(主机)升级。镜像分发镜像分发是影响容器扩容时长的重要环节。我们采取了一系列的优化措施来保证镜像分发的高效和稳定:跨站同步:保证服务器始终可以从最近的镜像仓库拉取扩容镜像减少拉取时间和跨站带宽消耗.基础形象预配:美团-大众点评基础形象是用于构建商家形象的公共形象。业务镜像层是业务的应用代码,通常比基础镜像小很多。容器扩容时,如果基础镜像已经在本地,只需要拉取部分业务镜像,可以显着加快扩容速度。为了达到这个效果,我们会提前将基础镜像分发到所有的服务器上。P2P镜像分发:在某些场景下,基础镜像的预分发会导致上千台服务器同时从镜像仓库拉取镜像,对镜像仓库服务和带宽造成很大压力。为此,我们开发了镜像P2P分发功能。服务器不仅可以从镜像仓库拉取镜像,还可以从其他服务器获取镜像的碎片。资源管理与优化资源管理与优化关键技术服务画像:对应用的CPU、内存、网络、磁盘和网络I/O容量和负载进行画像,了解应用的特性、资源规格和应用类型及其影响对资源在不同时间的真实使用情况,再从服务角度和时间维度进行关联分析,从而进行整体调度和部署优化。亲和性和互斥性:哪些应用放在一起整体算力较小,吞吐量较高,具有一定的亲和性;相反,如果应用程序之间存在资源竞争或相互影响,则它们之间存在一定的亲和力。相互排斥是存在的。场景优先:美团点评的大部分业务基本都是稳定的场景,所以需要进行场景划分。比如一类业务对延迟非常敏感,即使在高峰期,也不允许过多的资源竞争。在这种场景下,必须避免和减少资源竞争导致的延迟,以保证资源充足;CPU资源可能超过配置上限。我们通过CPUSet方式共享这部分资源,从而突破应用规范的机器资源限制。不仅服务可以获得更高的性能,闲置的资源也得到了利用,进一步提高了资源利用率。弹性伸缩:应用部署实现流量预测、自动伸缩、基于规则的高低峰值伸缩、基于机器学习的伸缩机制。精细化资源分配:基于资源共享和隔离技术,实现精细化的资源调度和分配,如Numa绑定、任务优先级、CPUSet等。策略优化调度策略的主要作用有两个方面,一个是根据既定策略部署目标机;二是实现集群资源的优化配置。亲和性:具有调用关系和依赖关系的应用之间存在一定的亲和性,或者说哪些应用放在一起可以使整体的计算能力更小,吞吐量更高。我们的CPUSet就是利用CPU偏好的亲和性约束来构建应用,让不同CPU偏好的应用可以互补。互斥:相对于亲和性,主要是指有竞争或业务干扰的应用在调度时尽量分开部署。应用优先级:应用优先级的划分为我们解决资源竞争提供了前提。目前,当容器之间存在资源竞争时,我们无法决定谁应该获得资源。有了应用优先级的概念,我们可以在调度层限制单台主机上重要应用的数量,减少单机的资源竞争,也为单机底层解决资源竞争提供了可能;在宿主机层,按照应用的优先级进行资源分配,保证重要应用的资源充足,低优先级的应用也可以同时运行。分散:应用的分片主要是为了容灾,分为不同层次的分片。我们提供不同级别的粒度,包括主机、Tor、机房、区域等。隔离性和排他性:这是一种特殊类型的应用程序,必须在隔离环境中使用主机或虚拟机独立部署,例如业务搜索团队的成员。特殊资源:特殊资源是为了满足某些业务对GPU、SSD、特殊网卡的特殊硬件需求。在线集群优化在线集群资源的优化不像离线集群那样,通过预测资源需求可以达到很好的效果。由于未来需求未知,在线集群在资源安排上很难达到离线集群的效果。针对在线集群的问题,我们采取了从上层调度到下层资源使用的一系列优化。Numa绑定:主要解决业务端反馈服务不稳定的问题。通过绑定Numa,将同一应用的CPU和Memory绑定到最合适的NumaNode上,减少跨Node访问的开销,提升应用性能。CPUSet:将一组功能互补的应用绑定到同一组CPU上,使它们可以充分利用CPU资源。应用错峰:基于业务画像数据,错峰应用,减少资源竞争和相互干扰,提升业务SLA。重新调度:优化资源分配,使用更少的资源来提高业务绩效和SLA;解决碎片化问题,提高资源配置率。干扰分析:根据业务监控数据指标和容器信息判断哪些容器异常,提升业务SLA,发现并处理异常应用。结论目前,我们正在积极探索以下几个方面:线上线下服务混合部署,进一步提高资源利用效率。智能调度,服务流和资源使用感知调度,提升服务SLA。高性能、强隔离、更安全的容器技术。作者简介郭亮是美团点评基础研发平台集群调度中心高级工程师。