构建独立部署系统,从部署规范开始

发布于 2016年04月16日

作者:徐桂林,FIT2CLOUD(飞致云)首席布道师、东区总经理。

几个月前,我曾经写过一篇文章解释「为什么需要一个独立的部署系统」,并在其中说明独立部署系统需要解决的一系列问题。但是,如果需要构建一个独立的部署系统,我们应该从哪里入手,以保证整个部署系统能够落地到公司日常的业务上线流程中,并真正发挥其价值。简单来说,这个入手点就是部署规范。部署规范不仅仅定义了一个部署系统的实现细路,更重要的是其体现了该部署系统的价值取向及其背后的出发点。一旦部署规范定义出现问题,部署系统在企业内部落地就会成为很大的问题,而这是实现层面如何努力也很难弥补的问题。

什么是部署规范?

在解释部署规范之前,让我们先对部署行为有个一致的理解。个人把部署行为定义为:

部署是把一个可部署软件包安装到一个指定IT环境上并让其按预定流程提供服务的过程。

从上面这个定义来看,一个部署过程涉及到“软件包”、“IT环境”以及“部署流程”这三个主要要件。而部署规范正是要定义这三个主要要件的标准,以便让一个部署过程标准化、自动化并且可复制可预期。因此,部署规范的内涵就包括这几个方面:

  • 软件包规范:软件包(也称部署包)是一个部署系统的输入,对其规范是整个部署过程规范化的前提。一般来说,软件包的规范包括包内内容项以及其目录组织方式,该标准需要保障输入的软件包内容完整,意义明确。
  • IT环境规范:IT环境是最终提供服务的载体。在一个软件研发流程中常常会涉及到不同类型的环境(如开发环境、测试环境、生产环境等)。IT环境规范需要定义软件研发流程中的环境类型,每个环境包括的实体等。另外,定义好不同环境之间的升级和回滚标准也是非常重要的一步;
  • 部署流程规范:定义一个软件包在一个软件环境里面安装部署的流程规范。由于一次部署可能会在一个环境的多过节点上部署,所以部署流程规范的定义一般指一个软件包在一个环境节点上的完整部署流程。

在明确了部署规范的内涵,我们就可以展开讨论如何来定义一个好的部署规范,并以此为基础落地业务部署系统。

什么是一个好的部署规范?

当讨论一个部署规范的好坏,其判断标准经常非常模糊。就个人来说,部署规范的优劣在于它是否有助于落地企业的部署,能够让业务团队愿意使用该套规范来部署业务。如果从这个角度出发,我们会发现一个好的部署规范基本都会有如下几个特征:

  • 部署规范灵活,能够支持不同类型应用的部署。在公司内部,应用类型多样化是一个难以避免的问题。不同应用的场景不同,技术栈不同都会导致不同部署单元需要不同的部署方式。例如,web层有可能用Nginx,有可能用Appache。应用容器层有可能是Tomcat,也有可能是WebSphere。有些业务需要分布式部署,而有些组件用集中式方式会更合适。如果部署规范过于严格,或者和具体技术/场景绑定就会限制其使用范围,导致最后无法推广;
  • 部署规范非侵入,能够避免对业务逻辑的影响。在推进一个部署规范,业务部门最常见的一个担心就是该部署规范是不是会给业务团队带来较大的负担。因此,部署规范的非侵入性非常重要,尤其是要减少对于业务代码的直接修改和限制;
  • 部署规范易用,能够让不同背景人员都容易接受。一个业务系统的研发流程会涉及开发、测试和运维等不同角色,每个角色的技术背景和偏好都不太一样。所以部署规范需要容易上手,对于落地技术工具没有特别强的要求,最好是能够支持大家的最大技术公约数。

在日常工作中,我们可以看到各种部署工具及系统,而每套工具或者系统都会显式或者隐式引入一套部署规范。其中,最常见的一个问题就是规范要求过于严格、或者对于落地规范的技术要求过高,最终要不就是因为改造成本太大或者根本支持不了某些业务系统而被迫放弃。当然,如果走向另外一个极端,即部署规范太过于宽泛,也会导致无法自动化或者自动化代价太大,最后估计只能成为纸面上的规范。所以,部署规范的制定确实需要比较好的平衡,下面我就以亚马逊的CodeDeploy部署规范为示例来说明这种平衡。

CodeDeploy是其亚马逊云平台AWS的一个服务,它来源于亚马逊内部的部署平台Apollo。该部署平台支撑着亚马逊电商及AWS整个后台的部署工作。按照亚马逊CTO的博客透露,该平台在2014年一年执行了超过5000万次的部署任务,是一个亚马逊内部员工非常喜欢的工具之一。如你所想,该部署平台也引入了一个部署规范。具体来说,该部署规范包括如下几个方面:

  • 一个部署流程规范。在CodeDeploy里面,每个可以部署的组件被定义为一个部署单元。一个应用可以包括多个部署组件(如Web端组件、App逻辑组件等)。其部署流程规范定义一个部署单元在一个部署节点(一般为一台主机或者虚机)的部署流程。该部署流程规范如下图所示:

如上图所述,该部署流程由一组预定义的部署阶段组成,由用户给相关部署阶段提供部署脚本(hook)。如此,整个部署过程就是按照上图逐一执行每个阶段的部署脚本。整个流程非常简单直观,用户可以按照自己应用的需要组织部署脚本,且部署脚本的具体实现(语言选择、安装逻辑)都可以由用户自己选择。

  • 一个打包规范。为了落实如上部署流程,并且能够在部署包里面精确描述这个部署流程。CodeDeploy打包规范中引入一个描述性YAML文件,下面是该YAML文件的一个示例。

在打包一个部署包的时候,CodeDeploy要求在部署包的根目录提供如上YAML说明文件(命名为appspec.yml),并且在部署包里面按照YAML文件内部定义的相对路径存储所有部署脚本文件。下图即为一个符合CodeDeploy打包规范的部署包目录结构。

由于应用的每个版本部署实现都可能会有变化,所以CodeDeploy建议用户把如上YAML文件及所有部署脚本放到版本管理系统内统一管理,并随同项目代码同步演进,保证项目代码和部署代码能够持续有效。

通过如上分析,CodeDeploy部署规范整体比较灵活、易于上手,并且实施过程不会对业务系统有太大影响。现实工作中,很多团队为加速部署效率,都或多或少有了一些部署脚本,只是还没有完整的流程规范和系统来支撑整个部署过程。所以,如果采用类似标准实施,需要的改造成本不会太高。当然,CodeDeploy部署标准在环境管理上强绑定了AWS的基础设施服务(EC2、AutoScaling等),限制其只能在AWS上使用。

如何落地一个部署规范?

在解决了如何定义一个部署规范后,接下来的挑战就是如何落地这个部署规范,让业务部门能够接受它并用于日常部署工作中。在这个过程中,非常重要的一点就是要站在业务部门的角度分析投入产出比。尽可能的降低业务部门的投入成本,而最大化该投入带来的产出价值。无论是构建独立部署系统,还是在项目具体实施过程都可以从这个角度来分析。具体如下:

构建部署系统

当你需要通过一个独立部署系统来落地部署规范时,在该部署系统的设计过程中就需要充分考虑如何为业务部门降低投入、提高产出。例如,在降低投入方面可以尝试如下方面工作:

  • 使用好构建系统,让部署的打包规范能够在构建过程自动化落实,从而自动生成符合规范的部署包;
  • 对接好构建系统,让生成的部署包能够自动注册到部署系统中,从而在部署系统内自动实现部署包的版本管理;
  • 统一好不同部署环境,让一套部署规范和系统能够支撑对不同环境的统一部署,避免需要维护不同部署流程;

同样,在提升部署系统的价值上可以尝试如下方面工作:

  • 让部署系统能够自动化、批量分发部署任务,实现一键部署多台机器,大大提升部署效率;
  • 让部署系统能够可视化整个部署过程,包括当前部署任务的进度,每个部署节点的执行日志等;这样能让部署过程及结果集中查看,方便跟踪复杂的部署任务,尽快发现部署问题;
  • 提供不同的部署策略,支持不同环境的部署要求。例如,在开发、测试环境中可以让用户对目标环境中的所有部署节点同时部署,以提升部署效率。而在部署生产环境时候,单台逐一部署则更能够控制风险。

实施部署流程

在有了一个独立部署系统后,如何在业务系统中实施仍然有不小的挑战。这其中也可以有一些策略帮助降低成本,提升实施价值。具体可以进行如下方面进行尝试:

  • 照顾到项目中不同人的技术背景,选择最合适的技术方式实现部署流程中的部署脚本;
  • 充分利用项目已有的资产,如已经存在的手工部署脚本,进行改造来实现自动化部署流程;
  • 让自助部署成为一种最佳实践。要尽力让团队的每个人都可以利用部署系统进行部署(尤其是开发、测试环境);
  • 帮助团队彻底打通从代码到最终部署上线的整个通道,而不仅仅是停留在部署系统自身的实施。这样才能够提高部署的频率,提升整个链路的迭代效率,从而最大化部署系统及部署规范的价值。

更多内容

随着分布式系统和云平台的普及,部署规范内涵也在不断扩充。这又以如下两个方面表现最为突出:

  • 部署编排,更高级的部署规范?在微服务架构日渐火爆的今天,我们一般倡导各个组件解耦,形成独立的微服务模块,并且各自作为独立的部署单元独自演进,然后通过动态服务发现来解决组件之间的部署依赖关系。但是,无论是传统应用还是微服务模块,都不可避免的会涉及到外部依赖(如依赖外部数据库等)。这样,一个完整业务的不同组件之间就会有相互依赖的部署关系(如组件A的部署过程必须依赖组件B已经部署完成)。因此,如何解决部署过程中的这些依赖关系并设定相应的部署规范就是一个必要的考量。这其实就是大家经常提到的部署编排问题,它需要有新的部署依赖描述方式和相应的精确描述格式文件,并以此为基础形成新的更高级别部署规范。我们可以在很多商业部署系统(如IBM uDeploy、HP Operation Orchestration等)看到类似的部署规范在不断向前演进。但个人觉得现有的这些部署编排规范还普遍存在对应用系统限制较多,操作和自动化流程太重的问题。我们也在这个领域努力,希望能够提供一个灵活并且够用的轻量方案;
  • 环境即代码,全新的部署规范?云平台的出现让我们可以从全新的角度看待IT基础设施。由于云平台对于IT基础设施的标准化和自动化,让我们有可能通过代码精确描述一个系统需要的所有IT基础设施,并以此自动创建出这样的环境。在这个方面,AWS的Cloud Formation服务已经给我们做了一个非常好的示范。如此,这就意味着未来的部署流程完全有可能包括对于环境生命周期的完全管理(从创建到使用,乃至最后销毁)。所以,IT环境生命周期管理有可能会成为部署规范中的全新内容之一。