刘劲辉(微信号:akito_hui),前阿里移动事业群高级运维工程师,现优维科技运维与平台研发专家,专注于DevOps、应用运维和平台架构设计,参与实施监控平台设计、运维规范设计、虚拟化应用、效率提升等相关工作,在若干大中型项目的建设和运维中,积累了丰富的系统运维、架构设计、项目实施经验。
前言
在深入探讨持续交付之前,我们先来看一个典型的场景: A 公司最近很苦恼。 A 是一个传统行业的公司,物流运输为主营业务,IT部门作为支撑部门辅助业务发展。但是随着业务的快速发展,IT 部门开始感觉到有点力不从心了:
一个好的运维/测试应该可以设计交付流水线,实践了流水线才是真正的devops专家。
长久以往,业务部门对IT部门的印象直线下降,认为IT部门是一个成本部门的同时表现还让人失望,而 IT 部门则哑巴吃黄连,有苦吐不出。
A 公司遇到的问题,相信很多传统企业都会有同样的困扰。其实,知道问题在哪里,就是最好的开始,我把帮助类似A公司解决这些问题的方案整理出来,希望对大家有所帮助。
无规矩,不方圆,标准化一切!
在讨论标准化是什么之前,我们先来思考这些问题:
标准化可以帮助我们解决以上的这些问题,我对标准化的定义就是:
针对企业内部的业务系统技术栈进行梳理,规划出一套开发和部署规范,并且在各个环境(Dev/Test/Prod)严格执行。
标准化对可变部署模式最为有效,通过标准化,企业内部的每一套系统,每一个环境,都保持一致,然后把规范化后的部署方案整理好,落实到自动化平台,就可以实现自动化部署而无需过多的人工干预。
试想一下,如果是一百套不同的系统,自动化平台根本做不起来,业务维护、交接和部署的成本简直不可想象。 那么问题就来了,如何做标准化?
PS:什么是部署模式? 实际环境中,部署模式分为2种,一种是可变部署模式,一种是不可变部署模式。 可变部署模式: 是指任何的版本变更操作,都会在原来的版本上进行,例如升级、回滚、卸载、安装,这些变更操作会直接影响到原来的版本的服务,技术术语中把使用了可变部署模式的服务器称之为:Mutable Monster Server(随之时间推移逐渐变成不可控的怪物服务器)。 例如:ver1.0 发布之后,更新至ver2.0时,需要把服务器上的ver1.0的服务停止,删除版本文件,然后把 ver2.0的版本文件安装上去,再启动服务; 因此,如果版本回滚的时候,也是同样的操作,把 ver1.0 的安装回去。 不可变部署模式: 不可变部署模式,和可变部署模式相反,一旦当前的版本发布后,就不能再对该版本做任何的操作,如果要进行版本变更操作,就需要重新发布一个新的不可变版本,这些变更操作不会影响原来的版本的服务,不可变部署模式的目前代表是 Docker 镜像发布模式。 例如:ver1.0 的镜像发布后,更新至 ver2.0时,只需要把 ver2.0 的镜像发布出去,运行起来,然后把流量切换到 ver2.0 的容器实例上即可; 因此,如果版本回滚的时候,就把流量切换回去 ver1.0 的容器实例上。
我把标准化的实践思想总结为XY轴对象模型,从开发、测试、运维3个角度着手。
例如,以运维的角度来梳理:
基础层一般指技术栈最为底层依赖的环境,例如:
A 公司使用了 JBOSS-EAP,因此底层依赖的环境是 OS + JDK:
框架层一般指技术栈所使用的项目开发框架,可以是开源方案,也可以是自研发框架,例如:
A 公司使用了 JBOSS-EAP 作为开发框架:
公共组件层一般存放多个组件共享的代码、配置、驱动等,需要按照实际场景进行分析,因此不一定需要。
业务组件层,就是研发同学开发的业务组件,业务组件一般会有:
结合 X 轴,可以得到以下需要标准化的实体/属性表:
例如,A公司针对部署目录这个属性,定制的标准化如下:
可以看看业务组件层的设计细节:
部署标准化执行准则
结合个人经验,在构建标准化对象模型时,以下的准则是应该遵守的:
同样,在测试方面也可以提供业务测试的定制化规范,比如功能测试用例的编写、规划的测试流程(黑盒测试、白盒测试、回归测试以及性能测试)等等,不知道大家是否理解了?^_^
标准化构建平台,持续交付跑起来
经过标准化建设后,企业内部大部分的系统开发、测试、部署实施规范就差不多大体落地了,接下来我们需要做什么呢?
虽然我们把标准化落实了,但是开发、测试和运维部署依然是孤立和隔离的,版本迭代效率并没有得到太大的提升,例如:
持续交付可以解决上述提到的大部分的问题,一般来说,持续交付包括以下 3 个方面的内容:持续集成和持续部署,持续反馈;接下来会跟大家逐步解析。
持续集成,又称为Continuous Integration(CI),根据敏捷大师Martin Fowler的定义:
持续集成是一种软件开发实践。在持续集成中,团队成员频繁集成他们的工作成果,一般每人每天至少集成一次,也可以多次。每次集成会经过自动构建(包括自动测试)的检验,以尽快发现集成错误。
从这个定义,我们可以理解到持续集成的关键思想:
随着版本发布的流程,我们来一步一步地规划出一般持续集成具备的基本环节:
1.研发同学从 SCM中checkout代码进行日常的版本开发,完成后提交到代码库。
2.CI Server实时监控代码库分支的变化,一旦检测到分支代码变更,就会自动拉取代码。
1.CI 服务器会自动编译代码,编译成功后,会运行单元测试。
注意,从编译开始,任何一个环节失败,自动构建都会马上停止,并且把失败信息邮件等方式自动通知研发同学。 这就是CI的反馈能力,帮助研发同学找到bugs,保证版本质量。 到目前为止,我们可以总结一下持续集成的一部分的最佳实践:
集成测试一般是指CIServer自动运行旧的功能测试用例或者其他固定的测试流程等等;
每一次成功的构建,都会邮件通知项目组,然后测试同学会编写新的功能测试用例、运行性能测试以及选择性的回归测试等等,这也是持续集成流程里面唯一需要人工干预的步骤。
到目前,持续集成基本上结束了,在构建过程中任意一个步骤失败,都会马上停止,并且反馈到研发同学,同时我们也可以总结出剩下的持续集成最佳实践:自动化部署。
上面提到是持续集成的一般流程,给大家介绍持续集成的概念,但是在实际应用中业务环境可能更加复杂,例如:
因此,在这里我会推荐一个持续集成生产模型给大家参考一下:
该持续集成模型具有以下的优势:
最后,要提醒一下大家,这里只是提供一种比较成熟的思路,切忌生搬硬套,要切合公司的实际情况,梳理代码开发和测试规范,并且应用到持续集成流程中。
在这小节,我会演示一个简单的例子,来告诉大家持续集成的实践应用。
实现持续集成的工具有很多,例如:Jenkins、Hudson、Travis CI、Build Bot、Strider等等。
其中,Jenkins 是 CI 的主流工具,它的前身是 Hudson,我这里选用 Jenkins 为大家演示案例。
首先要给大家介绍一下在 Jenkins 中的专业名词:
现在,让我们来看看任务里面的具体设置:
Jenkins 的构建任务分为8个模块,来支撑我们之前提到的持续集成的所有步骤,这里给大家介绍以下核心的模块:
参数化构建过程 在构建任务中,可以使用自定义全局变量,常用的有选择变量、字符串变量等等:
串联执行控制 多个任务之间可以互相触发,串联执行构建,称之为上下游,对上下游的任务进行构建控制:
在这里可以观察到一个任务只能对一个代码分支进行持续集成,在版本开发和分支管理策略上面就需要做好调整:
我在这里不展开更多的细节,更多的版本分支管理和发布实践可以参考 IBM 开发文库:《Git 分支管理最佳实践》。
PS:默认 Jenkins 只安装了Git插件,如果需要对其他的SCM进行持续集成,那么需要在“系统管理”-“管理插件”-“可选插件”中进行搜索和勾选安装; 如果 Jenkins 服务器没有联网,还手动下载插件的.hpi安装文件,然后在“系统管理”-“管理插件”-“高级”中上传插件进行手动的安装,安装时注意自己解决依赖。^_^
在进行构建之前你还有什么想要准备的,在这里编写 pre-build step。
顾名思义,在这里执行构建动作,一般的构建动作会包括:编译、运行单元测试,如果需要上传和部署,那么还需要打包。
在这里,我给大家演示一下 Maven 项目的构建(mvn package 指令会经历 compile、test 等关键周期,因此编译、单元测试均均会运行):
Post Steps 允许你根据构建的结果,来执行其他操作,构建的结果支持:
1. Run only if build succeeds 2. Run only if build succeeds or is unstable 3. Run regardless of build result
在这里,你可以发送邮件通知其他项目组的成员关于本次构建的结果:
本次构建结束后,你还可以执行其他的操作,如下图:
例如之前提到的触发其他任务进行构建,在这里勾选 Build other projects 即可:
又例如,我们在构建成功后,自动上传和部署到开发或者测试环境,在这里设置一下构建后的操作即可:
持续部署和持续集成非常接近,持续部署就在持续集成完成后,自动部署到生产环境。
部署生产环境的能力和部署开发联调环境、测试验证环境一样,但是我们通常做不到生产环境的自动化部署,原因有很多:
1. 商业、市场上的策略,新版本功能披露的时机需要人为控制。
2. 许多组织的测试并不充分,这无法确保一次新的发布能够在没有人工干预的情况下部署至生产环境中。即使这些测试本身是可靠的,但往往没有将这些测试在所有可能在生产环境中出现的相同条件下运行。
3. 生产环境的自动化部署对团队能力要求高,例如研发同学需要编写足够充分的单元测试,关注线上的服务部署状况、测试同学要提前做好新版本的测试准备、运维同学的角色定位在发生变化,将会从枯燥重复的部署操作中解放出来,去实践一个业务运维应该关注的工作——业务监控、业务分析、性能优化等等,这是对公司组织 结构和团队功能的变革。
在很多传统企业的场景下,就算我们做不到持续部署,对开发联调环境和测试验证环境的持续集成的实践已经是非常巨大的进步了。持续部署示例如下(多环节部署、回滚、灰度、升级、调度编排等等):
在实现了持续集成、持续部署后,我们的版本能够从提交代码后,自动化部署到各个环境而无需人工干预,但是好像还缺少些什么?
是的,没错,我们还缺少持续反馈。
版本上线,我们需要得到持续的反馈:
1. 研发、测试和运维团队关注版本的质量、版本的性能;
2. 运维团队关注目前关联系统的IT运营分析,例如集群容量变化等等;
3. 运营和产品关注新版本带来的产品收益、对用户的影响;
4. ……
我们一般会通过监控平台和日志分析来做持续反馈。
通过监控平台和日志平台的数据分析反馈,我们得到产品的程序性能跟踪、运营的数据分析,这些都可以反馈到提升业务价值上,最终实现了持续交付。
端到端监控
监控,是业务发布中非常非常重要的一环,所谓业务上线,监控先行。业务上线的质量以及后续问题跟踪,需要业务监控来保护、发现并且暴露出来。 一般情况下,监控的采集方式有 2种:
1. 动态数据采集:常见于底层数据分析,例如硬件资源使用情况、系统资源使用情况等等;
2. 日志数据采集:常见于业务层数据采集,多维数据采集、分析和监控。
业务监控能力包括以下个方面:
在很多传统企业里面,生产环境可能不止是 Linux 服务器,还可能包含大量的 windows 服务器,监控系统需要对这 2个 OS 进行无缝支持:
写在最后
持续交付最终的目标,其实也就是IT运营,把IT部门从成本部门的印象中解放出来,变成能够为业务部门提高产品运营和发布效率、提升价值的支撑部门,估计应该是许多 IT 人的梦想吧。
以上提到的在实现持续交付时所需的平台功能,鹿厂优维科技会在新发布的EASYOPS社区版中陆续开放,用户可以终身免费使用,助大家早日实现 IT 运营!
另外,刚听朋友问到监控日志的问题,我下次谈谈监控分析和日志分析的新思路吧。
最后,也是最重磅的,可以免费使用EasyOps一站式运维平台。扫一扫如下二维码即可直接注册享受带来的精益运维能力。