持续部署,并不简单!(2)
建立逻辑软件包版本和版本库中软件包版本间的关系
为相互依赖的包编译并打上统一的标签
简化运行时包依赖关系的生产
简化运行时包依赖的指定(可参考apt-get和RubyGem,环境只需指定直接依赖的包,间接依赖的包从运行时依赖树中自动导入)
一个可能的简单结构如下:
上述讨论还没有涉及操作系统,如果我们的运行机器要支持多个系统,我们又该怎么办???
配置信息也是个大问题,大家可以思考
- 环境配置和应用配置如何区分?
- 如何简化环境配置工作?
- 如何使环境配置的效果只对具体环境有效,而不会泄露到环境外部?
再者,
- 如何使应用支持多运行目标?
- 环境管理如何能方便开发环境的调试?
- 要如何简化版本的选择?
- 在多个包有编译和运行时依赖时,编译时如何检查以减少引入兼容性问题的风险?
这些都留待大家思考。
四、督脉——部署系统
《持续集成》和《持续交付》中都对部署有详细的讨论,不在赘述。在我看来,部署其就是按照其目的执行一系列步骤将环境置于其目的所指向的状态中。我们一会再回国头来看这段文绉绉的话,先看看第一部分持续集成的环境下,我们部署的步骤可能会是下面这个样子:
- 登陆目标机(ssh)
- 停止服务
- 清理环境
- 准备安装环境(创建文件夹等)
- 安装项目包(rsync,解压,权限设置等)
- 配置环境变量
- 启动服务
- ……
而在第二部分的情景4中,我们看到如果对不同的持续集成环境建立不同的部署脚本和环境维护脚本,这部署过程的维护会非常繁琐。基于第三部分的环境管理,我们可以将部署过程抽象为:
现在回到开头那个文绉绉的描述:部署其就是按照其目的执行一系列步骤将环境置于其目的所指向的状态中。
由于我们已经将部署作为环境管理的一部分,而环境又是对外提供服务的最小实体,因此,对环境的部署就是要根据部署的类型,在环境上按一定的步骤执行一系列操作,从而使环境置于部署类型所要的状态,这个过程中可能会生成对应的环境实例。举例来说,我们可能会修改环境相关的一些配置,然后重启环境,显然,这种情况下不需要下载安装软件包(没有改变),因此也就不需要生成环境实例。
对于标准的部署——安装软件包并启动环境,可能的步骤将会是:
- 选择将要部署的软件包的版本
- 生成新的环境实例(确定环境实例的版本和其依赖包的版本,确定环境配置等)
- 清理和准备目标机环境
- 下载包
- 设置环境配置
- 环境实例切换
- 生成部署报告
- ……
好,部署系统和环境管理各就各位,我们可以将各个项目环境纳入我们的环境管理之中,甚至是持续集成环境本身。再补充一句,要让部署系统和环境管理能很好的发挥作用,我们即需要一个简单一致的UI界面(为开发人员),也需要提供一个清晰明了的服务接口(供外部系统调用,如持续部署系统)。对于与环境管理相关的机器状态管理,网络资源的配置等等,本文不再涉及,大家可以自己思考。环境管理的实现、编译系统改造以及持续部署的具体实现,另作文章探讨。
就技术而言(不考虑围绕持续部署的过程实践),环境管理、部署系统以及我们没有提及的编译系统改造才是生产线的真正引擎,持续部署不过是水到渠成的传送带而已。
五、没完
打通了任督二脉后,事还还没有完,还有很多细节上的问题。你想,这个工具实在是太好用了,于是公司里成百上千的工程师们都在使用这个自动化部署系统,我们又会面对很多很多问题:
- 部署系统的性能问题。几百号人不停地在把他们的软件部署到自己的机器上,部署到测试环境,部署到生产环境,一天之内一个人可能会要部署N次,回滚N次,不但有大量部署请求,还有大量的文件在网络上传输。你得想想这套部署系统如何解决这些性能问题,还得考虑未来更大规模的性能水平扩展问题。
- 目标机环境的管理。在目标运行机上需要解决几个问题:1)两个环境间如果有一些的一样的包,那就没有必要再下载了,这样可以节约时间。2)每次部署都需要把老的部署环境给保留下来,这样方便在新旧环境下的切换。这两点对于在生产环境下部署非常关键。(这需要环境内所有软件的绿色安装才能更容易达到这个目标,因些,Unix/Linux会比Windows更容易做到这点)
- 部署一致性事务问题。有时候,我们需要同时部署若干台服务器,比如:包A到机器MA,包B到机器MB,包C到机器MC,……(Web Service的SOA架构),这些包之间有运行依赖性和兼容性问题,要么一次性全部完成,要么就全部失败。回滚也是一样的,这是一个部署事务或部署一致性的问题。如何解决呢?
- 部署环境的版本控制问题。前面说过,我们的一个环境就会和若干个包的版本耦合,环境必需管理要部署的包的版本。于是,当你的部署越来越多的时候,各个环境的包的版本开始出现混乱,各种依赖间的版本也会出现不统一的情况,也就是说,就算你有这样的一个工具,在一个高速开发的环境下,我们的部署环境的管理还是会出现很多混乱的情况,需要你不断地统一大家的开发、测试环境。
- 部署计划。我们可能会有很多部署计划,比如:设定定时部署,提升或降低部署优先级,部署事务定义,部署策略(如:先部署10%的机器,如果没有问题,再把剩下的系统部署了),热切计划和策略…… 等等 ,等等 。
- 部署的监控和维护。任何软件和系统都会有这样的问题,当规模上去了以后,我们的自动化部署系统的监控和维护的复杂度并不亚于一个大型的互联网应用。
这样的问题会有很多,基本上来说,这样一个持续集成持续部署的自动化系统并不是那么简单的事,其开发工作量和一个标准的大型互联网业务系统没什么两样。
六、总结
这里只谈一点自己的看法,从传统的持续集成到面向大型软件的持续部署,我们将系统所依赖的软件环境和软件包抽象为一致的实体纳入到管理之中,并将运维人员的工作真正的分摊到开发人员身上。而云计算的出现,使得计算机本身也可以自动化的创建和回收,这样环境管理的范畴将进一步扩充。相应的,部署的能力和灵活性也是一次质的飞跃,将再一次减轻运维人员的工作压力。
说了这么多废话,总结一下自己的观点,对于向大型软件企业推销基于持续集成的持续部署(交付)的哥们:
- 你就是在耍流氓,如果你不解决环境管理!!!
- 你就是在耍流氓,如果你不建立部署系统!!!
- 你就是在耍流氓,如果你不扩展编译系统!!!
- 你就是在耍流氓,如果你只是推销小团队的实践而不考虑改造大环境!!!
- 你就是个流氓,如果你只是不断地告诉别人怎么做,自己却从来不动手写一个测试或建立一个持续集成环境!!!
最后,用Linus最经典的话来结束本文——“ Talk is Cheap, Show me the Code!”
(注:本文由@常新居士完成初稿,我做了一些编辑,主要写了第五节“没完” )
时间:2012-06-26 09:42
来源:酷壳网
作者:@常新居士
原文链接