@gaoxiaoyunwei2017
2018-04-23T13:34:21.000000Z
字数 7722
阅读 580
北哥
杨利东
- 腾讯QQ平台运维负责人
分享一个老生常谈而又古老的话题---自动化运维。腾讯织云的自动化体系包含了非常非常多的内容,上图可见。我的同仁对织云的内容进行过分享的,如组件、基础运维、架构、调度、监控、AI、算法等方方面面的内容。
我要分享的是红色框框的部分内容。像包管理,我会给大家讲解我们的包是什么,不是LV,也不是爱马仕。还会分享一下业务CMDB配置管理和自动化流程。在这过程中会给大家分享下我们遇到的坑,和我们的想法以及经验,希望能给大家带来一些灵感和触动,我的目的就达到了。
我做了很多年的运维工作,以前做过农牧场运维,也做过广告业务运维,现在主要是负责QQ的密码、资料、关系链的运维工作。上面是我所要分享的三大块内容。
在迅猛发展的情况下,大家可能会遇到各种问题,发展过程中运维承担着很大的压力。比如说研发团队成长非常快,很快招了很多研发,这个需求就相应的变得非常多还急需,而且他们不一定采用同样的框架,以及自己的编码习惯和组件可能也不一样。作为运维人员,可能通过某些手段说服了老板给你加人,新招了两个运维小弟,发现这两个运维小弟能力上可能不一样。在日常的沟通交流和脚本管理开发上肯定会受到影响,因为大家对技术点、脚本、架构理解肯定是不一样的。包括现在很多人员会涉及到出差、工作交接和离职。最后可能又花一点精力把老板说服了,做运维优化,从业界选择了很多大名鼎鼎的运维方案,但是又可能不一定推得动,可能研发人员不配合,想法虽好落地困难。
先吹两个牛,第一个是全民晒照片,全民18岁,短时间图片上传量达到平日晚高峰的4倍,我们几小时扩容上千台设备。第二个是QQ红包,两周内我们大概搞定800个模块接近3万设备的上线,用来支持春节红包的活动。
在讲包管理和运维方案之前,要讲一下研发组织结构。一个公司自从诞生之日起,一定是研发同学把环境部署好,基本上该做的东西做完了,老板说兼任运维兼不动了,需要招专门的运维了,这时你才被招进来填坑的。
我们对应什么样的组织结构下容易用什么方案解决?
当我们面对人员方面的问题,首先要有一个概念和指导思想,整个方案的优化过程一定是渐进型的,不是一下就能一步到位的。又轻松、又低成本、又节约时间、又能搞得定的方案是没有的。
大家看一下我们的过程,第一步是做包管理,后面随着设备的增加我们做了SPP框架组件,然后做了名字服务、调度能力,后面做了CMDB资源、镜像、条带化、自动化流程,最后做了数据银行、智能运维。这是模块化的交付过程,比较契合企业的发展状况。一下把AI的运维方案交给一个只有10台服务器的公司有用吗?没有用的。有人问我,我们公司应该怎么做?我说要根据具体情况来,不要说哪个火哪个潮流就用哪个,这是没有用的。
当有非常多的开发天天来问你重启命令、操作和维护等等这些问题的时候,会让你非常头大,这些问题非常简单,会让运维陷入到重复性劳动而又没有什么价值的工作中。
我们的包管理系统就是为了解决上述问题,这是运维必须要承担的,又特别不容易有产出的一种工作,也是最麻烦的一件事情。当时想到是统一研发框架,像谷歌这样的公司已经有这样的开源的方案了。对于我们多中心型的团队,搞定一个团队就不容易,搞定多个团队更加困难,开发同学忙于自己的业务。
后来我们就想到了统一管理框架。做这个事情的出发点是为了优化运维管理,其目的是管理,千万不要过度的让开发去改底层代码,这是不太现实的。因此我们就把文件目录和脚本功能进行梳理。
这是梳理后的效果图。那么包到底是什么呢?我给包做了一个简单概念,包就是为了完成一组特定功能的文件的集合。根据包的功能的不同,列出目录的规划,比如Admin做功能上的重启、清理文件,Conf是配置文件,Log是日值文件,Client是插件。这样的一种把文件规范划分的做法,让所有的包看起来都长得差不多。这听起来很简单,实际情况远远不止这样,请往下看。
文件管理
把前面划分完之后我们就采到坑了,当时负责广告运维,这是一个现金流的业务,分分钟就多少钱,我要删除IP,点了一个删除,结果发现所有IP都删了。后来想装上去就可以了,但是老板发现了,装上去流量没有用,然后就找开发看看,发现丢了一个软链。当时目录下面有一个软链接文件,他不想改代码,我把这个软链给链上就正常了。这一点点后置脚本功能就能帮我解决大问题。
还有一个大坑就是公共文件。多个程序一定会访问同一个文件,我们现在就遇到,QQ空间有一个公共文件达到上千行的配置,为了管理这个公共文件我们还做了开发系统,做了各种锁,总之非常复杂,在这种情况下还经常出事故。所以如果大家用“包”的思想管理程序,遇到这种公共文件,一定要把归属自己包的划分出来,千万不要混在一起,对涉及到多人编辑的情况下一定会出问题。因此,公共文件一定要拆。
进程管理
遇到问题整天要启动、停止,包一定具备了进程启停的功能。只要带参数就可以启动,但是我们这边做了一个限制,“停止”就是默认不让你编辑,因为我们的停止使用了自动化的方法。这种东西经常带来误杀,会把其它进行误杀掉,鉴于此就做了这样的一种模式。
我们有一个进程自监控的功能,对于有死机或者业务进程收到了不正常的请求,进程被挂掉了,就需要自启动功能。
我们怎么做的呢?现网每3分钟PS一下,去找这个包里面的进程有没有在,如果它在就自然什么都做了,如果不在,就需要在标记位里问一下,如果标记位允许它在,就要做拉起,失败则告警。如果它不在,标记位也不在,那就什么也不做了。
为什么会有“标记位”这个东西存在呢?懂架构的人知道,这是一个非常复杂的,为了维护这个标记位,我们做了几十的版本,各种加锁和各种保护在里面。产生这个东西是因为产品决定的,包在用户用的时候有一种需求是安装完了并不启动,可能依赖一些其他文件或者其他的环境,我还没有准备好,启动的时候也启动不了,每次都会报错,因此就不启动了。
我们有一个“安装后是否启动”的标签,如果不希望启动,你把这个拉起了,用户期望以外的事情就发生了,这是不允许的。所以我们做了这个“标记位”,在启动的时候才显示,如果不启动就不写这个。
版本管理
产品的迭代是非常非常频繁的。这个例子里面有100多个版本,版本管理我们是怎么做的?版本之间的区别是通过描述进行的。听起来很专业,一旦描述错了怎么办?我们有办法。
这里有三个问题:
1. 存储1000个包,100个版本,存下来就是9.5T。
2. 100个IP版本升级,那么传输消耗是12000M还是2000M?
3. 如果上面升级出问题了,我们赶紧回馈,这时候回馈的网络传输消耗是多少?
这是我们的方案。调用Diff函数来进行下载,缓存的仅仅是变化了的文件,也就是不同的文件,速度非常快。我们这里有4万多个包,60多万个版本,包存量3T。
文件级diff到底是怎么回事?左边的图是织云包,右边的图是镜像包。通过织云包,这是一个传输方法,用镜像包就是diff,从第二个版本到第三个版本,只需要传输4和5就好了。如果1和2特别大,又涉及到需要传输的特别多,整个用户体验升级的过程和消耗的时间就会非常慢。我们的包管理非常轻量、非常敏捷,它的技术实际上就是图上这样的。
我们的版本回滚也非常快。在升级的时候,把diff内容放到了本地磁盘。如果你要回滚,从本地磁盘直接对本地磁盘传输,网络消耗是零,它不需要变化。我们整个包的版本管理和存储一切都是增量,包括存、下载、回滚全部都是增量。
我们包操作任务一天有2万多次,非常频繁,每次耗时10-20秒,耗时非常少,成功率可到4个9也非常高。通过这么多年的版本迭代解决了非常多的问题。
实例管理
实例就是让你非常清楚的知道现网每个IP到底是哪个程序、哪个版本。我们这里针对实例做了一些防呆设计和排序。这里讲两个:
实例管理没有那么简单,每一个IP看起来都很爽,其实没有这么简单。这里我们有1.0、1.1、1.2、1.3这四个版本。这个在现网上确实存在的。这里有几个问题:
我们允许多版本存在。互联网非常敏捷,需要快速得到用户的数据和反馈,因此我们用了金丝雀发布,当然还有灰度发布和蓝绿部署,后面的方法不太常用。我们允许金丝雀发布和灰度发布,至少有两个版本,要不然做不起来。
第一个图全是1.0,A开发在灰度中,B开发夹带1.1版本的特性灰度后全量发布。
经常做发布的同学应该会遇到,这也是我们经常遇到的一个问题。它的原因比较简单,但是引发的后果比较严重,经常有人跑过来问我怎么办,我们同学又把版本夹带出去了。我说别紧张,给你提需求,凡是灰度发IP的时候都给我发一个邮件,也告诉B同学,有版本在发了,你还没有灰度完,还剩几个IP,当到第四个IP的时候到哪里,我说这没有用,发到满邮箱都是邮件也没有用,我来出一个主意,就是约束。
一个集群下最多存在两个版本。金丝雀发布是需要的,我做一个约束,最多出现两个版本,不需要出现第三个版本,其实就是两个原配不允许第三者插足,当两个原配单身的时候就可以了。当你有1.0和1.1的时候,1.2想发布都发布不出去,要么把1.0全升级成1.1,要么把1.1回滚到1.0。
除了版本夹带的问题,还有一个是帮助运维非常方便的选择扩容版本。其实扩容版本就是正式版本,灰度版本也是正式版本,帮助客户决定哪个是正式版本。我们选择比例大于50%的版本。为什么选择比例大于50%的版本呢?
这里写了一堆文字描述。其实就是大家的选择。选新的时候,问题可能会放大,如果选旧的版本,新版本灰度很久了,你还放旧的版本,这时候用户体验不太好。还有一个是人工定义,每次发布的时候都让权威人士或者领导审批,让他定义哪个是正式版,这个也行,但是效率太低了,多中心团队那么多产品要发,怎么做这个。如果你的产品就是一个传统企业,审批流非常严格,半个月一审批,一个月另外一个审批,下下个月另外的审批,那就不存在这个问题。
发布管理
在发布管理上我们面临版本迭代频繁、回滚紧急、规模巨大、文件众多的问题。前面讲过我们怎么做到非常快、非常轻量的应对这些挑战。
谁来发布的问题,我们的发布是全民发布,产品、开发和测试,这里谁发现需求谁来变更,这个效率是最高的。我们有一系列办法、约束条件去让这些开发、产品和测试能够很好的用我们这套发布系统,这里有收益和风险并存。
既然是全民发布,那么多人都在发,很可能是同一批目标机器,而且复杂业务上下游关联性特别强,你发完觉得正常,但是上游不正常了,所以变更非常重要,因为需要快速捕捉有谁在那个时间点在做变更。按照我的经验,如果你的业务出问题了,一定有人变更,只是变更对象不一样。比如说掉电了,可能在电力调整,如果你能把这些数据采集上来,那也很牛。如果光纤被挖断了,变更对象是大地,你的业务也就受影响了,或者你的支撑部门、操作系统变更,总之一定要有变更。
我们这边做了一个变更日志,一旦出问题马上来看,告警出现之后对应的时间点,选业务,把时间再一选,八九不离十,一定是他,抵赖也没有用。
发布管理中还面临一个问题,金丝雀发布的节奏和时间怎样强制?
对于上述问题,现在处于半解决状态。我们经常说为了安全一定要灰度,时间上,下班了不要发,半夜不要发,但是有时候他发了你也没有办法。现在要强制他,一种要制度加强,二是秋后算帐,没有采取很强硬的手段。我们采用了一个半强硬的手段,叫做“发布计划”,将来把要发布的内容,比如你要发什么包或者什么版本到哪个环境下,通过这样一个发布计划的制定,让非常多的人提前得知你要干什么,不至于当你干的时候发现已经晚了。我们鼓励使用这样的方法,而且很多的人已经习惯了,这个不仅仅是帮你强制性的做这个,而且可以提高效率,不然那么多IP,你哪里知道上面发布了哪些。
我从文件管理、进程管理、版本管理和发布管理方面,详细讲了一下我们包管理的特点。总结一下,务虚一下:
我这里把包和Docker作一个简单的对比。前面介绍过,包的发布速度是非常快的。包可以做到千人一面,但是Docker不一样。我前面很少讲基础的东西,因为包主要是管业务逻辑,包括进程、发布方法这都是业务逻辑相关的。包是业务逻辑,而Docker是物理的。Docker解决环境问题非常理想。
包管理的思考---标准化。整个包的发展是从效率灵活往规则约束这边发展,现在互联网发展的大趋势下必然往灵活上面靠。我们现在寻找到一个平衡点,这个平衡点就是标准化的做法。比如说我们的目标、节奏、分工、强约束、多数原则、非包不发、全民发布无审批,这些东西是我们所要达成的标准化的契约。这里尤其重要的一点是“达成一致”,作为运维负责人,要跟你研发的老板以及一大堆人去做沟通,去说你的优化方案,说你的解决思路,一定要找到打动他们的点。而我们找到的那个点是什么?就是非常低的改造门槛,却能带来巨大的效率提升。对于这样的一个东西,相信很多研发的人具备不了。
复杂业务的另一个表现是架构复杂。上面这个图和微服务架构一样,就是一个一个微小的服务,只是没有采用标准接口。
大家知道微服务的运维和管理非常复杂,这里也面临一样的问题。前面都是对程序的管理,对服务的管理就涉及到非常多问题,程序以外有很多东西,比如说权限、配置文件、设备、资源管理、名字、文件分发、验证服务、其他接口,所有这些东西都是一个服务正常跑起来所必须依赖的。
我们采用的传统手段就是文档,第一步先做什么,第二步跑哪个命令,第三步找谁,第四步跑到哪里之后发现出错。我认为文档用来传达思路和架构比较合适,所以我们暂时抛弃了文档的方法,用了CMDB镜像的模式。
大家理解CMDB是管硬件的,但是我们的CMDB不只是能管硬件,还能管业务。在物理结构之上构建了业务层,包括地域、包、配置、权限、测试用例等等,我们把所有的东西统称为资源,每一个服务节点都需要这个资源,通过这样的逻辑方法来进行管理。
那么问题来了,文档不靠谱资源就靠谱吗?资源来源于方方面面的各个子系统。我们CMDB镜像的维护是一致性的,线上会上报一些配置信息,一致性的逻辑层会去配置库拿对应的,发现不对就进行修复。修复的逻辑以前是用现网覆盖配置的,现在是反过来的,用配置覆盖现网。CMDB镜像具体落到页面上如右图所示。
有了资源镜像,而且很可靠,在做一键扩容就非常容易了,这图上面的23个步骤也很好理解的,看一下就可以。这23步的顺序不能搞乱,如果搞乱就会出问题,这个顺序是我们摸索出来的。
还想说一点,现网的20多万台机器那么多服务,我们浓缩的流程上只有四套来管理的。
上图是我们演示的结果,这里放大了,想重点突出一下自动扩容。
想做到自动扩容,我们也做了一些逻辑,但是这个逻辑是针对非常严格、非常高标准的业务模块来的。我们会在高负载扩展,低负载缩容,根据它的标准去判断到底有没有达到我们自动扩容和缩容的要求,如果达到会通过负载组件、通过一定的权重调节上线还是下线、上线的节奏是什么。
变更体检,既然是全流程,一定要从头到低全负责起来,不能只顾开始。变更完了之后,我们通过变更体检发变更报告的方法,让变更负责人和相关人收到异常的告警,如果正常就不发了,如果异常就发报告,所以变更完一定要发变更报告。
总结下,团队在什么思路下做这个管理,分享了我们的程序管理,模块资源和自动化流程,整个自动化运维还包含更多的内容,如权限如何做的、配置、流程引擎、运维组织的划分、事件管理、资源如何流转更高效、API平台、业务架构。管了单个服务,如何管理更大片的服务。这些东西就不展开了,如果有需要,可以私聊交流。
前几年我经常听到一些声音,自己也有所担心,说运维要失业了。现在云计算很火爆,自动化运维很流行,又出来一个AI运维。我觉得没有必要担心,我自己总结了三种受欢迎的运维,深度型、全局型和耐操型。耐操型是一个人愿意加班,愿意做很多东西,在很长一段时间内,只要业务需要就可以。全局型的可以掌管很多资源,包括QQ红包和跨年活动,或者是高并发的突发事件和活动,一定需要全局型的人出来针对业务架构做运维方案的优化和问题的解决。深度型的可能手里没有那么多资源,但是却非常理解运维。比如说AI运维,什么场景适合用AI,这种场景下要抓什么特征给算法去算、给机器学习,机器不会自己得知这些东西的,需要人。
希望成为受欢迎的运维,就必须解放自己,让自己进步。谢谢大家。