关于持续交付你准备好了吗?

这里讨论一下关于实现交付过程中的一些原则和实践。大部分观点来自-持续交付(发布可靠软件的系统方法)

持续交付理论要解决的最重要的问题就是,如何以最快的方式将我们的软件交付到客户手上;如何实现可靠,迅速并且低风险的软件发布

在传统的软件开发方法中我们更多的关注软件研发环节,而DevOps运动则将软件研发活动的视角从传统的需求,开发,测试等活动延伸到了部署,发布以及运维过程中。

软件的核心价值是为软件的使用者带来收益,在过去我们经常听到开发人员说这个功能已经开发完成了。 但是在持续交付中我们认为之后将特性真正的发布到用户手上才以为则完成

image

持续交付

而要想达到持续交付的目标即实现可靠,迅速并且低风险的软件交付需要所有相关人员(需求,开发,测试,运维)的协同工作才能保证这一目标的实现。

在持续交付过程中我们希望一个团队是能够充分自治的,能够完成从软件的需求,设计,开发,部署以及运维的端到端所有工作。

image

全功能团队

持续交付的基本原则

本文将以持续交付的8个原则来阐述在持续交付过程中的那些方法和实践

原则一 为软件的发布创建一个可重复且可靠的过程

在传统的软件研发模式中瀑布式的工作方式深入到软件研发的各个环境。

在软件的发布过程中充满了各种等待:

  • 构建和运维人员在等待说明文档或者缺陷修复
  • 测试人员等待“好的”版本构建出来
  • 研发团队可能在新功能发布几周后才收到缺陷报告

image

最终的结果就是软件产品迟迟不能发布甚至延期,同时由于开发与测试,开发和运维之间的过长的反馈周期直接导致软件产品的质量低下,同时可能并不能真正的为使用者带来价值

同时如果管理者想要对整个软件交付过程进行改善将会很容易陷入到局部优化的恶性循环当中,很难真正了解交付的问题瓶颈

而持续部署流水线则是解决这一问题的最佳方式,建立持续部署流水线即建立了一套端到端的软件交付流程,同时在持续部署流水线的流程当中参与到软件交付的各个角色都能各司其职,形成一套高效的“拉动系统”

image

开发人员持续的查看代码度量数据以及测试失败等问题,测试人员自助部署测试环境,同时运维人员也可以通过一键方式将软件部署到预生产环境以及生产环境。同时对于管理人员也可以通过度量持续部署流水线的各个环境来分析交付问题,通过合理的方式优化软件交付流程当中存在的问题。

而将持续部署流水线中的各个环节可以划分为如下几个不同的阶段

image

  • 提交阶段

该阶段主要从技术层面证明软件系统是可以工作的,该阶段会进行软件的编译,以及以单元测试为主的自动化测试,以及代码分析

  • 自动化验收测试阶段

该阶段主要从功能和非功能需求角度正面软件是能够满足用户的需求以及相关的需求验收条件

  • 手动测试阶段

该阶段主要试图发现那些自动化验收测试不能覆盖的缺陷,同时证明系统是否能够真正的为用户提供价值,所以在该阶段中通常需要由测试人员完成相关的探索性测试,集成测试以及用户验收测试

  • 发布阶段

发布阶段则旨在将软件产品发布到用户手中包括软件包发布或者是直接将软件部署到生产环境

原则二 将几乎所有事情自动化

为了搞笑的支持持续部署流水线,我们需要将除了探索性测试以外几乎所有的事情都自动化。

在软件交付过程中对于自动化我们可以分为两个方面,一方面是指在产生软件包过程中的如:编译,打包,单元测试,集成测试,自动化验收测试等活动。

  • 自动化构建

在这个过程中我们使用例如maven,gradle这样的构建工具可以帮助自动化的完成软件的构建以及解决软件依赖问题

  • 自动化测试

同时借助诸如robotframework,以及cucumber这样的自动化测试工具,以及采用BDD或者ATDD的开发实践能够帮助我们产生高质量的自动化验收测试集

  • 基础设施及代码

在虚拟化技术和容器化技术盛行的今天,通过诸如AWS的CloudFormation以及Docker的Dockerfile等我们可以将我们的基础设施也变成自动化的

另一方面则涉及到与软件运行相关的自动化如包括基础设施的自动化管理,运行环境的自动化配置,软件本身的安装与配置等等

  • 自动化配置管理

自动化配置管理工具如ansible,puppet,chef等相比传统的脚本。通过dsl环境描述的过程将服务器环境的准备过程变成自动化的,可重复的,并且能够支持大规模的集群管理

原则三 把所有东西都纳入版本控制

在过去通常而言我们的svn或者git当中只存在我们源代码本身,而在持续交付过程当中我们认为任何会对软件的行为,质量产生影响的部分都应该要做版本化的,并且这些任何部分的每一次变更都应该通过持续部署流水线的形式来进行自动化的验证。确保任何的变更,如代码变更,测试用例变更,环境配置变更都能得到快速的验证,以及反馈

这些相关的“变更集”包括:基础设施描述文件,源代码,测试脚本,自动化测试用例,环境配置脚本,部署脚本,以及数据库的创建,升级,以及回滚脚本等。

从上面的“变更集”也可以看出,持续交付是一个团队所有人员和角色都应该参与的事情,并且每一个人都对软件交付富有责任

原则四 提前并频繁的做让你感到痛苦的事情

“如果集成是让你感到痛苦的,那么每一次代码提交都应该进行集成,而且应该从项目一开始就开始这么做;如果发布软件过程前测试是一件痛苦的事情,那么就应该从项目一开始就不断的进行测试;如果软件发布是一件痛苦的事情,那么每一次代码提交在完成自动化验收测试之后都应该进行发布,或者至少发布到类生产环境”

image

原则五 内建质量

在持续交付过程中持续交付流水线定义了一套标准的,可重复的软件交付流程;同时借助大量的工具我们可以将这个流程中的机会所有事情都进行自动化。但是另外一个点就是软件质量。

image

根据原则四,其实我们也可以推断出如果对代码进行测试是一件痛苦的事情,那么在编写实现代码之前我们就应该写测试,TDD,ATDD,BDD等软件研发实践正是体现了这一基本原则。

内建质量是戴明提出的名言之一。越早的发现缺陷,修复它们的成本越低。

根据内建质量的原则我们可以知道在软件交付过程中,测试并不是一个阶段,所以并不应该在开发介绍之后才开始。同时测试也不应该主要是测试人员的职责,参与交付的所有人都应该对软件的质量负责

其中测试四象限很好的阐述了为了确保软件质量而应该做的各种类型的测试建模

image

原则六 “Done”意味着“已发布”

在持续交付过程中认为一个特性的交付在理想状态下应该是已经发布到用户手中,或者至少已经向用户进行了演示。

相应的在敏捷开发中,我们每一个迭代结束后都应该想”用户代表”进行演示,并且在“用户代表”试用认为是完成了之后才意味则“Done”

其中“用户代表”可以是正在的用户,也可以是相关的业务人员

原则七 交付过程是每个成员的责任

在现实情况下,测试部门总是抱怨研发交付的软件质量差,运维总是抱怨软件不够稳定,开发总是抱怨缺陷反馈周期太长,解决问题的成本过高。

而在持续交付当中我们知道,对于交付团队而言最终目标是确保软件能够交付到用户手中,并且产生相应的价值。

而通过持续部署流水线,我们将所有参与到软件交付中的角色都联合成了一个整体,并且各个部分之间是能够快速的产生反馈,促成各个成员和角色之间的交流,并且快速的解决问题

image

原则八 持续改进

在任何一个充满生机的组织当中持续改进是这个组织保持活力的基本要素之一。

参与软件交付的成员需要定期对过去一段时间内的交付工作进行回顾,去发现在这个流程当中的做的好的方面,以及做的不好的方面,并且提出解决方案。

持续交付组织应该做好哪些准备?

交付团队而非部门

根据康威定律“设计系统的组织,其产生的设计和架构等价于组织间的沟通结构”

由于存在部门墙的存在,导致开发,测试,运维之间的大量沟通成本,严重影响效率。甚至严重时部门和部门之间甚至会非常容易起冲突。

开发人员只管完成既定的功能缺乏系统整体性思考;测试人员根据需求文档完成测试用例,但是却不思考需求本身的合理性;运维人员则缺少对软件架构本身的理解。各个部门看似各司其职进井有条,但是却很难对软件交付的效率和质量做出太多实质性的贡献。正如开篇所述,

而通过“交付团队”从项目一开始让所有项目成员能够参与到软件的交付过程中,确保各个角色的人员能够频繁的进行交流,并且为了一致的目标而共同努力,这也是DevOps运动核心价值

而相同角色之间的沟通交流通过社团COP的形式来进行领域知识的交流和提升是一个不错的方式

充分授权团队

确保持续交付实践的成功,赋能团队,授权团队也是整个组织应该思考的问题。在持续交付中我们知道一个团队是一个应该是以做产品而非做项目为目标,需要充分授权团队,使得团队能够完成从需求,开发,测试,上线的端到端过程。

当然在实际情况中,组织会有更多的因素需要考虑,比如最典型的场景比如由于落后的基础设施管理方式导致运维团队往往是被动的响应研发团队的需求,并且存在大量手动的操作环节导致时间和资源的浪费

平台化,服务化

  • 公有云,私有云,容器云

通过组织级别引入虚拟化或者容器化技术以及相应的管理平台如OpenStack,Rancher,Ks8等工具可以大大减少Ops团队的运维团队,在过去需要大量手工操作的过程都可以通过虚拟化平台或者容器化平台完成,研发团队或者资源的周期从之前的几天缩短到几分钟。

  • 基础设施自服务

同时对于Ops团队则专注于提供底层的基础设施资源,包括网络,安全等相关管理。并将相关的资源以服务的形式暴露给团队,各个产品团队管理自己的基础设施环境,维护持续部署流水线,以及软件运行环境的变更

  • 平台化服务

同时对于企业和组织而言通过引入统一的平台化服务,可以完成对所有产品团队的统一管理,和监控。这些关键的平台化服务可能包括:统一的日志管理平台,持续交付平台,以及监控和运营平台等。

image