DevOps的高部署频率通常会给QA(质量保证)人员和信息安全带来很大的压力,考虑开发每天部署10次,而信息安全通常需要4个月的时间来评估应用的安全。显然,在代码开发和代码安全审计方面的速率是不匹配的。
一个著名的故障案例,提供云存储、文件同步和客户端软件服务的Dropbox公司,2011年程序更新未经充分测试从而导致认证功能被关闭了4h,导致未授权的用户可以访问所有存储的数据。
当然对QA和信息安全来说,也不全是坏消息,开发会通过持续集成和好的发布惯例(持续测试的文化)来维持高频率部署。换句话说,一旦代码被提交,自动测试便开始运行,而且一旦发现问题,必须马上解决,就像开发人员检查还没编译的代码。
通过集成功能测试、集成测试和信息安全测试到开发的每天例行工作中,问题将会被更快发现,同时也会被更快解决。
同样,也有着越来越多的信息安全工具,如Gauntlet和SecurityMonkey,可以帮助开发和测试,达到信息安全目标。
但是也有一个很重要的问题需要考虑,静态代码分析工具通常需要花费很长时间才能运行完,以数小时或天计。在这种情况下,信息安全就必须注明特定的有安全隐患的模块,如加密模块、认证模块等。只要这些模块变化,一轮全面的信息安全测试就运行,否则部署就可以继续,而不需要全覆盖信息安全测试。
需要注意的是,相较于标准的功能单元测试,DevOps工作流更依赖于检测和恢复。换句话说,当开发以软件套件的方式交付的时候,部署变更和补丁就比较困难,同时QA也严重依赖代码测试来验证功能的正确性。另一方面,当软件以服务的形式交付,缺陷就可以很快被修复,而且QA也可以减少测试依赖,取而代之更多的是依赖缺陷的生产监控,只要缺陷能被快速地修复便可。
代码故障恢复可借助于“功能标签”等手段,通过以配置的形式来启用或禁用某些代码功能,从而达到避免推出一个全功能部署,而只部署通过测试的功能至生产环境。
当功能不可用或性能出现下降等较坏的情况发生时,依赖于检测和恢复进行QA,将会是一种更好的选择。但是当面对损失保密性或数据和系统一致性的时候,我们就不能依赖检测和恢复这种方法。取而代之的是,在部署之前必须进行充分的测试,否则可能导致重大的安全事故。
1.模式一
通常,在软件开发项目中,开发人员在开发功能时都会用完所有计划中的时间,这样会导致无法充分解决IT运维的问题。于是他们就在定义、创建和测试数据库、操作系统、网络、虚拟化等代码依赖的方面直接“抄捷径”,以此节省时间。
这就是开发和IT运维以及次优结果之间存在永恒的紧张关系的主要原因。但是这样可能会带来很严重的结果,如不适当的定义和指定环境、无法重部署、代码和环境的不兼容等。
在这种模式下,将在开发过程的早期提出环境要求,并强制代码和环境必须被一起测试的策略,一旦使用敏捷开发方法,便可做到非常简洁和优雅。
按照敏捷的要求,在每个迭代结束后,就会发布能运行且可被部署的代码,通常时间为两周。我们将修改敏捷迭代周期策略,不仅仅只交付能运行且可被部署的代码,同时在每个迭代周期的早期,还必须准备好环境用于部署这些代码。
由此,我们不再让IT运维负责创建生产环境的规格要求,取而代之的是,建立一个自动化的环境创建流程,这种机制不仅仅只创建生产环境,同时也包括创建开发和QA环境。
通过使得环境早期即可用,甚至可能早于软件项目开始之前,开发人员和QA人员可以在统一和稳定的环境中运行和测试他们的代码,从而控制不同环境之间的差异。
此外,通过保持不同阶段(如开发、QA、集成测试、生产)尽可能小的差异,在生产部署之前,就能发现并修复代码和环境之间的互操作性问题。
理想情况下,建立的部署机制是完全自动化的。可以使用Shell脚本、Puppet、Chef、SoarisJumpstart、RedhatKickstart、DebianPreseed等工具来完成。
2.模式二
BrowserMob前CEO(首席执行官)PatrickLightbody曾经说过:“当我们在凌晨2:00叫醒开发工程师来解决问题时,缺陷被修复得比以前更快了,这真是一个惊人的反馈回路。”
它强调了问题的关键点,开发人员一般会在周五的17:00点提交代码,然后高高兴兴地回家,而IT运维人员则要花费一整个周末来收拾残局。更糟糕的是,缺陷和已知错误在生产上不断递归,迫使IT运维人员不停地“救火”,造成这种现象的原因就是开发人员总是尝试开发新功能。
第二种模式的一个要素是缩短和放大反馈回路,使得开发产品更贴近客户(包括IT运维人员和最终用户)体验。
注意这里的对称性,模式一讨论的尽早让环境统一并可用即是将IT运维嵌入开发中,而模式二则是将开发嵌入IT运维中。
我们将开发嵌入IT运维的问题升级链中,可以将它们放在三级支持中,甚至让开发对整个代码的部署成功负责,要么回滚,要么修复缺陷,直到服务恢复。
我们的目标不是让开发取代IT运维,相反,就是想让开发看到他们工作和变更的下游变化,激励他们以IT运维的视角来更快地解决问题,从而达到全局的目标。
3.模式三
在开发和IT运维之间DevOps价值流中,另一个经常发生的问题就是不够规范。每个部署都带有其特殊性,因此也使得每次部署后的环境带有特殊性,一旦这样的事情发生,那么这个组织里就没有针对流程配置的控制。
在这种模式下,我们定义可重用且可跨多个项目的部署流程。敏捷方法里有一个很简单的解决方案,就是将部署的活动变成一个用户故事。例如,我们为IT运维构建一个可重用的用户故事,叫作“部署到高可用环境”,这个用户故事定义了明确的构建环境的步骤、需要多长时间、需要哪些资源等。
那么这些信息可以被项目经理用来集成部署内容到项目计划中去。例如,如果我们知道在过去的3年时间里,“部署到高可用环境”用户故事被部署了15次,每次的平均部署时间为3天,那么我们对自己的部署计划将会非常有信心。
此外,我们还可以因部署活动被合适地集成到软件项目中而获得信心。
然而,有些特定的软件项目要求特别的环境,且其不被IT运维官方支持,我们可以允许这些被生产允许的环境中的例外,但是它们需要被IT运维部门以外的人提供支持的。
通过这种方法,我们既获得了环境标准化的好处(例如,减少生产差异,环境更一致,IT运维的支持和维护能力增加),又在允许的特殊情况下,提供业务需要的灵活性。
如何才能实现DevOps呢?很多人会不假思索地说,使用Chef/Puppet就能实现DevOps。于是,DevOps变成了一个简单的问题,选择Chef还是Puppet。在开源软件盛行的今天,各种软件声称实现了DevOps。如同Agile,把DevOps等同于工具层面的Chef/Puppet,是错误的,会严重束缚人们的思维。因此,在国内CloudNative应用开发时代开启的今天,充分认识DevOps是很有必要的。
(1)DevOps不仅仅是工具。
DevOps是Agile的延伸,Ailge依靠Dev&Biz部门紧密协作,通过增量交付的方式来解决需求多变的难题。DevOps则进一步延伸到IT运维,通过Dev&Ops的紧密协作提高软件交付的质量和频率。人的重要性大于流程,流程的重要性大于工具,如图6-1所示。这个结论适应于Agile,也同样适用于DevOps,工具带来的影响是短期的和片面的,流程和人所产生的影响是长期的和全面的。
图6-1 DevOps的重要性(www.xing528.com)
事实上,大部分人都知道这个道理,只是在潜意识中仍然把DevOps当成Chef/Puppet等工具。建设DevOps的正确步骤应该是:充分理解DevOps的原则,认真分析自身需求和条件,选择正确的方法和流程,最后才是选择或构建适当的工具。LearnByExample仍然是学习和建设DevOps的重要途径,大家需要多关注流程、组织结构和文化方面的分享。所以,DevOps不仅仅是工具,即便是工具,其也是建设DevOps所需工具链中的可选工具。
(2)Chef/Puppet只是DevOps工具链中的可选工具。
DevOps目的是打造标准化的、可重复的、完全自动化的DeliveryPIPeline(输送管道),其范围涵盖需求、设计、开发、构建、部署、测试和发布。除了需求、设计和开发外,其他的4个步骤都是可以自动化的。自动化是提高可测试性、一致性、稳定性和交付频率的核心。
图6-2非常清晰地解释了DevOps如何实现交付的自动化。
图6-2 DevOps的流程
DevOps流程需要用到的工具和环境有:
①源代码版本控制工具:如SVN、Git等。
②持续集成工具:如Jenkins、Bambo等。
③Artifact存储仓库:持续集成构建后的Artifact,统一放在一个仓库中,如Nexus、Artifactory,当然也可以是FTP、S3等。
④配置和部署工具:Chef/Puppet/CFEngine,Fabric/ControlTier,也包括新兴的Docker等。
⑤CloudProvision工具:在云环境下,由于任何ITInfra资源都以编程接口提供,意味着Full-StackAutomation(from“bare-metaltorunningbusinessservices”)成为可能。Cloudprovision工具可以自己通过API构建(如NetflixAsgard),也可以使用第三方工具(如Ringscale/Scalr等)。相当一部分CloudProvision本身也集成了Chef/Puppet来实现后续的部署和配置。
⑥测试工具:除了传统的测试工具外,还需要模拟Infra灾难、验证系统健壮性的工具,如Netflix的ChaoMonkey。
⑦发布工具:一般情况下,人们需要拥有DTAP(Development、Testing、Acceptance/Staging、Production)四个环境,即开发环境、测试环境、验收/预发布环境和生产环境。每种环境的作用、部署方式和代码版本等是不一样的,如开发环境是持续部署的,测试环境是定期(如每天晚上)自动部署的,验收/预发布环境和生产环境是手动触发的。
⑧云基础设施:包括AWS、Azure等公有云,Cloudstack、Openstack等私有云。
因此,可以看出Chef/Puppet只是实现DevOps工具链的可选工具,可以用来实现配置和部署自动化。
(3)仅靠Chef/Puppet本身无法实现Full-Stack(全栈)部署自动化
如果要实现Full-Stack部署自动化,那么就必须实现环境创建自动化配置,应用部署和配置自动化,监控和告警自动化,故障检测和恢复自动化,扩展自动化,如图6-3所示。
图6-3 环境创建自动化
①环境创建:创建VMs、网络、存储、负载均衡,协调不同角色VMs的创建过程和配置。
②软件安装和配置:操作系统配置,如创建用户、组,设置ulimit参数等;基础软件安装和配置,如MySQL/Nginx。这些软件的特点是变动不频繁。对于Chef/Puppet来说,这个步骤的自动化是其最擅长的。它们都提供大量现成的RecIPes,并抽象各种异构系统之间的差异。
③应用部署和配置:部署应用代码,如war包、db脚本、PHP/Rails代码等。这部分的变动是频繁的。对于Chef/Puppet来说,其是可以做这个工作的,但是很多人认为用Fabric/Glu等更为合适。另外,对于复杂的系统来说,如果需要保证升级期间系统的可用性,那么系统的各个应用组件需尽量是无状态的和松耦合的。如果系统的组件之间是有依赖的,那么升级期间必须动态地协调(Orchestration)、控制好相关组件的行为。
④监控和告警:包括OS级别和应用级别的可用性和性能监控。如果发现异常,需要能够自动发出告警信息。
⑤健康检测和恢复:为了应付云基础设施故障,系统需要DesignByFailure,在发生异常时,系统可以发现并自动进行处理。
⑥自动伸缩:一般情况下,业务存在高峰期和低谷期。为了节省成本,系统应该是可以自动伸缩的。
对于上述的每一个步骤,看似都存在现成的工具可以用来实现自动化,但是,实现Full-Stack部署自动化不是一件容易的事情,绝非简单通过选择、拼凑相关工具即可实现。Autodesk中国研发中心最近在InfoQ网站上分享了他们基于AWS的自动化部署实践。在这里,分析一下基于PaaS和Netflix两种差异较大的实现方式。
基于PaaS的实现方式(以CloudFoundry为例)如表6-1所示。
表6-1 基于PaaS的实现方式
这种方式中CloudFoundry基本实现了上述的所有自动化步骤,应用开发人员只需专注于应用逻辑本身的开发。然而,CloudFoundry也限制了用户的选择权和控制权,特别是大型的、复杂的、分布式系统,开发人员需要的是Full-Stack可控制性。
Netflix的实现方式如表6-2所示。
表6-2 Netflix的实现方式
Netflix除了利用AWS的CloudWatch、AutoScalingGroup、ELB等服务外,本身也开发了一系列工具以完成Full-Stack部署自动化。这些工具通过Asgard这个可视化云管理和部署控制台集成起来。另外,Deployableimage这种部署模式虽可简化部署并确保一致性,但是一部分复杂性转移到了应用层面。系统的各个组件是无状态的和松耦合的,同时还需要Eureka这种服务来实现中间层的负载和Failover(故障转移)。
在上述两个案例中,大家都看不到Chef/Puppet的影子,即便是CloudFoundry自身的部署工具Bosh,也不是基于Chef/Puppet的。所以,尽管Chef/Puppet非常流行,并且有很多成功案例,但是不能将DevOps等效于Chef/Puppet。它们只是建设DevOps所需工具链中的可选工具,仅此而已。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。