探索中的持续部署

持续部署随着敏捷的发展而受到社区的更多关注,@常新居士在酷壳上发表的《持续部署,并不简单!》一文中对此作了深入的分析和经验分享。 

作者@常新居士首先对持续部署适用的场景做了总结:

  • 功能要及早交付
  • 功能在部署到生产环境前要先部署的一个测试环境
  • 功能必须经过测试
  • 要减少后期维护的工作
  • 支持协同开发

那么,面对复杂的项目环境,持续部署需要解决那些问题呢?

  • 场景1:环境升级
    项目A和项目B都依赖于Web容器,公司决定升级Web容器版本,而公司要升级的机器有上百台,依赖人肉升级已不现实,维护团队因此针对各种软件开发了相应的自动化脚本,但当新的软件出现时,必须要开发新的脚本。而且当同时升级若干环境软件时,则难度随之增大,手工调度的方式极易出错,当升级失败时仍需要大量人工处理。由于存在大量升级脚本,有一定的维护成本。
  • 场景2:依赖于环境的软件升级与回滚
    针对环境升级,公司为项目A和项目B开发了新的版本。但环境的升级和软件的升级不是同步进行,出错的可能性非常大(想一想间接依赖和多重依赖的情况)。当新版本部署到生产系统时,发现问题,需要回滚到之前的版本——所有运行时版本都需要回滚,而且环境也需要同步回滚。几百台机器……
  • 场景3:运行时依赖
    之前,我们将所有的运行时依赖都打包到一起。当项目依赖关系复杂时,这样产生的包将非常臃肿,潜在地延长了部署的时间(想一想有几百台服务器,一个部署计划需要部署几百兆文件的情况),而且产生冲突的可能性非常大,而且对于不同类型的项目(Java和Ruby项目)缺乏通用性。06年左右,Nortel可是拿Excel统计过运行时依赖的,牵涉若干项目组,反复多次,没有个把月真搞不定。
  • 场景4:泛滥的部署
    每个项目相关的持续集成环境都需要开发自己的部署脚本,重复投入大,而且各个项目的部署过程不一致,并且对于同一个项目无法同时满足不同目的部署要求,例如,环境或系统配置参数改变后,无需安装包,只需做清理和激活的工作。最后,持续集成只是支持了和代码修改有关的部署。
  • 场景5:不一致的环境
    简单项目中,开发环境和运行环境都由开发人员搭建,当公司变大时,系统的运行环境将由运维人员搭建,而开发环境如果由运维人员搭建则工作量太大,由开发人员自己搭建则操作复杂又容易产生不一致的情况。
  • 场景6:热切换
    对于某些部署,需要尽量减少服务的停止时间,需要在服务的同时进行部署。

随后,@常新居士提出了解决办法,比如“环境 = 软件包 + 配置信息”:

在这个定义下,我们就必须将运行环境的软件解构,并以包的形式导入到公司的整个项目资源库中,比如Apache将作为一个包被导入,而Apache依赖的其它包也将依次被导入,并建立起正确的依赖关系。而且,在导入的过程中还必须做些相应的调整,如,环境变量的读取和设置,必须来自于环境配置模块,而不要修改系统的环境变量,防止不同环境在系统环境配置上相互影响和依赖。

部署,一次部署可能会产生一个环境实例。一系列部署将产生对应于环境目标的多个环境实例,除去当前起作用的环境实例外(最新的),其它的是历史环境实例。通过在历史环境实例中切换,我们自然而然的就可以使整个环境回滚,因为项目所依赖的一切都已经成为的环境中的软件包,而且环境依赖的包的版本会随着部署具体确定下来。

建立逻辑软件包版本和版本库中软件包版本间的关系;为相互依赖的包编译并打上统一的标签;简化运行时包依赖关系的生产;简化运行时包依赖的指定(可参考apt-get和RubyGem,环境只需指定直接依赖的包,间接依赖的包从运行时依赖树中自动导入)

由于我们已经将部署作为环境管理的一部分,而环境又是对外提供服务的最小实体,因此,对环境的部署就是要根据部署的类型,在环境上按一定的步骤执行一系列操作,从而使环境置于部署类型所要的状态,这个过程中可能会生成对应的环境实例。举例来说,我们可能会修改环境相关的一些配置,然后重启环境,显然,这种情况下不需要下载安装软件包(没有改变),因此也就不需要生成环境实例。

@左耳朵耗子在文章的最后提出了一些自动化部署会遇到的问题:

  • 部署系统的性能问题。
    几百号人不停地在把他们的软件部署到自己的机器上,部署到测试环境,部署到生产环境,一天之内一个人可能会要部署N次,回滚N次,不但有大量部署请求,还有大量的文件在网络上传输。你得想想这套部署系统如何解决这些性能问题,还得考虑未来更大规模的性能水平扩展问题。
  • 目标机环境的管理。
    在目标运行机上需要解决几个问题:1)两个环境间如果有一些的一样的包,那就没有必要再下载了,这样可以节约时间。2)每次部署都需要把老的部署环境给保留下来,这样方便在新旧环境下的切换。这两点对于在生产环境下部署非常关键。(这需要环境内所有软件的绿色安装才能更容易达到这个目标,因些,Unix/Linux会比Windows更容易做到这点)
  • 部署一致性事务问题。
    有时候,我们需要同时部署若干台服务器,比如:包A到机器MA,包B到机器MB,包C到机器MC,……(Web Service的SOA架构),这些包之间有运行依赖性和兼容性问题,要么一次性全部完成,要么就全部失败。回滚也是一样的,这是一个部署事务或部署一致性的问题。如何解决呢?
  • 部署环境的版本控制问题。
    前面说过,我们的一个环境就会和若干个包的版本耦合,环境必需管理要部署的包的版本。于是,当你的部署越来越多的时候,各个环境的包的版本开始出现混乱,各种依赖间的版本也会出现不统一的情况,也就是说,就算你有这样的一个工具,在一个高速开发的环境下,我们的部署环境的管理还是会出现很多混乱的情况,需要你不断地统一大家的开发、测试环境。

读者朋友在实际工作中对持续部署有何经验和看法呢?

你可能感兴趣的:(探索中的持续部署)