持续交付是最早由Jez Humble和David Farley提出,并在“持续交付:发布可靠软件的系统方法”一书中对其实现进行系统说明。
持续交付其实描述的是软件开发,是从原始需求识别到最终产品部署到生产环境这个过程中,需求以小批量形式在团队的各个角色间顺畅流动,能够以较短地周期完成需求的小粒度频繁交付。频繁交付周期带来了更迅速的对软件的反馈,并且在这个过程中,需求分析,产品的用户体验和交互设计、开发、测试、运维等角色密切协作,相比于传统的瀑布式软件团队,更少浪费。
持续交付是经典的敏捷软件开发方法的自然延伸,以往的敏捷方法并没有过多关注开发测试前后的活动,例如前期的需求分析,用户的体验设计,产品的部署和运行维护,随着敏捷的很多思想和原则在前后端领域的运用和升华,以及UX、DevOps等实践的逐渐兴起,在持续交付这个新的大概念下看到了敏捷方法和更多实践活动的结合和更大范围的应用。
上面都是对持续交付的定义,对于持续交付以及持续部署等概念的解读,个人认为核心就是一句话:将技术与业务解耦。
目前较为认同的是DevOps Handbook上对持续交付、持续部署的定义是:“持续交付是指,所有开发人员都在主干上进行小批量工作,或者在短时间存在的特性分支上工作,并且定期向主干合并,同时始终让主干保持可发布状态,并能做到在正常工作时段里按需进行一键式发布。开发人员在引入任何回归错误时(包括缺陷、性能问题、安全问题、可用性问题等),都能快速得到反馈。一旦发现这类问题,就立即加以解决,从而保持主干始终处于可部署状态。”
“持续部署是指,在持续交付的基础上,由开发人员或运维人员自助式的定期向生产环境部署优质的构建版本,这通常意味着每天每人至少做一次生产环境部署,甚至每当开发人员提交代码变更时,就触发一次自动化部署。”
“持续交付是持续部署的前提,就像持续集成是持续交付的前提条件一样。”
这里面涉及到的有几个层面:持续集成、持续交付、持续部署,以及持续发布。下面分别给大家介绍;
持续集成(Continuous integration,简称CI),简单来说持续集成就是频繁地(一天多次)将代码集成到主干。每次集成都通过自动化的构建(包括编译、发布、自动化测试)来验证,从而尽快地发现集成错误。
持续集成的过程:先把代码放到git、Jenkins从git获取代码进行构建、测试、生成结果再返回给客户端。
持续集成强调开发人员提交了新代码之后,立刻进行构建、(单元)测试。根据测试结果,可以确定新代码和原有代码能否正确地集成在一起。
持续集成的目的:
让产品可以快速迭代,同时还能保持高质量。它的核心措施是,代码集成到主干之前,必须通过自动化测试。只要有一个测试用例失败,就不能集成。
持续集成并不能消除 Bug,而是让它们非常容易的发现和改正。
持续交付(Continuous Delivery,简称CD)指的是:频繁地将软件的新版本,交付给质量团队或者用户,以供评审。如果评审通过,代码就进入生产阶段。
持续交付是在持续集成的基础上,将集成后的代码部署到更贴近真实运行环境(类生产环境)中。比如,我们完成单元测试后,可以把代码部署到连接数据库的Staging环境中更多的测试。如果代码没有问题,可以继续手动部署到生产环境。下图反应的是CI/CD 的大概工作模式。
持续交付是经典的敏捷的软件开发方法的自然延伸,它强调产品在修改后到部署上线的流程要敏捷话、自动化。甚至一些较小的改变也要尽早的部署上线。通俗的讲可以有几个特点:
持续部署(Continuous deployment)是持续交付的下一步,指的是代码通过评审以后,自动部署到生产环境。
持续部署的目标是:代码在任何时候都是可以部署的,可以进入生产阶段,持续部署的前提是能自动化完成测试、构建、部署等步骤。
持续测试是贯穿整个内部研发流程始终的,从持续集成到持续部署,都有自动化测试的存在。
“没有自动化测试,持续集成就只能产生一大堆没有经过编译并且不能正确运行的垃圾”。自动化测试是持续集成的基础,同样也是其他实践的基础,越靠前的测试越应该自动化。
测试是获取反馈最有效的方式,从部署流水线中,能够看到在不同的环节,不同环境上运行的不同层面的测试。
从理想的测试自动化金字塔来看,截止到持续交付阶段,在开发环境、测试环境以及类生产环境,已经把开发内部需要运行的所有测试全都跑完了。
所以在这个点,从技术的层面上讲,代码是可以被部署到生产环境的;从业务的层面上讲,需要判断是否发布特性给用户,以获取最终的用户反馈。
代码提交阶段也称为版本控制。提交是将开发人员编写的最新更改发送到代码仓库的操作。开发人员编写的每一个版本的代码都是无限期存储的。在与合作者讨论和审查更改之后,开发人员将编写代码,并在软件需求、功能增强、错误修复或更改请求完成后提交。管理编辑和提交更改的代码仓库称为源代码管理(SCM工具)。开发人员在提交代码(代码推送请求)后,代码更改将合并到存储在中心代码仓库(如GitLub)中的基本代码分支中。
使用GitHub、Gitlab、SVM、BitBucket等工具都可以
开发人员编写代码并将其推送到代码仓库后,系统将自动触发以启动下一个代码分析过程。想象一下这样一个步骤:提交的代码可以直接构建,而在构建或交付期间失败。就机器和人力的资源利用率而言,这都是一个成本昂贵的缓慢过程。组织必须检查代码中的静态策略,静态应用程序安全测试(SAST)是一种白盒测试方法,可以使用SonarQube、Veracode、Appscan等SAST工具从内部检查代码,以发现软件缺陷、漏洞和弱点(例如SQL注入等)。这是一个快速检查过程,其中检查代码是否存在语法错误。尽管此阶段缺少检查运行时错误的功能,但该功能将在以后的阶段中执行。
持续集成(CI)过程的目标是进行常规代码提交并不断构建二进制工件。持续集成过程通过检查添加的新模块是否与现有模块配合良好,有助于更快地发现错误。这有助于减少验证新代码更改的时间。生成工具根据用于编写源代码的编程语言来帮助编译和创建可执行文件或程序包(.exe、.dll、.jar等)。在交付期间,还将生成SQL脚本,然后与基础设施配置文件一起对其进行测试。总之,构建阶段就是编译应用程序的阶段。作为构建过程一部分的其他子活动是工件存储、构建验证和单元测试。
使用Jenkins、Bamboo CI、Circle CI、Travis CI、Maven、Azure DevOps等工具可实现
发布构建过程后,通过一系列自动测试将验证代码的准确性。这一阶段可帮助避免生产中的错误。根据构建的规模,这种检查可能持续数秒至数小时。对于由多个团队提交和构建代码的大型组织来说,这些检查在并行环境中运行的,以节省宝贵的时间,并尽早将错误通知开发人员。
这些自动化测试由测试人员(或质量保证工程师)设置,他们根据用户案例设置了测试用例和场景。他们执行回归分析和压力测试以检查与预期输出的偏差。测试涉及的活动包括健全性测试、集成测试、压力测试。这是一种非常高级的测试。在这里,可以发现开发人员可能未知的问题。
使用Selenium、Appium、Jmeter、SOAP UI,、Tarantula等技术实现
集成测试是使用诸如Cucumber、Selenium等工具执行的,其中将单个应用程序模块组合并作为一组进行测试,同时评估是否符合指定的功能需求。在集成测试之后,需要有人批准该组中的更新集应该移动到下一阶段,这通常是性能测试。这种核查过程可能很繁琐,但它是整个过程的重要组成部分。在测试过程中出现了一些新的解决办法。
负载平衡和压力测试也使用自动化测试工具(如Selenium、JMeter等)执行,以检查应用程序运行是否稳定,并且在高流量环境下是否良好。由于全面的压力测试是长期运行的,因此通常不会在每次更新上运行这一测试。当要发布主要的新功能时,将对多个更新进行分组,并完成完整性能测试。如果将单个更新移动到下一阶段,则管道可能包括金丝雀测试作为替代。
在测试阶段完成之后,标准的代码准备部署到服务器中,这些代码将与主要应用程序集成。在部署到生产中之前,他们将被部署到测试/暂存或产品团队内部使用的测试环境中。在将构建移动到这些环境之前,构建必须经过两个子库,其名称为Bake和Deploy。这两个阶段都是Spinnaker所固有的。
使用Spinnaker、Argo CD、Tekton CD等技术
Bake是指从源代码中创建一个不可变的映像实例,该实例在生产环境中具有当前配置。这些配置可能是数据库更改和其他基础设施更新之类的内容。Spinnaker可以触发Jenkins来执行这个任务,而有些组织更喜欢使用Packer。
Spinnaker自动将Bake的映像传递到Deploy阶段。这是将服务器组设置为部署到集群的位置。与上述测试过程类似,在Deploy阶段执行功能相同的过程,首先转移到测试阶段,然后转移到产品环境,最后进行批准和检查。其整个过程由Spinnaker之类的工具处理。
这也是组织的团队优化整个CI/CD流程的关键位置。因为现在已经进行了大量的测试,所以失败很少见。但是,此时必须尽快解决所有故障,以最大程度地减少对最终客户的影响。团队也应该考虑使流程的这一部分自动化。
使用蓝绿部署、金丝雀分析、滚动更新等策略部署到产品。在部署阶段,将监视正在运行的应用程序以验证当前部署是否正确或是否需要回滚。
为了使软件发行版具有故障安全性和健壮性,在生产环境中跟踪发行版的运行状况至关重要。应用程序监视工具将跟踪性能指标,例如CPU利用率和发行版延迟。日志分析器将扫描由底层中间件和操作系统产生的大量日志,以识别行为并跟踪问题的根源。如果生产中出现任何问题,将通知利益相关者以确保生产环境的安全性和可靠性。此外,监视阶段可帮助组织收集有关其新软件更改如何为收入贡献的情报,帮助基础设施团队跟踪系统行为趋势并进行容量规划。
使用Zabbix、Nagios、Prometheus、Elastic Search、Splunk、Appdynamics、Tivoli均可实现