DevOps转型的动机
我们的客户是一家海外本土最大的金融保险集团,他们在发展到一定规模以后,意识到自己就像一头笨重的大象,举步维艰,通过对整个交付流程的思考和分析,发现了以下一些严重影响交付速度的问题:
- 一些好的关于产品改善和创新的想法很难落地。涉及到一些遗留系统的配合:调整、部署、扩展等,使团队对发布没有信心。新的服务或者应用的构建,很难快速上线,被卡在了生产环境部署阶段。
- 各种不同种类的应用、服务的部署方式和流程不一致。运维部门作为一个支持部门,很难为大量团队提供快速反应。运维人员对于需要部署和运营环境之上的产品也不够了
解。 - 微服务运营过程中,交付团队难以做到快速集成和部署。运维团队对微服务的部署运维方式不理解,依旧老瓶装新药,很难适配新架构下的交付模式。开发团队大多关注代码和架构,对于产品如何能在生产环境稳定运行、需要考虑哪些安全性和可持续性的因素并不是很了解。
问题分析和挑战
通过对这些问题和各个团队反馈的深入分析,发现其中最大的瓶颈在于交付团队与运维部门之间的各种依赖和沟通浪费,而这个瓶颈又是解决大多数问题的前提。
我们将瓶颈具象化后(如图上图),可以看到两种团队之间其实是存在一堵墙的,一是因为传统的部署流程非常繁琐和低效。二是因为两种角色关注点和目标的不一致。
如果在这样的情况下,想实现微服务架构转型,实现更快速和安全的交付,只会更快的暴露出这堵墙引起的各种问题。开发阶段,系统的架构和依赖环境都是Developer说了算,对生产环境的关注度不高。部署、发布阶段,Operations会考虑如何构建一套稳定的基础设施,又如何去部署和运维开发的产物,但是往往对于产物的了解不充分,对于产物的周边生态和与它们关系的了解也不够。
那么引入DevOps文化,消除开发与运维之间的壁垒,逐步打造更高效的交付流程就成为我们破局的关键,那我们应该怎么做呢?
改革之初,我们发现并去尝试了Bimodel(双模IT), 我们看看它是否能解决我们的问题:
先简单介绍一下什么是双模IT:
它将IT系统分成了两种模式:
- 一种是新型的数字化、高市场适应性的IT,这部分业务聚焦企业新市场和业务的开拓,创新和发展,强调IT自身对于市场的高适应力。
- 另外一种模式下,我们则需要稳固发展,对于传统模式我们倾向于更加严谨和标准的流程去保护现有业务,稳定性比速度更加重要。
我们从采用这样一种模式的实践案例中发现:组织内部会出现连两种速度的交付流程,好的情况可能是采用敏捷开发流程的交付线,有着快速的交付能力,相反,对于继续采用传统开发流程和运维方式的团队,保持着稳定但低效的交付能力。
从业界很多公司的现状和发展趋势来看,双模IT确实是很多组织存在的现状或是必然经历的过程,但不是一个好的模式,从实际的交付过程来看,存在4点问题:
- 双模IT的划分方式更多是基于软件系统,而不是从业务活动出发进行的,所有软件系统的交付都应该是面向业务价值的。
- 双模IT会让我们误以为速度的提升会引起质量的下降,但是对于我们在ThoughtWorks的很多敏捷实践中学到的:随着交付的推进,质量内建是团队共同负责和持续改进的重点。交付速度的提升,往往都伴随着质量的保障,而不是忽视质量。
- 实际生产中,一个新的产品或者功能往往会依赖很多遗留系统提供的服务,如果它们仅仅只能达到稳定和低效的交付,对企业来说对市场整体的响应能力也会越来越低。
- 企业的创新不仅仅只是从零创造一个新的产品,还有很多机遇现有的资源。一个新的系统和功能往往不仅会既涉及到新服务、应用的创建,也会涉及到遗留系统的修改,调整和改造。
由此可见双模IT是在以一种试图掩盖问题的方式来逃避目前最重要的问题:开发和运维之间的壁垒。感觉像是一个病人先是放弃治疗,然后又努力的寻找延长寿命的方法,有些隐患终会爆发。
打造自服务持续交付
紧接着,我们开始采用了一种看似不可行的方式开启了DevOps转型,建立公有DevOps团队。有很多人可能会说这是一种反模式,怎么可能会建立一个团队专做DevOps相关的事情,那和以前的运维部门又有什么区别?DevOps提倡的Dev与Ops高频度合作的文化是不是就无法大面积传播了?
因此我们需要很明确的定义我们对这个团队的期望和它的职责是什么,它是怎样和交付团队合作,影响交付团队,最终能让DevOps的文化可以大面积传播。这个团队的目标是要像杠杆一样,翘起更大面积的DevOps变革。
所以我们认为公有DevOps团队应该与其它的端到端交付团队的人员构成是一样的。不同的只是目标和价值,主要体现在帮助更多的团队植入DevOps文化、优化持续交付流程。最终达到的目标是每个团队都可以自治,每个团队都可以进行端到端的开发、测试和部署,并可以自驱动的持续改进。与此同时,这个团队不仅仅只是为交付团队提供更多涉及基础设施、持续交付流水线、部署等活动所需要的自动化能力,还会支撑交付团队根据自身的上下文去定制和规划自己的持续交付流程和部署策略等。
(图片来自:http://t.cn/R9jnzHR)
现在,相比于DevOps团队的叫法,我们更愿意称呼这个团队为Platform团队,一个原因是我之前所说的避免被错误理解,另一个原因是随着各个交付团队逐步实现自服务持续交付,这个专有团队也有了更高的目标:持续打造和优化一个能够支持各交付团队快速交付的平台。
当时,我们首先为团队定义了新的工作方式:以自服务,自动化和协作 作为核心文化,希望团队通过提供便捷的基础服务,让交付团队拥有自动化的交付流水线,并通过更多的沟通协作,尽可能让每个交付团队都能够独立自主的设计、创建和更改自己的基础设施。然后再根据各个交付团队的实施情况和结果来对流程和服务持续改进。
所以第一件事,我们首先设计了一个高效的持续交付流水线,让Platform团队和交付团队建立触点:
如下图所示,蓝色的基因链为交付团队的持续交付环,红色的基因链为平台团队的持续交付环。两种团队以某种低耦合的弱连接进行全程协作,Platform团队在整个端到端的交付过程中都要能尽量通过构建自动化能力来支撑交付团队能够快速、安全的进行持续集成、部署等活动。这样的合作方式也给我们提供了优化触点的可能性,也能够通过优化和改进,缩小这个持续交付周期,让交付更高效。
实践过程
下图是我们为团队设计的持续交付流水线,目的是能让Platform团队和交付团队之间的触点能够被融入到持续交付流水线中,并且以基础设施代码作为协同媒介,通过自动化的方式实现开发与运维(即基础设施与软件系统)的无缝对接。
我们来看看我们给持续交付流水线赋予了哪些能力:
- 站在交付团队的视角,我们决定将基础设施构建,流水线构建,部署等活动都代码化,与应用代码放在同一个代码仓库中。
- 交付团队通过提交我们的基础设施代码到仓库后,自动触发持续交付工具创建或更新流水线。
- 接着会自动触发构建,静态检查,测试覆盖率校测,代码规范验证等任务,最终输出构建产物并将构建产物推送到仓库。
- 然后会根据交付团队对基础设施和环境的定义到当前要部署的网络环境中去创建或更改虚拟机、网络、存储方式等
- 最后,当基础设施创建成功以后,就会去仓库下载指定版本的构建产物进行最终的部署活动。
但需要注意的是:
- 为了持续优化交付流程,我们对开发的许多活动进行的数据收集和分析,以报表的形式去分析展示代码提交频率,系统和代码的质量情况,缺陷和构建情况等,帮助团队找到自己的瓶颈或问题。
- 帮助团队能够实时监控自己应用的运行状态,设计和查看不同纬度的日志总汇等。
那我们来看看通过什么技术可以实现这样的持续交付流程:
我们选择了一种轻量级、低耦合的技术组合Ansible+Jenkins+AWS。我认为其核心是Ansible。
下面我们来看看Ansible可以帮助我们做些什么:
- 创建和更改AWS中的资源
- 自动化部署和基础设施测试
- 建立开发与平台团队之间的沟通体系
考虑到基于yaml语法的Ansible配置简洁且易读,所以我们选择直接用它作为提供给交付团队的公有DSL模板,利用Ansible Playbook的模块化思想将开发团队的职责和平台团队的职责很清晰的分离,平台团队关注Ansible提供给交付团队的服务是否满足需求和DSL模板是否易用,而交付团队只用关注如何基于公有DSL去定制自己的基础设施,环境依赖和部署等。
于此同时也满足了很多开发对于Ansible和AWS的兴趣和热情,更使得之后在交付团队落地变得更容易。
接下来通过一个实例来看看:
左边是Platform团队的仓库,这个仓库里面包含了创建基础设施、环境配置和部署的实现。
右边是交付团队的仓库,其中deployment目录下,是公有的DSL模板,其中包含多种环境(开发、测试、预生产环境等的独立配置),以及一套基于DSL的代码模板,其中包含创建基础设施和部署应用这两部分DSL代码模板。
接下来,我们来看看它们配合与集成的方式:
他们会在持续集成流水线中被动态组合到一起:
- 在创建基础设施和部署的时候会分别拉取基础设施代码库和应用代码库。
- 此时应用代码为调用入库,公有基础设施为功能框架库,两者配合,完成环境的创建和应用部署。
在做微服务的团队,接受度非常高,能够快速上手,而且甚至有团队因为自身的一些需求,自己去写一些Ansible模块,然后向我们发起pull request。
当然,我们在推广这套流程的过程中发现,一些实践能够帮助我们更快速落地:
- DevOps团队的成员由各交付团队和原运维团队组成,这样的组成方式,能够保证团队的视角可以关注到整个持续交付过程的每个环节。
- 交付团队成员与DevOps团队成员定期轮岗制,DevOps小组中的文化(如自动化优先)可以蔓延开,让交付团队更快适应。
- 结对、Showcase和培训,主要目的是知识的传递,让更多地团队逐步采用新的交付模式,得到更多改进中的反馈。
- 提供给交付团队的自服务代码仓库对每个人开放,交付团队被授权优化、新增基础设施,让DevOps文化和职责落地到交付流程中。
现在来看,集中式、审批式、被动响应请求的中央运维团队不再是整个交付流程中的依赖和瓶颈,已基本转向带自服务化、审查式、主动优化的去中心化交付团队:
我们通过技术驱动改进,让团队之间的合作方式发生了巨大改变,开发与运维之间的那道墙也渐渐消失,以前被动响应请求中央运维团队逐步被平台团队所替代,平台团队中一部分人会负责基础设施平台的发展,负责公有云与企业内部系统的对接、完善安全、灾备、提供基础设施的自服务机制,另一部分人会为产品团队提供可定制的工作、平台、并为产品团队赋能。这时交付团队开始管理自己的环境、维护流水线、负责生产环境变更。
在推广和落地自服务持续交付流程的过程中,我们也遇到了很多遗留系统和复杂部署应用的交付团队,他们无法直接对接这套交付流程。
例如有一个40-50人的团队,它是基于AEM开发整个公司所有的前端门户,AEM是Adobe公司的CMS系统,其安装和部署很复杂,以前都是通过手工安装和拷贝的方式进行部署,而且他们在开发-》测试-》部署阶段可能会动态扩张多套环境来支持,且每次代码变更的提交都会对已经安装的AEM进行修改、配置、重启等操作。
整个开发和测试流程都很复杂,而且效率很低,出现问题和故障的风险也很大,如果我们直接利用Ansible把AEM的安装和部署过程都自动化,由于AEM本身部署的复杂性,可以预见以后这部分更新和维护的工作还是很难交由交付团队自治。所以我们第一步要做的就是为其设计新的持续交付流水线,然后在这个流程中去定义和识别两个团队的职责和关注重心,最后再通过打造高效的自服务使整个交付流程得到改进。
首先我们根据校服团队提交变更的平率,从低到高依次定义了三条持续集成流水线(如下图):
- 创建和测试基础设施资源
- 配置基础设施资源和环境
- 部署应用程
因为AEM安装和更新很复杂,所以我们引入了镜像技术。基础设施和基础设施配置两条流水线的产物为一个image,应用流水线在部署阶段会去检查是否存在新的环境镜像,如果存在,就会基于快速创建一个新的AEM环境,然后进行应用代码的部署。
通过新的自动化持续交付流水线大大加速了AEM团队的开发和测试速度,也使得整个环境更加可控和易维护。对于交付团队来说,他们可以自己去维护包括基础设施、环境变更和应用部署等全生命周期交付活动。对于Platform团队来说,只用去考虑镜像的生命周期管理,如何去优化镜像的创建速度等,这些可以帮助到更多其它团队解决类似问题的领域。对于这种特殊情况,我们尽管引入很多与大多数团队不同的交付流程和技术,但所有的工作和优化都是基于之前打造的自服务持续交付流程、协议和工具平台之上的,保证了不同的交付团队与Platform的配合方式的一致性。
实践启示
通过在大量交付团队落地基于自服务的持续交付流程,两种团队的职责更加清晰了:
所有好的实践都必须考虑规模化的问题,如果无法大规模的被接受和落地,再好的实践也没用。对于咱们这个转型的过程,我也给出一个套路:(如下图)
有了套路,接下来总结一下应用这个套路进行DevOps转型过程中的一些经验和思考:
- 易用的通用DSL模板设计,提供交付与Platform团队统一的DSL模板(build and update anything)。
- 构建通用持续交付流水框架,提供给交付团队定制化流水线的能力,使流水线主要关注点始终在产品的成功交付。
- 以技术驱动DevOps文化大面积传播,让Platform团队成员走入交付团队,协作改进、知识传递,确保实践落地。
- 将一切自动化、自服务化。交付团队应该被授权优化、新增基础设施服务,让DevOps能力和职责在交付团队落地生根。
最后,我提取了5点对我们来说非常重要的策略或是推进方法:
- 小步快跑,在有大方向的基础上,需要将每一步改变都设计得足够小,这样才能足够快的去改进。
- 交付团队赋能,给每个人都留一扇门,在他意识到要做些事情的时候,可以很快付诸行动。
- 逐步用基础设施自服务化替代运维部门的审批流程。
建立持续反馈和改进机制。 - 以DevOps团队为杠杆,撬动更大范围自服务交付。