编者按:2017年8月23日,腾讯“云+未来峰会”在北京召开,此次大会特别设立了腾讯云开发者分论坛,在此论坛上,腾讯织云负责人梁定安做了《腾讯DevOps流水线的应用实践》的演讲,本文根据此演讲实录整理而成。梁定安(大梁),腾讯织云产品负责人,开放运维联盟委员,DevOps三十六计发起人,高效运维社区金牌作者,腾讯云布道师,复旦大学客座讲师。
责任编辑:孙浩峰 技术之路,一起进步,云计算、大数据、人工智能、运维、安全等方面的干货文章,欢迎投稿。投稿信箱:[email protected]
今天是开发者专场,我在这里给大家分享一下腾Devops流水线的应用实践。我来自腾讯的社交网络的运维团队,做了十几年的运维,目前我们把多年积累的运维能力实现了产品化,就是我们今天要讲到的织云平台,其中包含了很多我们在建设DevOps过程中的构想和思考,如何让企业能够更接近DevOps,让每一个企业IT人员,工具系统能够产生它的价值。
织云这款产品,其实从去年就已经走出腾讯,跟很多的企业有合作,像贵州的智慧小区、宏立城,还有上海的华通银行、内蒙古的金谷银行、深圳的港交所等等。但是为什么大家听的比较少,因为当时所有的方案都是私有化的,就是专门针对客户的场景给他定制一体化的运维平台。
今天主要有三个方面的内容和大家聊一下。一开始,先跟大家分享一下腾讯的DevOps实践是怎么做的。下图是一个企业IT价值链的流势图,提到Devops肯定要提精益,因为DevOps是基于精益理论在上面构造出来的。
精益里面强调了一点,价值要流动,必须要由一条链承载,这就是我们今天聊的DevOps的流水线。任何一种开发模式,像瀑布式开发或者是敏捷开发都有一条链承载的,这条链大同小异,都长成这个样子。因为任何一款互联网产品从需求搜集,提出需求,到开发、编码、测试、到最后交付到运维手中发布,并为保证高可用做监控、告警,做修复等一系列的动作,再到搜集新的需求,把这条链反馈到产品中,这条链大家可以认为流转速度越快,代表企业的IT能力就越强。这就是为什么Devops在2009年被提出来之后大受欢迎的原因,因为它提供了一种技术实践的方法,让我们找到了一种可以依托的实现的技术,让我们企业IT的价值链流转加快。 以传统行业的案例举例,以前可能应用的发布一次可能就需要一个月、甚至半年,现在我们为什么能够做到每周发布,每天发布呢?其实就是这条链来决定的。
Devops的组成,其实也是按照这条链,只是把刚才那条链扁平化了。在完整的Devops当中应该包含了我们怎么做计划,包括我们做产品设计的时候,要用最小可行产品, 要管理需求,可能有一些敏捷的方法,你的需求怎么描述,你的用户故事、用户地图怎么写,在做设计和开发的时候,要怎么样保证代码的质量稳定可靠等等一系列问题,最后到如何发布,发布完以后,如何监控。今天发布的腾讯这条流水线的对应的工具,包括了TAPD、tGit、GIS和织云,今天我会重点给大家介绍一下织云作为最后一环的持续部署的效率和质量,经过了腾讯这么多海量业务的洗礼,我们的方案会是怎么样的,也希望通过我们方案的介绍,会给大家一些启发。
在腾讯内部,我们会把一个需求从概念变成特性需求,变成可以供开发人员理解的具体开发需求,然后一步步的走到我们的生产环境中,就是下面这张图图。图中把我们今天发布的所有产品都涵盖了,就是TAPD。 产品人员、开发人员录入需求,这个需求经过评审,分解成一个个的直接开发实现的特殊功能,存放在腾讯内部,然后会进入到持续集成的阶段,做自动化的编译、集成、自动化测试、代码的近态扫描。 如果有一些不合规范的代码,或者合并了某个分支以后,主干测试就通不过了,则通过CIS解决,这些解决以后,就会形成一个制品库,所有的制品库会和织云系统进行一个对接,织云系统拿到制品库之后,就会按照腾讯标准的发布、管理的方案,把我们的制品、软件发布到生产环境,进而去做灰度,做上线的一个过程。
今年3月份,就是春节那段时间,GitLab有一个很著名的故障,就是他们的一个操作人员在测试环境和生产环境多终端切换的时候,在生产环境敲错了一个命令,结果把生产库全删掉了。然后也是花了很长的时间才把代码恢复。这里面其实说明了一个问题,首先不考虑技术的因素,先思考一个问题,如果一个经验不深的同事入职了,把一个很重要的任务交给他,他会不会一个发布把网站都发没了。如果一个经验之深的人做这个事情,可以拍胸口说他绝对不会出错,因为可能过程中有很多坑,这些坑没有办法通过配置、通过系统、通过规范流程描述出来,那这样把它交给一个新人,不熟悉的人,就会有可能有问题。
我很喜欢用一句话来总结这个问题是怎么产生的,这句话就是文档即过期、离职即消失,我们在经营一个企业的技术体系的时候,通常喜欢依赖于文档,文档可以帮我们记录很多事情,但是无法记录他的经验,而且可能他留下的文档经过两周的版本迭代也不适用了。那么,下面,我就给大家介绍一下怎么站在运维的角度解决这些问题。
在腾讯内部执行DevOps是有一个标准的执行的规范,就是每个产品需求怎么样一步步变成一个编码过程,变成一个可交付的制品,放在我们的生产环境之后,会配套给这个制品什么样的监控,什么样的运维以及什么样的效率和质量支持,而这其实就是由我们这条流水线决定的。这条流水线要解决的几个问题,就是不能因为人的经验而流失。例如,有可能有一个开发人员经验很资深,知道做这一步一定要测试,但换了一个新人,他不知道或者老员工因为工作繁忙,忘了交待新员工,从而使得不该发生的故障发生了。那么,我们怎么解决这个问题呢?下面,我们一起看一下腾讯的应用架构怎么保证对每一款业务、每一个架构的可运维性的保障。
Devops有一本很著名的著作被称之为红宝书,就是《持续交付》这本书,作者是Jez Humble,中文译者是乔梁,现在是腾讯公司的高级顾问。这本书有8个原则,就是一个纯概念的东西,可以指导我们怎么做好整齐的一个流水线规划,为软件的发布创造可重复和可靠的一个过程,可重复、可靠,背后意味着什么?意味着我们要有一个很强的体系,如果每个对象都长的不一样,怎么可靠、可重复呢?因此,我们得按场景进行自动化,把所有的东西都纳入版本控制,将几乎所有的过程都进行自动化,为什么?大家仔细想想。如果大家是开发人员,有没有想过你拿什么样的制品去发布到生产环境,或者你们有运维的同事的话,是不是就是丢一个压缩包给他,让他发布?站在精益的角度,这些其实就是浪费。
那么,当我们去规划持续交付、持续部署的系统,要怎么规避这种浪费呢?通俗的讲,就是怎样创建一个可靠、可重复的过程?实际上,这就是要求要标准化我们的发布,不能够让发布的动作随着人的经验而发生改变,它必须要依靠一些可靠的、可以被重复执行的脚本。我不清楚在座有多少同学是做运维的,其实做运维,或者做技术都会有一个问题,就是往往别人交接了一个小系统或者小架构,或者小脚本给你,你拿到的第一件事,看看代码,心中默念几句脏话,写的太烂了,类似的,你会跟你的老板说,给我一周的时间,我重构它,然后周而复始。对于运维的岗位,也经常发生这种事情,为什么?A同学写了一个发布的工具,写了一个发布系统,B同学来了,发现跟他的思维模式完全不一样,重构,重构,重构,时间全部浪费掉了,然后我们的企业一直都没有得到最终的价值,为什么?其实我们退一步想,为什么写这个工具?开发也好、运维也好,我们在企业的价值都是为了让企业能够创造更大的商业价值,而不是彼此的不断地重构、不断地重复造一些轮子。所以,基于Devops持续交付的原则,我们希望能够找到一些突破口。
我们提出了“四步走”,就是我们的业务要从一开始就能够去让它的架构尽量规范,为什么?站在开发人员的角度,要实现自己价值,就是要把产品需求实现,就是把产品需求变成一个个功能、特性,编码的时候,要完成这种功能的逻辑实现。
但是,如果站在架构高可用,还有可运维性的角度去思考这个问题,仅仅完成功能的开发是不够的,还需要一些非功能的,一些站在可调度、可容灾,高可用角度的需求,这在DevOps里有一个专业名词叫“非功能需求”,这种非功能需求和功能需求怎么融合在一起,都放在开发编码阶段,让它实现,这是一个问题。最后当进入到运维的领域,怎么让统一架构和运维规范朝着标准化操作方向发展,然后在逐步往自动化,甚至更远的智能化方向发展,这是我们要解决的关键问题。我们下面就来探讨一下怎么落地和怎么实现。
其实所有的互联网业务的架构,我们都可以看成是上面这张图。我们从用户说起,用户有终端,无论是PC还是手机,会通过我们运营商提供的网络,访问到提供服务的内网,如果是云的话,就有可能访问到腾讯云的网络,还有可能是一些云主机。在这些网络里,如果大家按照微服务架构设计的话,存在接入服务、接入层、逻辑层、数据层,刚才张兴华老师跟大家分享摩拜的架构,按照腾讯架构的思路去给它重新规划的时候,架构层次非常清晰,接入层做什么,接入层承载的是海量的服务,只需要协议的兼容, 转发给后面的逻辑层处理,逻辑层强调高并发的吞吐,QPS是多少,然后完成所有的逻辑计算,最后是数据究竟怎样落地,用KV还是用SQL。
在腾讯,我们提出了尽量把架构做成框架化、组件化、无状态、分布式。用一个词,就是尽量往微服务靠。怎么样做到这一点?我给大家举两个实践。在腾讯我们是怎么样把服务做成框架化的。我这里举的是腾讯内部在使用的一个逻辑层名字叫SPP的计算框架,这个框架有什么特点呢?大家其实可以想一下,任何一个互联网服务,如果是分布式架构,其实在服务之间通常都有一个调用。那么,腾讯这么大一个体量,如果每一个开发人员都要写一个微服务给别人使用,或者要调用别人的话,这里面有很大一部分工作将是重复劳动,为什么?因为每一个服务网络收发请求这部分功能都是公共的,怎么样提高开发效率或者怎么样保障统一框架的诉求呢?
所以,我们提出了像上图这样的一个逻辑层的计算框架,这个计算框架帮助开发人员去通过框架的层面实现网络的请求收发。开发人员只需要很简单的写一个动态链接库,把业务逻辑写在动态链接库,当一个进程加载的时候,会自动加载这部分的业务逻辑,而当这部分业务逻辑真正使用收发请求的时候,就直接调用API就可以完成了。这样当开发人员在接到不同业务需求的时候,都能很快的实现。
虽然有了统一的计算框架,但像类似的计算框架在腾讯内部其实还有很多。那就遇到了一个问题,就是服务和服务之间的访问,路由怎么决定?大家有没有考虑过一个问题,当A服务访问B服务,B服务是一个集群有10台机器,有1台机器故障了,如果用配置的形式访问,在一个配置里面写一个IP地址访问,很有可能A服务发一个配置,重启一下进程,才可以把B服务故障的IP去掉。但是,大家试想一下,在腾讯这种海量业务的情况下,QQ有5万多台服务器,微信应该也接近5万台,这两个业务已经10万台了,整个腾讯,超过50万台服务器,腾讯有70万台的物理机。这么大体量的设备压力,没有办法做到任何一个IP挂了,我们都有人能够去处理,都发一个配置去变更。但是当我们引入了一个软路由服务之后,就帮助我们很好的解决了这些问题。下面一台机器,当主调程序访问被调程序的时候,会通过API问路由服务从而得到一个服务ID,通过这个服务ID,去访问被调服务,被调服务要做的是什么?只要通过维护好这个ID后面映射的那一个IP,就可以做到主调和被调中间的路由解耦,主调服务通过每一次请求都会调用一次这个名字,假设被调服务是十个IP,每一次请求,API都会随机返回任意一个IP,在一定的时间段内,所有请求的成功率、延时积累下来,在下一个请求,主调程序再去请求L5 API的时候,L5就知道下一次返回一个最优的IP,就是成功率最高的IP,从而实现被调服务如果出现了任何问题,只要不是整个集群都挂掉,都可以实现自决策的负载均衡。路由服务目前也跟着织云一起开放了,大家如果需要使用的话,也可以免费使用软件的路由服务。
基于框架的能力和组件的能力,我们慢慢找到了一些规律,那就是可以把很复杂、业务形态各异的业务架构,逐步的通过规划和不断地架构演进、迭代,将千人千面的业务架构长成千人一面。在每一个架构层级我们都有相应的解决方案,可能都不需要部署在哪里,围绕着这个方案做很多关于自动化、高可用、质量、监控、告警等等操作。
最后一个部分介绍一下基于腾讯DevOps实践以及可运维性得出的一个运维方案,就是腾讯织云的持续部署的架构实践。下图是腾讯织云的功能的一览表,这里代表腾讯织云从下会管理到IaaS层,目前腾讯对很多私有云的客户基本实现了从专线、网络设备负载、CPU、内存,还有虚拟或是实体的物理机实现了全盘接管。对于一朵云还是跨云,也都可以接管,并且在接管以后提供了一系列的组件,如监控信息、日志、路由服务等,都可以提供。基于此,我们上面会有CMDB,就是配置管理。
现在谈论自动化运维,都会涉及到一个核心的功能模块,就是配置管理,我们必须要把这个架构用配置描述出来,包括基础工具、持续部署、架构组件、监控、报警、质量,因为在DevOps中,很强调一点就是一定要把价值链闭环,任何东西不是发布出去就结束了,发布完才是真正的开始,我们基于发布出去的特性,通过用户的主动反馈以及技术日志分析出来的结果,进行相应的优化。例如为什么北京的用户量是最大的,但是北京的访问延时却不是最优的,那我们有什么优化的方法?其实很多初创型的公司都不知道在一些特定的场景中应该怎样分析,分析什么样的数据。但在腾讯,我们面对互联网的业务相对比较全面,无论是对技术日志分析的经验,还是日报的分析,以及哪几个字段应该重点分析,像这些很细节的点,我们都有丰富的经验,并且可以给用户很好的建议,并把这部分成熟的运维经验和我们的系统一起输出。基于此,我们认为有必要讲一讲自动化和监控如何做。
为什么把自动化和监控放在一起说?因为我一直认为一个企业业务质量的问题,或者说效率的问题,不能孤立的来看,就像我们收到一条告警,为什么会有告警?我们应该深层次的挖到根源,有可能由于某个变更引起的,有可能是由于某个不规范操作引起的,这就说明了如果我们没有去记录那部分操作的信息,无论监控怎么做,天花板就已经在这儿了。所以,我们提出一体化运维的概念,这就是我们织云平台的功能。
通过平台功能的介绍,我们来看一下日常织云能管那些运维对象。这里有一个词,我们很注重非功能的规划,织云这个平台先天性带这运维的理念,对你的每个发布的发布目录,发布日志,应该要怎么放,我们都会给用户最好的建议,为什么给这个建议?因为当日志写满目录的时候,会自动触发一些工具,可以在得到授权的情况下自动帮你清掉。当然,可能现在不能随便做这件事,因为前一段时间网络安全法刚出台一条,任何人员不能擅自删除记录。基于这一点,我们一直再寻找一些要怎么样通过一个很强的规划去把我们的运维对象慢慢减少,减少运维对象的意思不是说不运维,而是例如我有一个Web服务,有一些开发团队选择Apache做它的Web Server,有一些开发团队用Agents,有一些用INS,有些开发团队觉得那三个都是不好的,我要自己写一套,你还有一百个开发团队,他都觉得前面的不好,他都要写一套,而这个时候就需要统一的一套Web服务,而不是多套,这就是减少运维对象。我们希望通过统一框架的提供,让大家都不要再去纠结这种问题,让我们的企业架构不要失控,这是我们的一个初衷。
为此,我们的CMDB配置管理包含了两大部分,一部分是基础配置,还有另一部分是应用配置。基础配置有什么用呢?进入了企业内部环境的所有资产的信息,包括企业有多少台服务器,序列号是什么,厂商是什么,这些信息都属于基础配置信息。这些信息有什么用呢?最直接的用处,就是运营成本马上可以通过CMDB得出,比如每个月成本的开销是怎么样的。CMDB会记录下分布信息、运营配置,拿运营配置来举例,运营配置里面有很多个字段,包括设备的负责人、设备的状态、响应级别。记录了这些信息以后有什么用呢?刚才秦俊老师介绍织云的时候提到一点,我们强调的是先有规划,再有操作,有规划之后,我们的操作就可以根据规划来做更多、更自动、更智能的动作,例如我们一开始已经把我们的企业的业务架构分成不同的层次,而不同的层次由于它的容灾能力、容错能力不一样,有可能会被分成响应级别最低的以及响应级别最高的。响应级别最低的,如果出了问题,可以直接用云的弹性收缩的能力进行修复或者直接销毁,再上一台,这样就可以把我们的效率提高,这其实就是DevOps,不然DevOps就流行不起来,它必然是通过很多自动化的过程,让开发和运维的变得更高效,开发效率得到提升,才得以流行起来的。
再举几个案例,还是以资产对应的资源配置举例。资源配置代表什么,资源代表了我们的制品,就是我们的软件包,二进制文件,配置的文件、环境管理的脚本,或者更高级一些的,都会定义成资源,这个资源用作当我们要操作某个业务功能或者服务需要扩容,或者需要全新部署的时候,这些资源就会被配置化的描述起来,我们的运维系统可以自动的理解,并帮助你做这样一个发布,而不是有一个业务要部署。比如,经验丰富的同志就知道有一个配置必须要发,但是换了一个经验欠缺的就有可能发少了一个配置,或者少改了一个配置,这是很致命的,如果没有做灰度测试就发布上去,业务就可能受损。我们基于CMDB的配置,把对运维体系中要纳管的对象基本都进行纳管,最后通过业务编排,有了一个资源,然后是传输、执行。把这一系列的链条做成一个可靠、可重复的过程。我们得出自动化运维的方案,就是统一规划、标准化、配置化、自动化、监控,不能漏了监控,通过我们的流程引擎把它串起来。
统一规划要做什么?就是要把我们的全流程理顺。开发、测试、运维怎么对接?标准化,架构可运维性是不是可以描述出来的?我们的非功能规范是什么?我们的系统可不可以承载非功能规范?以前和很多同行交流过,非功能规范都有,但是大家不执行而已。比如,谈到配置化的话,要把什么东西描述出来,然后自动化,你能做什么自动化。谈到监控,自动化以后怎么保证无人值守是可靠的,或者哪怕不是自动化,每一个发布,怎么度量你的发布是正常的?发布完成后,经验丰富的知道要看哪几个指标,经验不丰富的就看漏了一个,出了问题都没有办法排查,大家一头雾水。而通过我们的工具编排,这些都会变成一条条可以去重复使用的一个流程,我们称之为工具链。
这里以新设备上架举例,如果新采购回来一台设备,或者在云上通过控制台购买了几台机器,那者几台机器要怎么管?以腾讯内部的流程来说,我们会先测试一下连通性,把密码入库,权限回收,初始化成一个可以直接给业务使用的状态,包括应该装什么应用、系统用户是什么等,然后把它的状态改成待分配。待分配有什么好处呢,别人可以看到现在的Buffer池有多少,容量多大,自动化程序就可以从待分配这里拿机器,去上线,去扩展节点,类似这些,然后划到Buffer池,待使用。实际上,每个企业要开展正常的生产环境的管理工作都需要很多不同的流程,我们提供了编排的流程,或者说改一下状态,监控系统在做监控告警的时候就会根据这个状态来决策,究竟是直接不告警,还是直接打电话告警,还是发一个统计信息。
我这里给了一个案例,假设我们在做自动化部署的一个过程,总共六步,申请设备、获取资源、发布、质检、测试、灰度、上线。我们把每一个步骤的最原始的操作总结出来,一步步的串行做完。每一家企业都有一个工具流,因为金融行业可能基于监管的需求,没有办法完全自动化,就在某一步加一个发邮件,领导说到这个邮件点一下链接,这个流程继续在走,是授权在做。或者停下来看指标怎么样,再点下一步再继续做,我们其实都是支持这种不同的过程。
下面再举一个自愈案例。这个自愈案例讲的是在某几台服务器上跑一个应用程序,这个应用程序是以进程端口提供服务,进程挂了怎么办,按传统的思路挂了就告警,告警就处理,但是用了我们这个运维管理的体系,在安装包开始,并且它的这个动作完成之后,会自动的给我们CMDB对应的业务注册的配置信息,我们拿到这个配置信息,会生成监控服务依赖的一个监控的配置文件,我们会下发到具体的每个监控agent那里,监控agent拿到说,原来我在这个IP上执行,是要保证这几个进程都在的,监控agent就会每分钟PS,当它发现不在了,就会调用进程重启,去把它拉起来,从而使进程继续可以自动的去修复。类似这种场景其实还有很多,我只是举了进程监控的这个案例。从这里可以看出,通过这些集中的规划,统一的管理,可以使我们运维的效率的到很大提升。
下面还有一个案例,就是自动扩容的案例。今天早上在主会场提到了一个案例,就是人民日报加天天P图的那个军装照,那个军装照整个背后支撑的就是织云,我为此还发了一篇公关文,就是8亿人晒军装背后的运维技术。就是讲的今天这个主题,在我们腾讯这边,因为社交业务经常会由于一些不同的事件,有可能今天是“520”,不发一个红包给我,就好像不爱我。当有这些事件,对互联网业务来说,表象就是像这种图,流量来了,我突然搞一个推广活动,流量一来,怎么办?传统的思路只能人去处理,但是如果你有一套很完整的运维体系,并且思路很清晰的话,其实我们是会这样的。当流量一来,我们的后台决策会基于容量来决策,是不是需要紧急的触发一些自动化的流程来修复这个问题。所以,我们会收到一些短信或者微信,QQ消息的提醒,告诉我们说有一个业务,流量陡增,但我可以帮你自动调用这个流程,你可以先等等,然后就7×24小时帮我们支撑好服务。当流量突然增加,我们会自动的增加容量,大家可能会说,如果是一些原生云的服务,可以用弹性伸缩,但是弹性伸缩只基于母机的一个性能的前提下,但我们还可以跨母机的增加更多的资源。