高洪涛 分布式实验室
本次分享面向对Mesos与SRE感兴趣的听众。随着容器技术在国内的持续流行,关注点已经由容器技术本身向运维方面逐渐过渡,Google一直安利的SRE经验正好契合了这个时代的运维节奏,由此契合SRE概念而衍生的Mesos,Kubernete服务也持续推动着相关理念落地。当当正是在这种背景下研发并推广作业云平台,该平台借助Mesos平台打造高自动化云平台。本次分享将重点为大家带来我们是如何使用SRE中的相关理念,来保证服务稳定运行,同时助力业务快速迭代的。
本次分享包括以下主题:Elastic-Job-Cloud介绍,监控的本质:现象与来源,SLO实践,快速迭代的基石:发布系统,应对变化:配置管理与资源部署。
希望本次分享对大家有所帮助。
作业是一种应用很广泛的计算形式,它的适用领域包括在数据同步(ETL),数据分析,批量计算等方面。当当作为中型电商平台,同样也有数量可观的作业类任务。原有作业分散部署的方式造成每个团队需要花费许多精力来关心作业的稳定性。于此同时基于Google Borg系统衍生的Mesos等任务调度平台也趋于成熟。在此背景下,打造一套弹性作业云平台Elastic-Job-Cloud就成了水到渠成的事情。
Elastic-Job-Cloud的结构
Elastic-Job体系。Elastic-Job体系包括Elastic-Job-Lite与Elastic-Job-Cloud。两种作业的API基本相同,同样的作业在规模小的时候可以使用Lite部署,需要大规模部署才需要转移到Elastic-Job-Cloud中,这样就带来了部署策略的灵活性。
OpenSource
目前Elastic-Job-Cloud已经开源,且我们内部使用的版本与开源版本仅仅存在发布时间的差别。内部开发,运维中积累的经验都会反馈到新版本中,同时也积极吸收外部的先进特性。这种良性的开源模式,将保证Elastic-Job-Cloud向正确的方向迈进。
SRE是Site Reliability Engineer的简称,它是源起于国外互联网企业的一个词语或者新定义的一个职业。在传统的系统管理员模式时代这个角色我们叫运维,国外称做Operation。但是机器规模大了,单纯的使用人工手段,你就玩不转了。所以这个时候你就需要开发人员,也就是Developer加入到团队,来实现一些自动管理机器的功能,这其实就是DevOps的一种形式。很多人都认为这个概念还比较新,需要一段时间成熟。实际上按照我的经验,这其实是一个老概念。
早在90年代电信行业就引入了计算机软件来管理机器,他们使用自动化的程序来开关通讯端口,实现网络迁移等原来需要人工介入的操作。第一代被机器替代的运维人员那个时候叫话务员。本质上SRE来源于机器规模的扩张,以至于你必须从On-Call任务中分出部分精力来构建自动化服务,否则将无法通过单纯增加人力来满足运维的需求。从这点出发可以总结出来以下方法论:
SRE在一天中应有有70%的时间用于研发,如果一些On-Call的任务违反了这个原则,那么我们会希望将这些任务 变为自动化处理,减少On-Call的时间。
这条原则可以指导我们在纷繁的目标中选择那些最重要的内容。
下面我会从三个方面阐述SRE的一些实践心得。
当中国神舟飞船总设计师戚发轫老师在央视“开讲了”节目中被问及对年轻工程师有什么寄语的时候,老人语重心长的说了两个字反馈。
对于我这种被各种坑折磨过的老油条,戚老这两个字一击即中我的心坎。有多少次彻夜排查问题,结果都一无所获,就是系统的反馈机制出了问题。这就应了一句俗语,死不可怕,可怕的是不知道怎么死的。
而SRE中将反馈的概念进行了细化,将它拆分为“现象”与“来源”。
现象
问题现象一般通过监控手段获取,监控一般是白盒监控,我们使用promethus体系来打造监控体系。
如图中所示,Promethus将采集Mesos,Elastic-Job-Cloud指标数据,通过Grafana进行展示。这套体系简单灵活,同时又很稳定。这里要给promethus一个配置较好的环境,才能发挥其优势。同时采集数据时,要合理设置采集周期,有效利用系统资源。比如一个分钟级变化的指标,就不要每3秒去采集一次。
我们采集了Mesos文档中所描述的关键指标。同时由于Mesos的两级调度特性,各种状态会在Framework和Mesos中分别保留。对这种不一致性状态的监控是重中之重。
这里有一个坑就是Mesos文档中对agent的/monitor/statistics endpoint没有任何介绍,但这个endpoint是非常有用的,它其实可以采集到cgroup的信息。使用该数据可以展示每个容器的资源实时使用情况,和Mesos的资源限制指标,可以很好评估出应用的资源是否配置合理,过大还是过小。它可以代替cAdvisor的使用。
使用AlertManager做报警处理,报警指标力求做到恰到好处,我们也会定期做报警指标整理,去掉无效报警。
这个体系通了以后,我们开发了很多exporter去接入Promethus来做各种数据指标的展示。该体系大大提高了监控系统开发的效率。
来源
其实刚开始做监控的时候,我们重点建设了好多观察“现象”的组件,对“来源”甄别不足。
早期将日志接入ELK,方便问题的定位。但后来越来越觉得仅仅看日志是不能解决大部分问题的,我们需要同时查看一些监控指标。而监控指标的维度又往往不同,比如有些是从机器的角度看,有些是从任务的角度看。这就对理解一个问题造成了困难。
因为有些问题的现象往往是其他问题的来源,故我们希望通过一个屏幕能全方位呈现任务的概况,将配置数据,监控指标,日志等做统一呈现,同时以任务为维度。以点带面来探查问题的本质。
所以我们构建了任务360视图来做问题来源分析。该功能正在研发中,最终我们希望它能达到快速解决问题的能力。
SLO是服务质量目标的缩写,对SLO的定义,非常体现SRE的精神。它平衡了业务工程师和稳定工程师的关系,如果低于SLO就减少新功能发布转而提高稳定性,反之亦然。同时它也可以为保障松绑,原来我们的想法是保障体系要一味的加强,而通过SLO的设立,就可以针对不同级别的应用设立不同的保障目标。
我们实践SLO时,并没有Google做的那么深入,而是从简单的SLA做起。
SRE针对监控另个一要点就是监控指标越简单越少越好。这样才能将主要问题反馈出来。而SLA计算就属于这种银弹指标,通过它就能总体上衡量系统的稳定程度。
这里我们花了很多心思来考虑如何定义SLA。传统上SLA大部分应用在前台与用户交互的系统,而我们这种依靠cron表达式的内部系统是没有用户交互的,那该如何定义呢?我们经过研究发现,可以将cron表达式每次的事件触发当做是一次用户访问,那么整个SLA算法为 单位时间内 实际执行数量/预计执行数量。预计执行数量是通过cron表达式推导出来的,实际执行数量是通过event_trace库采集到的。
通过这样一种概念转换,我们将SLA引入到后端系统中,可以说为SLO最终达成提供了坚实的基础。
应用发布或者叫持续集成一直是SRE一项主要的工作。本质上应用发布是需要大量人员参与的,所以是On-Call类型的工作。故自动化和自助化就是该任务需要解决的核心诉求。
自动化与自助化之间,我认为后者可能更为重要一些,因为这会显著减少On-Call的时间。故我们选择了内部发布系统来做作业的发布,内部系统有比较完善的权限控制和全自助能力,这两项是我们比较看重的。这里我们做了一些改造,原来的发布系统只能发布到生产环境中的机器。由于使用Mesos,发布被它接管了。故作业云类型的应用需要发布到应用仓库中。所以我们为发布系统添加了一个新流程。
同时我们对原有的发布模式进行了改造,原来对于同一个版本应用是可以反复编译,部署的。这造成了有些团队为了部署方便,不升级版本号而修改程序并重新编译,部署。
我们重构作业云发布流程为不可变发布。由于作业云应用是发布到代码仓库,我们在代码仓库设置了规则,同一个版本只能被发布一次,这样强制要求任何变动都需要版本变化。即使是非常小的改动,如修改一个注释,都需要发布新版本。虽然会产生一些多余的版本,但对于发布的稳定性是至关重要的。因为对于一个特定的版本,如果他是可以正常部署的,我们就可以认为它在任何情况下都是可以正常部署的。
Mesos发布一个比较重要的过程就是做资源评估,每个任务需要使用多少资源是通过详细测试或基于以往运维数据而得出的。同时每台机器有20%的资源保留给一些监控Agent使用。为了可用性,整个集群会留出三分之一的空闲资源来保障故障转移。
资源利用率和可用性是一对矛盾体。我们采用对任务分级的方式来为不同的任务实施不同的保障级别。对高级别任务还会采取单独划分机器区域的方式进行隔离保护。
资源部署一开始我们觉得是比较简单的过程,只要基础运维帮我们配置好整套软硬环境就OK了。但由于提供给作业云的不一定是标准机器,那么上面安装的软件就可能非常不同,比如内核版本,JVM版本都会不太一样。虽然可以启动集群,但这样其实会带来故障定位困难,维护成本加大的问题。
为了应对这种环境问题,我们要求基础运维只提供我们要求的内核版本的操作系统,如果是已经运行过的机器,必须重装。剩下的所有的软件环境我们自己来初始化。我们使用Ansible脚本来对环境进行标准化操作,包括hostname改写,DNS信息写入,软件安装等等。尽可能保证环境的一致性。这里的要点就是能自动化操作的千万不要手动。即使当时为了快速解决问题,而先不使用脚本,后续也一定要补充好脚本。
但是新的问题也随着脚本的增加而暴露出来。比如脚本缺少幂等性,需要执行前确认当前环境状态。一些安装软件的脚本只有集群增加机器的时候才会运行,目前集群比较稳定,很少会运行这些脚本。但当需要故障转移时要用这些脚本了,它们的有效性就非常值得怀疑了。
为了应对以上问题,我们准备加入生产环境监测技术,该技术的理念来源于单元测试。我们希望脚本完全具有幂等性,可以反复之行。这样每天至少执行一次监测,保证环境中资源的正确性,同时也保证脚本的可用性。
未来我们会在自助化方面加强,满足业务快速接入,密集迭代的需求。同时在稳定性方面核心组件跨IDC部署也正在规划中。
以上就是我们实践SRE的过程。路才刚刚开始,前方不知是十里桃花还是万丈深渊,但我们会保持乐观与谨慎,积极应对各种挑战。