装箱百万奖金,第六届全国工业互联网数据创新应用大赛火热报名中! 了解详情
写点什么

美团集群调度系统 HULK 技术演进

  • 2019-09-21
  • 本文字数:4570 字

    阅读完需:约 15 分钟

美团集群调度系统HULK技术演进

一、背景

HULK 是美团的容器集群管理平台。在 HULK 之前,美团的在线服务大部分部署都是在 VM 上,在此期间,我们遇到了很大的挑战,主要包括以下两点:


  • 环境配置信息不一致:部分业务线下验证正常,但线上验证却不正常。

  • 业务扩容流程长:从申请机器、资源审核到服务部署,需要 5 分钟才能完成。


因为美团很多业务都具有明显的高低峰特性,大家一般会根据最高峰的流量情况来部署机器资源,然而在业务低峰期的时候,往往用不了那么多的资源。在这种背景下,我们希望打造一个容器集群管理平台来解决上述的痛点问题,于是 HULK 项目就应运而生了。


HULK 平台包含容器以及弹性调度系统,容器可以统一运行环境、提升交付效率,而弹性调度可以提升业务的资源利用率。在漫威里有个叫 HULK 的英雄,在情绪激动的时候会变成“绿巨人”,情绪平稳后则恢复人身,这一点跟我们容器的“弹性伸缩”特性比较相像,故取名为“HULK”。


总的来讲,美团 HULK 的演进可以分为 1.0 和 2.0 两个阶段,如下图所示:



在早期,HULK 1.0 是基于 OpenStack 演进的一个集群调度系统版本。这个阶段工作的重点是将容器和美团的基础设施进行融合,比如打通 CMDB 系统、公司内部的服务治理平台、发布平台以及监控平台等等,并验证容器在生产环境的可行性。2018 年,我们将底层的 OpenStack 升级为容器编排标准Kubernetes,然后把这个版本称之为 HULK 2.0,新版本还针对在 1.0 运营过程中遇到的一些问题,对系统专门进行了优化和打磨,主要包括以下几个方面:


  • 进一步打磨了弹性策略和调度系统。

  • 构建了一站式容器运营平台。

  • 对基础系统软件进行加强,自研内核,提升安全隔离能力。


截止发稿时,美团生产环境已经有 1 万个应用在使用容器,生产环境容器数超过 10 万。


二、HULK2.0 集群调度系统总体架构图


上图中,最上层是集群调度系统对接的各个平台,包括服务治理、发布平台、测试部署平台、CMDB 系统、监控平台等,我们将这些系统打通,业务就可以无感知地从 VM 迁移到容器中。其中:


  • 容器弹性:可以让接入的业务按需使用容器实例。

  • 服务画像:负责应用运行情况的搜集和统计,如 CPU/IO 使用、服务高峰期、上下游等信息,为弹性伸缩、调度系统提供支持。

  • 容器编排和镜像管理:负责对实例进行调度与应用实例构建。


最底层的 HULK Agent 是我们在每个 Node 上的代理程序。此前,在美团技术团队官方博客上,我们也分享过底层的镜像管理和容器运行时相关内容,参见《美团容器技术研发实践》一文。而本文将重点阐述容器编排(调度系统)和容器弹性(弹性伸缩平台),以及团队遇到的一些问题以及对应的解决方案,希望对大家能有所启发。


三、调度系统痛点、解法

3.1 业务扩缩容异常

痛点:集群运维人员排查成本较高。


为了解决这个问题,我们可以先看一下调度系统的简化版架构,如下图所示:



可以看到,一次扩缩容请求基本上会经历以下这些流程:


a. 用户或者上层系统发起扩缩容请求。


b. 扩缩容组件从策略配置中心获取对应服务的配置信息。


c. 将对应的配置信息提交到美团自研的一个 API 服务(扩展的 K8s 组件),然后 K8s 各 Master 组件就按照原生的工作流程开始 Work。


d. 当某个实例调度到具体 Node 上的时候,开始通过 IP 分配服务获取对应的 Hostname 和 IP。


e. Container-init 是一号进程,在容器内部拉起各个 Agent,然后启动应用程序。针对已经标准化接入的应用,会自动进行服务注册,从而承载流量。


而这些模块是由美团内部不同同学分别进行维护,每次遇到问题时,就需要多个同学分别核对日志信息。可想而知,这种排查问题的方式的成本会有多高。


解法:类似于分布式调用链中的 TraceId,每次扩缩容会生成一个 TaskId,我们在关键链路上进行打点的同时带上 TaskId,并按照约定的格式统一接入到美团点评日志中心,然后在可视化平台 HULK Portal 进行展示。


落地效果


  • 问题排查提效:之前排查类似问题,多人累计耗时平均需要半个小时。目前,1 个管理员通过可视化的界面即可达到分钟级定位到问题。

  • 系统瓶颈可视化:全链路上每个时段的平均耗时信息一览无遗。


3.2 业务定制化需求

痛点:每次业务的特殊配置都可能变更核心链路代码,导致整体系统的灵活性不够。


具体业务场景如下:


  • 业务希望能够去设置一些系统参数,比如开启 swap,设置 memlock、ulimit 等。

  • 环境变量配置,比如应用名、ZooKeeper 地址等。


解法:建设一体化的调度策略配置中心,通过调度策略配置中心,可定制化调度规则。



  • 实例基本配置,比如业务想给机器加 Set 化、泳道标识。

  • 实例的扩展配置:如部分业务,比如某些服务想将实例部署在包含特定硬件的宿主机,会对核心业务有 N+1 的容灾需求,并且还需要将实例部署在不同的 IDC 上。

  • 相同配置的应用可以创建一个组,将应用和组进行关联。


在策略配置中心,我们会将这些策略进行 Manifest 组装,然后转换成 Kubernetes 可识别的 YAML 文件。


落地效果:实现了平台自动化配置,运维人员得到解放。


3.3 调度策略优化


接下来,介绍一下 Kubernetes 调度器 Scheduler 的默认行为:它启动之后,会一直监听 ApiServer,通过 ApiServer 去查看未 Bind 的 Pod 列表,然后根据特定的算法和策略选出一个合适的 Node,并进行 Bind 操作。具体的调度策略分为两个阶段:Predicates 预选阶段和 Priorities 打分阶段。


Predicates 预选阶段(一堆的预选条件):PodFitsResources 检查是否有足够的资源(比如 CPU、内存)来满足一个 Pod 的运行需求,如果不满足,就直接过滤掉这个 Node。Priorities 打分阶段(一堆的优先级函数):


  • LeastRequested:CPU 和内存具有相同的权重,资源空闲比越高的节点得分越高。

  • BalancedResourcesAllocation:CPU 和内存使用率越接近的节点得分越高。


将以上优先级函数算出来的值加权平均算出来一个得分(0-10),分数越高,节点越优。


痛点一:当集群达到 3000 台规模的时候,一次 Pod 调度耗时 5s 左右(K8s 1.6 版本)。如果在预选阶段,当前 Node 不符合过滤条件,依然会判断后续的过滤条件是否符合。假设有上万台 Node 节点,这种判断逻辑便会浪费较多时间,造成调度器的性能下降。


解法:当前 Node 中,如果遇到一个预选条件不满足(比较像是短路径原则),就将这个 Node 过滤掉,大大减少了计算量,调度性能也得到大幅提升。



成效:生产环境验证,提升了 40%的性能。这个方案目前已经成为社区 1.10 版本默认的调度策略,技术细节可以参考GitHub上的PR


痛点二:资源利用率最大化和服务 SLA 保障之间的权衡。


解法:我们基于服务的行为数据构建了服务画像系统,下图是我们针对某个应用进行服务画像后的树图展现。



调度前:可以将有调用关系的 Pod 设置亲和性,竞争相同资源的 Pod 设置反亲和性,相同宿主机上最多包含 N 个核心应用。


调度后:经过上述规则调度后,在宿主机上如果依然出现了资源竞争,优先保障高优先级应用的 SLA。


3.4 重编排问题

痛点


(1)容器重启/迁移场景:


  • 容器和系统盘信息丢失。

  • 容器 IP 变更。


(2)驱逐场景:Kubelet 会自动杀死一些违例容器,但有可能是非常核心的业务。


解法


(1)容器重启/迁移场景:


  • 新增 Reuse 策略,保留原生重启策略(Rebuild)。

  • 定制化 CNI 插件,基于 Pod 标识申请和复用 IP。


(2)关闭原生的驱逐策略,通过外部组件来做决策。


四、弹性伸缩平台痛点、解法

弹性伸缩平台整体架构图如下:



注:Raptor 是美团点评内部的大监控平台,整合了CATFalcon等监控产品。


在弹性伸缩平台演进的过程中,我们主要遇到了以下 5 个问题。


4.1 多策略决策不一致


如上图所示,一个业务配置了 2 条监控策略和 1 条周期策略:


  • 监控策略:当某个指标(比如 QPS、CPU)超过阈值上限后开始扩容,低于阈值下限后开始缩容。

  • 周期策略:在某个固定的时间开始扩容,另外一个固定的时间开始缩容。


早期的设计是各条策略独自决策,扩容顺序有可能是:缩 5 台、缩 2 台、扩 10 台;也有可能是:扩 10 台、缩 5 台、缩 2 台,就会造成一些无效的扩缩行为。


解法:增加一个聚合层(或者把它称之为策略协商层),提供一些聚合策略:默认策略(多扩少缩)和权重策略(权重高的来决策扩缩行为),减少了大量的无效扩缩现象。


4.2 扩缩不幂等


如上图所示,聚合层发起具体扩缩容的时候,因之前采用的是增量扩容方式,在一些场景下会出现频繁扩缩现象。比如,原先 12 台,这个时候弹性伸缩平台告诉调度系统要扩容 8 台,在返回 TaskId 的过程中超时或保存 TaskId 失败了,这个时候弹性伸缩平台会继续发起扩容 8 台的操作,最后导致服务下有 28 台实例(不幂等)。


解法:采用按目标扩容方式,直接告诉对端,希望能扩容到 20 台,避免了短时间内的频繁扩缩容现象。


4.3 线上代码多版本


如上图所示,一个业务线上有 30 台机器,存在 3 个版本(A、B、C)。之前我们弹性扩容的做法是采用业务构建的最新镜像进行扩容,但在实际生产环境运行过程中却遇到问题,比如一些业务构建的最新镜像是用来做小流量测试的,本身的稳定性没有保障,高峰期扩容的时候会提升这个版本在线上机器中的比例,低峰期的时候又把之前稳定版本给缩容了,经过一段时间的频繁扩缩之后,最后线上遗留的实例可能都存在问题。


解法:基于约定优于配置原则,我们采用业务的稳定镜像(采用灰度发布流程将线上所有实例均覆盖过一遍的镜像,会自动标记为稳定镜像)进行扩容,这样就比较好地解决了这个问题。


4.4 资源保障问题


如上图所示,存量中有 2 个服务,一个需要扩容 20 台,一个需要扩容 15 台,这个时候如果新接入一个服务,同一时间需要扩容 30 台,但是资源池只剩余 50 台实例了。这个时候就意味着,谁先扩容谁就可以获得资源保障,后发起的请求就无法获得资源保障。


解法


(1)存量资源水位检测:当存量资源的使用水位超过阈值的时候,比如达到 80%的时候会有报警,告诉我们需要做资源补充操作。


(2)增量服务弹性资源预估:如果这个服务通过预判算法评估,接入之后可能会导致存量服务的扩容得不到保障,则拒绝或者补充资源后,再让这个业务接入。


4.5 端到端时效问题


如图所示,我们的分钟级监控时延(比如 1:00:00~1:01:00 的监控数据,大概需要到 1:01:10 后可将采集到的所有数据聚合完成)是 70s+,调度链路时延是 30s+,整体需要上 100s+,在生产环境的业务往往会比较关注扩容时延。


解法:监控系统这块已经建设秒级监控功能。基于这些做法都属于后验性扩容,存在一定的延迟性,目前我们也在探索基于历史行为数据进行服务预测,在监控指标达到扩容阈值前的 1~2 分钟进行提前扩容。


五、经验总结

技术侧


  • 开源产品“本土化”:原生的 Kubernetes 需要和内部已有的基础设施,如服务树、发布系统、服务治理平台、监控系统等做融合,才能更容易在公司内进行落地。

  • 调度决策:增量的调度均使用新策略来进行规范化,存量的可采用重调度器进行治理。

  • 弹性伸缩:公有云在弹性伸缩这块是没有 SLA 保障的,但是做内部私有云,就需要做好扩容成功率、端到端时延这两块的 SLA 保障。


业务侧


  • 业务迁移:建设了全自动化迁移平台,帮助业务从 VM 自动迁移到容器,极大地降低了因迁移而带来的人力投入。

  • 业务成本:使用 HULK 可较好地提升业务运维效率(HULK 具备资源利用率更高、弹性扩容、一键扩容等特点),降低了业务成本。


作者介绍


涂扬,美团点评技术专家,现任基础架构部弹性策略团队负责人。


本文转载自公众号美团技术团队(ID:meituantech)


原文链接


https://mp.weixin.qq.com/s/AuCQn3jdJURUi9tZLt0dlw


2019-09-21 08:001744

评论

发布
暂无评论
发现更多内容

SpringBoot官方支持任务调度框架,轻量级用起来也挺香!

沉默王二

Java springboot

一二三线互联网公司划分标准和榜单

laofo

研发效能 互联网公司 一线大厂 二线互联网 一线互联网

什么是加密?有哪些加密类型和加密算法?逆天原创神作,值得一读!

wljslmz

加密 密码学 加密算法 网络技术 6月月更

帮助中心对企业有用吗?要不要做帮助中心页面?

小炮

这本书押中了2022北京高考作文题!

博文视点Broadview

Web Service进阶(七)浅谈SOAP Webservice和RESTful Webservice

No Silver Bullet

6月月更 SOAP Webservice RESTful Webservice

面试突击55:delete、drop、truncate有什么区别?

王磊

Java 面试

GIT 常见问题

甜甜的白桃

git 版本管理 6月月更

数字货币持币生息质押理财dapp系统开发

开发微hkkf5566

C#/VB.NET 在Word中设置纯色/渐变/图片背景

在下毛毛雨

C# .net word文档 背景设置

在 Flutter 中以编程方式截取任何 Widget

坚果

6月月更

聚焦中国算力大会 | 浪潮集团肖雪: 数字化转型新场景激发算力需求

浪潮云

云计算

系统运维 SIG 直播: libbpf 编译平台 LCC——eBPF从入门到享受 | 第 20 期

OpenAnolis小助手

Linux 运维 内核 ebpf LCC

InfoQ 极客传媒 15 周年庆征文|基于ECS实现一分钟自动化部署【弹性云服务器ECS】

上进小菜猪

6月月更 InfoQ极客传媒15周年庆 弹性云服务器ECS

服务管理与通信,基础原理分析

知了一笑

Java 架构 微服务 nacos Feign

网络七层结构是干啥的? 看这篇文章就够了

郑州埃文科技

TCP/IP 网络结构 传输网络

SAS击球实验室向青少年展示数据与分析的价值

新闻科技资讯

APP前后端交互之积分篇【MUI】

上进小菜猪

mui 6月月更

使用 JavaScript 开发AR(增强现实)移动应用的预备知识和环境搭建

Jerry Wang

JavaScript AR SAP 增强现实 6月月更

Linux驱动开发_倒车影像项目介绍

DS小龙哥

6月月更

【Python技能树共建】正则表达式

梦想橡皮擦

6月月更

java培训流Stream循环遍历list

@零度

stream JAVA开发

基于 spring-cloud-k8s 跨NS坑续集

Xiao8

微服务架构 云原生 6月月更

优酷端侧弹幕穿人技术实战之:PixelAI移动端实时人像分割

阿里巴巴文娱技术

音视频 弹幕 人像 移动端 移动端开发

【LeetCode】爱吃香蕉的珂珂Java题解

Albert

LeetCode 6月月更

如何搭建短视频app源码,实现短视频内容的播放优化

开源直播系统源码

APP开发 短视频源码

spring4.1.8初始化源码学习三部曲之二:setConfigLocations方法

程序员欣宸

Java spring 6月月更

JavaScript原型链继承与盗用构造函数继承

大熊G

JavaScript 前端 6月月更

架构实战营|模块3

KDA

#架构实战营

美团集群调度系统HULK技术演进_文化 & 方法_涂扬_InfoQ精选文章