@gaoxiaoyunwei2017
2018-02-11T11:04:41.000000Z
字数 6111
阅读 510
黄晓轩
讲师 | 谭用
编辑 | 黄晓轩
谭用
腾讯TEG研发管理部技术运营负责人
我叫谭用来自腾讯TEG研发管理部,主要负责腾讯研发管理业务平台的技术运营,比如敏捷项目管理平台(TAPD),代码托管平台(TGIT),乐享、微校等等,也在做持续交付类的工具平台实践和尝试,以及运维平台的建设。我今天分享的主题叫痛点驱动的DevOps实践。DevOps这个提出来了差不多快十年了,但真正流行起来也就这两年,现在很热,得到行业的认可和验证,但落地的时候会发现这是个很庞大的工程,可能会不知道从何下手。这里我认为首先应该分析我们现有的研发运维体系遇到的最大问题是什么,通过解决这些问题或痛点,逐步的建立DevOps,这样的路径是我觉得比较好的落地路径,重要的不是为了DevOps而DevOps。另外一个事实是运维其实更能体会到DevOps带来的价值,所以很多时候都是原来的运维在推动DevOps,今天我也是从一个运维的角度,结合自己的一点实践跟大家去分享,如何通过问题的解决来构建自己的DevOps。
关于如何落地,我看过很多成功案例和分享,有两种思路:
第一种就是通过组织驱动,我认为自上而下的。这是非常高效的,就是从高层和组织,去开始推动所有的部门一起行动起来,然后去推进整个公司DevOps的实践。
另一种思路就是通过工具的方式。比如说我通过去建立我们自动化的工具,研发协作工具,通过这种工具去提升我们整个研发和交付体系的效率,再推动DevOps文化的形成。
无论那种思路,组织文化和工具应该是我们实施DevOps两个必不可少的因素,缺一不可。或者说不同的组织结构下,对实施DevOps会有不同的方法和路径
看一下组织,几年前或者在ITIL时代,当你的业务到一定的规模,DO分离,各尽其责,形成专业团队,基于ITIL建立服务体系,像变更管理、服务请求等,一定程度提升了服务和专业能力。但回想DO分离其实同样给我们带来了一些困惑,研发跟运维出现目标不一致的情况,各种吐槽和矛盾,流程的低效率,经常被诟病。比如说运维背锅,这是运维人的自嘲。随着DevOps的兴起,很多人认为是要去掉运维,或者让研发来做运维。比如组织是扁平化的,所有的角色在同一个团队里面,这样可以最大程度上面达到大家的目标一致性。但是简单的这样把开发测试运维合到一起是不是就可以解决问题呢,我认为在小的团队可能这样是好的方法,但是当组织到一定规模的时候会存在资源浪费,或许各个团队干重复的事情,效率不一定会提升。
我们追求的一个组织形式是什么样的,运维、研发应该有各自的核心能力和团队。研发关注于产品和需求实现,运维关注于基础设施、技术服务和效率工具研发。会有一个趋势,就是运维跟研发的交集会越来越多。以前的交集更多的是靠流程,通过流程交付给运维,现在的交集应该是从目标、责任再到权限、技能的交集。
比如以目标和责任来讲,系统最基本的一些指标,如可用性4个9,以前多半是由运维承担可用性的KPI或者指标。 我们可能不太一样,研发去承担这个指标,运维提供服务保障和支持。
另外就是在技能和权限上面,这个技能不是代表技术,比如说发布和部署,可能以前都是运维来做的,运维制定交付标准,开发按照标准交付,运维执行部署发布。其实是不是可以让研发团队自己去做部署、做发布,或者完全自动化,运维负责研发和输出工具和能力。所以运维就会存在一个转型,就是运维会越来越多的从原来部署、发布的执行变成工具能力的提供,服务提供的方式。
要做到这样并不那么容易,需要服务和工具体系支撑。所以我们要做到这种形式就一些需要解决的问题或者称之为痛点。
首先就是自动化程度和运维服务能力不够?我看到的自动化在很多团队并不是想象或者说的那么成熟,可能现在大家多在谈到AIOps、DevOps,但是现在这些概念都是建立在足够自动化,运维服务足够强的前提之下,才会去考虑的事情。所以自动化永远是需要考虑的一个点,最初最急需解决的就是自动化程度。
软件交付过程中,除了运维服务能力,前置还有很多的环节,CI,测试等。运维有自动化运维平台,测试有自动化测试平台,研发有CI工具,这些在软件交付过程中的工具能力如果不能对接,就不能发挥其最大的效能。
最后是交付质量,通过高效快速的交付来驱动更高质量的交付,这才是DevOps最终的一种理想的状态。
所以我们落地实践,实际上就是一层一层的去解决当下问题的过程。
建立运维服务能力或者运维自动化体系,矩阵模型参考。横向是专业平台能力,广泛的运维里面的角色太多了,系统管理、硬件工程师、网络工程师等等,这些都是专业领域,要建立专业服务能力输出,比如说资源即服务,也就是IaaS。基础服务比如说DB类,负载均衡,还有CDN、存储等等,这些服务能力整整体考虑,建立统一的运维支撑服务体系,不需要重复造轮子。应用层的运维能力,相对比较复杂一些,各种应用场景在架构上差别是比较大的。但是像Docker给应用层做运维服务化也提供了一些很好的解决方案。总结横向对研发和业务运维提供专业运维能力输出。
纵向就是业务的能力,根据业务特性和运维场景要去做一体化的工具和自动化。纵向的能力建设更多是通过横向能力的封装。比如自动化资源获取、创建基础服务、应用发布部署。核心是业务形态和运维场景,定制化的做成想要的一种具体的工具。
标准化到自动化再升级到平台,这是建立运维服务能力的基本步骤。运维自动化的前提就是建立在标准化之上,这个很容易理解,没有标准化的自动化其实是很痛苦的一件事情。和大部分团队一样初期也不太可能考虑标准化的事情,业务发展规模之后,再考虑标准化挺痛苦的,所以标准化能早做尽量早做。
自动化一开始都是脚本,最多能通过关联的API的互相调用把各个基础能力串联起来做成自动化的工具。单就运维来说,有这些工具多半都已经满足了我们运维的需求,可以释放运维大量的时间和精力。
可是通常你不可能把一堆自动化脚本给研发或其他业务运维,说你用这个脚本就可以了。所以再上一层就是我们要考虑去做服务化的能力,也就是运维平台。比如说做到一键发布、一键部署、在线扩容等,实现这些能力,这样的服务使用者无论研发测试或者业务运维,操作结果都一致的,所以你的运维能力就提升到一个开放的层次,可以放心的把运维的节点交给交付流程去集成,或者省去中间很多人工的流程。
深入的聊一下应用标准化。应用层面因为技术栈特别多,标准化要考虑很多的问题,比如操作系统的版本、运行的依赖、环境的依赖、中间件的版本、各种环境的配置,这些都是依赖。还有程序包,制定规范把代码、配置或者启动脚本,日志目录,包括其他可变的东西打包。环境依赖和程序包的结合,就是我们一个应用的单元。容器是简化了标准化的一个解决方案。Docker的选择最重要的就是解决标准化的能力,它还有很多其他的优势,资源隔离性、性能损耗小,可以节约成本,快速的分发。但是每采用一种新的技术,他一定是解决你一个很重要的痛点就足够了。对于我们选择采用Docker,最重要的是在标准化层面的痛点解决上有很大的优势。
基础设施无关,可以解决操作系统版本等依赖这个层面的问题。另外以镜像为交付单元,就解决了研发和运维的交付标准和接口问题。可运维性很强、有很好的移植性,可以快速支持混合云部署方式,我们现在很多应用都是需要混合云的部署方式。如果说Docker解决了标准化问题,但基于Docker建立起它的服务体系,就是我们要解决的下一个问题。
这是我们一个容器服务平台的简单的架构图,基于mesos开发。现在大家做Docker的容器编排服务大部分都是选用Kubernetes,它是基于容器的一整套解决方案,基本上把它部署起来就可以跑容器服务了。2015年底,我们那个时候做技术选型,Kubernetes那个时候的复杂度还是很高,也有一些问题,最后选用了Mesos。Mesos并不是专为Docker设计的,它在大数据场景下面的应用已经很成熟,在资源调度层已经很稳定,所以可以很快速的通过Mesos来实现我们资源调度的能力。它很灵活,可以支持很多的框架,而且很重要的是可以跟我们原来的一些平台方便对接。
建立容器服务平台有几个必须的模块。第一个就是资源调度,通过在线资源调度实现资源即服务的能力。对于应用或者研发来讲,资源就是一个可运行的程序,而不是一台服务器或虚拟机。第二模块是服务发现,在线的业务的变更,都通过服务发现,告知接入层或调用端,从而也是对应用层做一个透明。当然容器的运维模块,监控体系和日志这些跟运维相关的也会有特定的处理,跟原有的运维平台对接。这些是构建容器服务平台要考虑的几个点,当然除了这几个模块之外,镜像管理,在我看来是容器服务平台之服务的核心,或者说是构建持续交付的核心之一。
先看镜像,是不可变基础设施的载体,所有东西都认为是代码。除了代码,应用配置,环境配置,包括启动脚本,构建脚本,全都通过版本库管理和版本控制。举例以配置来讲,之前有配置中心集中管理的配置,比如开发测试和生产环境有不同的配置。现在在容器这里的我们选择把配置和代码存放到一起,把所有的配置在构建时就放到镜像里面去,通过启动时传不同的参数来初始化不同的配置。最重要是一个镜像交付到各个环境,保持足够强的环境一致性,避免一些环境不一致带来的问题。
关于镜像的三层镜像,我觉得镜像分层也是业界很通用的做法。
第一层是基础镜像层,就是一个最小化的工具集。为什么会有这一层?最主要的原因是我们要通过这些工具控制一些全局,可能是解决全局工具的问题,去做升级。
第二层,中间层是我们会去维护一个组件级,如(nginx,php,tomcat)。举例我们知道这些开源的东西安全问题特别多,可能时不时就会有一些版本搞出一些安全漏洞,我们要解决这些安全漏洞,通过这一层就可以控制版本。我们也可以提前把中间层的版本下发到宿主机上,一定程度提高我们镜像分发的效率。
第三层就是通过基础镜像构建出应用镜像,通过镜像完成交付。
再聊一下容器管理的几个模块。首先是资源调度,就是如何将容器运行起来,计算资源的按需分配,网络资源,存储资源的挂载,通过分布式存储落地数据,比如高性能要求的数据用块存储,还有通过共享存储或者对象存储的方式。另外需要具备健康检查的能力,健康检查是故障自愈的基础。除了这些基础能力之外,有的应用需要特俗的配置和资源,比如固定IP/端口,多个容器的编排,或者相关几个镜像要跑在同一宿主机上等。这是一些特殊的应用场景,我们通过标签的方式去管理资源的调度。同时平台层面要考虑资源的高可用和容灾的能力。
服务发现是后端对前端透明的关键服务,任何后端资源的变化,对于调用方或用户无感知。服务发现有一个注册中心或者叫名字服务。以host模式为来说,他的特点是共用宿主机的网络,每一次的发布或部署,会随机分配新的IP和端口。服务发现就是去发现这些变化,告知客户端服务的真实地址,或通知负载均衡获取新的配置来更新分发策略。负载均衡服务或者代理是服务发现的一部分,所以要考虑过载保护的能力和灰度发布的策略。
再说说运维层面,主要是监控和数据采集。其中一个点是agent,为了维护简单,有的是用超级agent的方式跑所有的监控、容量采集和日志采集。但我们的做法是把这些模块分开,用容器跑每个单独的能力。比如有独立日志采集的容器,只干一件事,有资源采集容器,应用监控的容器,其实并没有太大的开销,互不影响。另外容器本身就提倡单个容器干单一的事情,维护更简单。
前面具体的聊了镜像和容器。通过容器服务平台,我们已经可以把一些基本的线上运维能力开放,实现了一定运维服务化的能力,但这还停留在运维层面,应用的交付应该涉及到更多的环节。接着我们应该面临的问题是,如何实现研发和运维之间的自动化交付,我之前提过镜像管理应该是应用交付的核心。应用从代码仓库的代码提交到代码的编译打包,构建成业务镜像推送镜像仓库,容器平台分发应用,这是一个应用交付最基本的场景和流程,所以我们应该是基于这些最基本的流程去设计我们的镜像管理和交付过程。通过与代码管理平台的对接实现提交代码即出发流程,通过jenkins集群构建完成代码编译和镜像构建的全自动化过程,docker单一镜像的交付让测试、预发布、生产环境保持唯一的部署方式和标准化的运维接口。
到这里我们算是实现了最基本的自动化应用交付能力,当然持续交付是需要质量和效率的保障,缺一不可以。这个时候我们要考虑的就是质量如何去保证,持续交付的知识体系,这里面我重点分享质量内建。
质量应该不是独立的存在,而是贯穿在应用交付过程的各个步骤。持续集成CI阶段,集成一些质量检测工具,比如说静态代码扫描,在公司有专业的团队在研发静态代码质量扫描的产品,我们只需要去集成这样的能力。当然单元测试少不了,刚开始很难,需要通过持续交付流水线的质量门去推动研发不停的完善。
在测试阶段,就是尽可能的引入自动化的测试能力,减少人的参与,接口测试、UI测试逐步覆盖。另外我们还引入安全扫描的机制,在持续交付过程中去提前发现一些安全漏洞的发生。那这些能力也一样是集成公司现有平台的能力,开源也有很多的解决方案。当然我觉得自动化测试阶段最重要的不是工具,而是要对测试用例的开发和维护的投入。
持续交付里容易被忽略的是交付完成之后运营阶段的反馈,需要通过监控体系来及时发现这些变更和发布是否带来异常。也就是集成运维监控平台的能力到流水线,比如一条流水线完成后能自动输出线上的健康度报告。
最后是流水线流程的每个阶段都需要异常反馈,触发阻止交付的机制,通过TAPD缺陷管理跟踪,形成一个对质量闭环的把控。
最后构建好CI/CD持续交付流水线总线,去接入各种工具的能力,从TAPD项目管理平台到代码管理的对接,自动化测试工具,自动化发布或容器服务,运维监控。通过这些工具和平台的能力集成到交付流水线,来持续优化应用交付的质量和效率。最后通过工具成果推动文化的养成。这是我们的一个持续交付流水线例子。
总结我们的实践,并没有一开始就想要做CI/CD。从开始追求组织的模式而知道问题所在,驱动我们去建设运维自动化服务体系,跳出运维视角建设应用交付能力,最后到集成更多的工具做持续交付的流水线,距离理想的状态还需要持续优化。这是分享我们自己团队的一个实践路径,相信并不适应每个团队的情况。但回到我最初的观点,就是每个组织在某个时间都会遇到的最需要解决的问题,或者说痛点都不太一样,最终需要通过痛点的解决,驱动属于自己的DevOps实践。
最后提到的很多平台,也逐步通过腾讯云DevOps产品开放给我们的合作伙伴和其他公司。比如TAPD项目管理平台和TGIT代码源的管理平台已经开放,还有持续交付和运维服务腾讯云也有好几款产品,我们也在逐步开放。希望这些工具能帮助大家去构建自己DevOps的体系。