1、软件开发最终的交付产物是什么?
2、代码是如何构建成二进制软件执行包的?
3、软件执行包是如何部署的?
4、如何搭建一条高效稳定的构建部署流水线?
5、如何衡量构建部署的效率?
6、不同开发模式的构建部署方式有何差别?
7、构建部署发挥着怎样的作用?
编译,打包,部署,仓库搭建,二方/三方库,部署记录,docker ,k8s,开发模式,CI/CD,DevOps,GitOps
在整个工程生命周期中,我们经历了需求分析,业务建模,架构设计,组件设计后,终于把设计稿变成了一行行代码,接下来的就是怎么把代码变成我们想要的软件系统。我们知道计算机是无法识别我们的文本代码的,也就是其实在这个时候我们交付的也只是中间产物,那么就需要把我们文本代码编译成计算机认识的机器码,然后执行才能生成我们要的交付软件,也即是本章我们要介绍的构建部署环节。构建部署才是直接输出软件交付产物的环节,那么如何才能搭建出稳定高效的软件构建部署平台,才是我们所要关心的。
不同开发模式决定不同的构建部署方式。首先我们先来回顾一下史前的开发模式,不同的开发模式决定不同的构建部署方式,传统开发模式有:瀑布开发、迭代开发、螺旋开发、敏捷开发。我们先简单对比下这四种开发模式的区别:
瀑布开发,要求各个阶段都需要完成规范标准,从需求到设计,编码,测试,部署都要完成统一的流程
迭代开发,不要求每一个阶段都最完美的,注重的是把主要功能先部署起来,以最少的时间成本先完成一个半成品然后再逐步优化
螺旋开发,循环地增加系统定义和实现的复杂度而降低风险,主要在风险控制,因此需要在部署上有高的稳定性要求
敏捷开发,敏捷开发要求在短时间内协同好团队成员,形成良好协作基础,构建部署上更加高频
一开始简单的软件系统,我们可能是一次性编码完成后就直接本地编译成二进制软件包,但是随着软件复杂度的提升和业务变更的频度提升,传统的开发模式已经渐渐退出历史舞台了,取而代之的是新兴的开发模式:CI/CD,DevOps,GitOps等开发模式。
在软件开发中,构建是将源代码文件转换为可以在计算机上运行独立软件的过程,并且产出二进制文件或者可执行文件。
构建分为几个阶段:
从代码库获取源代码文件
编译代码并检查依赖项
运行自动化的单元测试
相应的链接库,文件,代码等
成功加载以上文件后,便会构建和存储
输出构建日志
完成构建通知
软件构建通常第一次开始是全新代码的构建,然后后续持续开发部署会进行迭代式构建,所以也分为全量构建和增量构建
全量构建
全量构建是从头开始执行构建过程,它将建服务器未执行过所需的资源以整体作为输入,检查依赖关系,编译所有源文件并按顺序构建所有模块,最后将其组装到构建目标软件包中。
增量构建
增量构建复用已编译好的模块,检查并比较源文件,以及所有与目标文件有关的文件。如果在上次构建之后修改了任何依赖项,则将再次重建,否则,将重新使用上次构建的文件。
增量构建比全量构建更快,并且使用很少的资源,有多种触发构建的方法:
手动构建触发器
计划构建触发器
源代码库构建触发器
后处理构建触发器
构建计算机程序的过程通常由构建工具进行管理,生成应用程序通常需要以正确的顺序编译各种文件,如果特定文件中的源代码未更改,则无需重新编译。不同的技术栈有不同的构建工具,这里笼统的列举一些常用的构建工具:
Make
Ant
Maven
Gradle
Meister
Rake
SCons
Grunt
Phing
软件部署是使软件系统启动运行的过程。
发布(或撤销发布)应该可靠且尽可能简单
发布(或撤销发布)应该完全可追溯所有的变更日志
只有授权人员才能参与部署
在大多数组织中,开发人员和部署该版本的团队之间需要区分职责
任何未经授权的线上变更都应立即发现告警
具备完善的程序来检查生产中变更版本及变更部署包
部署流程应需要增加审批环节
部署清单
随着互联网的盛行,业务不断复杂化,部署软件也是一项复杂的任务。所以部署需要一份部署清单来指导整个部署流程,部署清单会表明在部署之前要完成的关键任务。
部署工具
借助适当的工具实现部署自动化,可以把控好软件部署的关键环节。比如下文我们要介绍DevOps或者CI/CD等部署模式都是需要应用到一系列不同的工具来实现高效的部署。
部署模式
目前比较流行的部署模式是CI/CD,CI获取源代码并将其打包到应用程序构件中,持续集成还采用了持续测试的原则,即团队不断收集反馈以尽快发现问题。
交付模式
集成代码并构建应用程序后,CD涉及打包和准备要部署的代码。应用程序被置于预发环境中,在交付阶段会进行严格的测试,以确保应用程序一旦部署便能正常工作,持续交付的目标是使应用程序始终准备好进行部署。
自动部署
部署是一个复杂的过程,手工完成部署会留出太多人为错误的空间,部署自动化减少了失误操作而且加快了部署速度,并使流程变得如此简单,部署自动化的最简单形式是使用脚本在特定上下文中在特定环境中部署特定操作,要获得更高级的自动化,则可以使用部署工具来完成。
指标监控
部署新版本的软件后,需要密切注意关键指标。常见的指标包括服务器利用率,异常率,日志量和数据库性能。如果存在性能问题,则需要了解问题的根源。诸如Retrace之类的APM工具可让监控指标并跟踪部署,以便在出现问题快速排查问题的根源。
回滚策略
并不是每一次部署都是成功的,即使有了周密的测试也总会发布异常的情况出现。这个时候快速止血采用回滚方式可能是需要优先考虑的。诸如Automic之类的发行自动化工具支持回滚,可以保留最新版本的备份副本或者上一次正常的代码分支,直到确认新版本可以正常工作为止。
不同技术栈使用不同的部署工具,之类就不一一列举。
0penstack
Jenkins
Kubernetes
随着DevOps的兴起,出现了持续集成,持续交付(CI / CD)和持续部署的新方法。传统的软件开发和交付方法正在迅速过时。从历史上看,在敏捷时代,大多数公司都会以每月,每季度,每半年甚至每年的版本来部署发行软件。但是,现在,在DevOps时代,每周,每天甚至一天多次都是标准。下面我们简单介绍下这集中不同的交付方式。
上文我们也提过敏捷开发流程,对应的敏捷交付就是在这种开发模式下完成软件交付。敏捷交付专注于消除传统冗长的流程障碍,并且让加速交付方面进行更紧密的协作,其基本原则是迅速生产可运行的软件,与客户紧密协作以及应对新的需求变更。
传统软件交付会安排在一天内将所有分支源代码合并在一起完成部署,最终可能造成工作繁琐、耗时,而且需要手动完成。持续集成(CI)可以帮助开发人员更加频繁地将代码更改合并到共享分支或“主干”中。一旦开发人员对应用所做的更改被合并,系统就会通过自动构建应用并运行自动化测试来验证这些变更,确保这些变更没有对生产环境造成破坏或者污染。这意味着测试内容涵盖了从类和函数到构成整个应用的不同模块。如果自动化测试发现新代码和现有代码之间存在冲突,CI可以更加轻松地快速修复这些错误。持续集成(CI)是一种软件工程实践,其中团队成员以越来越高的频率集成他们的工作。为了与CI保持一致,团队努力至少每天甚至每小时进行集成,以接近“持续”进行的集成。
让软件产品的产出过程在一个短周期内完成,以保证软件可以稳定、持续的保持在随时可以释出的状况。它的目标在于让软件的建置、测试与释出变得更快以及更频繁。这种方式可以减少软件开发的成本与时间,减少风险。持续交付的目标是拥有一个可随时部署到生产环境的代码库。在持续交付中,每个阶段都涉及测试自动化和代码发布自动化。
持续交付与DevOps的含义很相似,所以经常被混淆。但是它们是不同的两个概念。DevOps的范围更广,它以文化变迁为中心,特别是软件交付过程所涉及的多个团队之间的合作(开发、运维、QA、管理部门等),并且将软件交付的过程自动化。另一方面,持续交付是一种自动化交付的手段,关注点在于将不同的过程集中起来,并且更快、更频繁地执行这些过程。因此,DevOps可以是持续交付的一个产物,持续交付直接汇入DevOps。
指在软件开发流程中,以自动化方式,频繁而且持续性的,将软件部署到生产环境(production environment)中,使软件产品能够快速的发展。持续布署可以被整合到持续整合与持续交付的流程之中。对于一个成熟的 CI/CD 发布流水线来说,最后的阶段是持续部署。持续部署可以自动将应用发布到生产环境。
有时候,持续交付也与持续部署混淆。持续部署意味着所有的变更都会被自动部署到生产环境中。持续交付意味着所有的变更都可以被部署到生产环境中,但是出于业务考虑,可以选择不部署。如果要实施持续部署,必须先实施持续交付。
DevOps(Development和Operations的组合词)是一种重视“软件开发人员(Dev)”和“IT运维技术人员(Ops)”之间沟通合作的文化、运动或惯例。透过自动化“软件交付”和“架构变更”的流程,来使得构建、测试、发布软件能够更加地快捷、频繁和可靠。DevOps 集文化理念、实践和工具于一身,可以提高组织高速交付应用程序和服务的能力,与使用传统软件开发和基础设施管理流程相比,能够帮助组织更快地发展和改进产品。这种速度使组织能够更好地服务其客户,并在市场上更高效地参与竞争。
GitOps是一种声明式和云原生方法,用于利用版本控制的代码管理作为配置管理和基础结构。随着越来越多的公司转向基于云的复杂微服务软件体系结构,使用版本控制管理基础架构变得越来越重要。GitOps流程通常与容器化Kubernetes部署一起使用,因为该平台可以将声明性输入作为要争取的所需基础结构状态。通过使用Git,IT团队可以更轻松地处理配置管理和部署,因为GitOps使部署工作流程更接近开发人员。GitOps的主要好处是,通过具有集中的代码和配置,开发人员可以轻松地进行新更改或快速还原到以前的版本。
技术设置是应用的硬件设备,随着云原生的推广,基础设置的云化也是大势所趋,所以目前主要是云上资源的管理,这块众多云平台厂商也提供了服务器管理平台,那么基础设施层面需要聚焦的有如下几点:
机器申请
机器下线
应用扩容
网络变更
域名管理
安全外联
代码服务可以参考我们之前《代码治理》这一章,有代码全域详细的介绍。而在devops的场景下,代码服务则是提供稳定的代码服务器,这里我们首选gitlab作为我们代码的管理平台。
维护硬件和软件的最新记录的过程称为配置管理。目前比较主流的是使用诸如Chef,Puppet或Ansible之类的CM工具来进行辅助。
为了构建高质量的软件,必须在整个交付流程中不断运行自动测试和手动测试。自动测试包括以下各项:
单元测试:此类测试通常是单独测试一个方法、类或函数,让开发者确信自己的代码在按预期运行。为确保代码可以测试且测试易于维护,在编写代码之前先编写测试,这种方法也称为测试驱动开发 (TDD)。
验收测试:此类测试通常是测试整个应用,以确保更高层次的功能按预期运行,并且未引入回归错误。例如,验收测试可以针对某个用户案例检查业务上可接受的标准、某个 API 的正确性,以及原来运行正常的功能是否出错。此类测试的编写应该作为开发过程的一部分。除非已通过自动验收测试,否则任何人都不能达到代码开发完毕的标准。
DevOps团队将涉及服务生命周期的所有方面,从需求到规划,部署和维护。
构建部署整体流程如下:
• 提交给源代码管理系统的代码提交将触发构建服务器上的进程
• 此过程编译代码,将所需依赖包整合到可部署的程序包中
• 然后对这些软件包执行自动测试,以确保代码质量符合规范且执行结果没有问题
• 如果提交阶段成功,则将应用程序部署到测试环境,由质量保证团队对其测试
• 最后批准了该应用程序,则可以将该版本直接用于生产
监控告警服务可以参考下一章《监控告警》,梳理了全域的监控告警体系化构建流程。
最后我们用一张图来概括构建部署的核心流程。
关注公众号《编程原理》,升级你的编程知识体系