AIOps 一场颠覆传统运维的盛筵
977
2022-10-03
深度解析:持续交付将如何拯救IT运维?
作者简介
刘劲辉(微信号:akito_hui),前阿里移动事业群高级运维工程师,现优维科技运维与平台研发专家,专注于DevOps、应用运维和平台架构设计,参与实施监控平台设计、运维规范设计、虚拟化应用、效率提升等相关工作,在若干大中型项目的建设和运维中,积累了丰富的系统运维、架构设计、项目实施经验。
前言在深入探讨持续交付之前,我们先来看一个典型的场景:
A 公司最近很苦恼。一家传统行业的公司,物流运输为主营业务,IT部门作为支撑部门辅助业务发展。但是随着业务的快速发展,IT 部门开始感觉到有点力不从心了:
频繁的业务版本迭代(扩容、缩容、迁移、升级、回滚等等),全靠人工变更操作,操作单调重复,却又风险很高;研发同学只关注代码编写,很少考虑线上部署的规范和设计,全靠运维同学自己把关,结果各个系统的维护自成一套;新旧系统越来越多,系统调用和接口关联复杂,一个看似简单的问题都要捣弄半天,甚至还查不出原因,更别提性能优化;……
一个好的运维/测试应该可以设计交付流水线,实践了流水线才是真正的devops专家。
长久以往,业务部门对IT部门的印象直线下降,认为IT部门是一个成本部门的同时表现还让人失望,而 IT 部门则哑巴吃黄连,有苦吐不出。
A 公司遇到的问题,相信很多传统企业都会有同样的困扰。其实,知道问题在哪里,就是最好的开始,我把帮助类似A公司解决这些问题的方案整理出来,希望对大家有所帮助。
无规矩,不方圆,标准化一切!
什么是标准化?
虽然我们把标准化落实了,但是开发、测试和运维部署依然是孤立和隔离的,版本迭代效率并没有得到太大的提升,例如:版本测试、部署依赖文档,团队缺乏协助,然而在现实中,文档通常只是为执行部署者写的备忘录,是难以被他人理解的;手工部署环境,既不可重复也不可靠,在调试部署错误的过程中浪费很多时间;尽管手工部署枯燥且极具重复性,但风险高,仍需要有相当程度的专业知识,成本高昂的资深技术人员被困于其中,无法投入到更加有价值的工作;配置的环境管理依然是手工模式,没有版本跟踪,需要每一个环境的部署都需要文档和口头交流反复确认;手工运行已有的集成测试;……
持续交付可以解决上述提到的大部分的问题,一般来说,持续交付包括以下 3 个方面的内容:持续集成和持续部署,持续反馈;接下来会跟大家逐步解析。
什么是持续集成?
持续集成,又称为Continuous Integration(CI),根据敏捷大师Martin Fowler的定义:
持续集成是一种软件开发实践。在持续集成中,团队成员频繁集成他们的工作成果,一般每人每天至少集成一次,也可以多次。每次集成会经过自动构建(包括自动测试)的检验,以尽快发现集成错误。
从这个定义,我们可以理解到持续集成的关键思想:
持续集成非常快非常廉价,让 Find Bugs 的时间大幅度降低,提高版本交付效率;持续集成让开发者可以有更多的时间在Fix Bugs,而非 Find Bugs;持续集成在流水线是全自动化的过程,无需太多的人工干预;持续集成是开发团队每个成员的职责,所有版本开发的成果都需要经过集成校验,提高质量;
如何实现持续集成?
随着版本发布的流程,我们来一步一步地规划出一般持续集成具备的基本环节:
1.研发同学从 SCM中checkout代码进行日常的版本开发,完成后提交到代码库。
2.CI Server实时监控代码库分支的变化,一旦检测到分支代码变更,就会自动拉取代码。
1.CI 服务器会自动编译代码,编译成功后,会运行单元测试。
注意,从编译开始,任何一个环节失败,自动构建都会马上停止,并且把失败信息邮件等方式自动通知研发同学。这就是CI的反馈能力,帮助研发同学找到bugs,保证版本质量。到目前为止,我们可以总结一下持续集成的一部分的最佳实践:有且仅有一个代码仓库;自动化构建;使用 TDD 开发模式,编写单元测试和集成测试;保证 CI 速度,CI越快,反馈效率越高,找到bugs速度越快,迭代效率越高;项目组成员都可以查阅所有的集成构建历史;
集成测试通过后,版本开始打发布包,自动部署到测试环境,并且运行部署后的测试。
集成测试一般是指CIServer自动运行旧的功能测试用例或者其他固定的测试流程等等;
每一次成功的构建,都会邮件通知项目组,然后测试同学会编写新的功能测试用例、运行性能测试以及选择性的回归测试等等,这也是持续集成流程里面唯一需要人工干预的步骤。
到目前,持续集成基本上结束了,在构建过程中任意一个步骤失败,都会马上停止,并且反馈到研发同学,同时我们也可以总结出剩下的持续集成最佳实践:自动化部署。
上面提到是持续集成的一般流程,给大家介绍持续集成的概念,但是在实际应用中业务环境可能更加复杂,例如:公司内部有大量的业务系统,通过API或者API网关关联,研发团队的成员在本地开发某一个组件时,需要开发环境的各大系统来联调;为了迭代更快,单元测试、集成测试都可以在开发联调环境来完成,在开发环境构建未通过前无需部署到测试环境;自动化部署测试环境后,测试同学会对版本进行更多的手工测试;缺少配置中心对配置进行环境和版本跟踪。
因此,在这里我会推荐一个持续集成生产模型给大家参考一下:
该持续集成模型具有以下的优势:
本地开发时可以联调开发环境,更加方便的进行代码测试和单元用例的编写,对研发更加友好;集成测试提前在开发环境完成,CI 反馈的速度更快;开发环境和测试环境隔离,开发环境可能是唯一的,但是测试环境会有多套,主要提供给测试同学执行更多的人工测试,例如性能测试、新的功能用例测试等等;测试同学维护开发环境和测试环境中的功能用例,还可以嵌入自动化测试管理系统来辅助管理;配置管理的模式有2种:部署平台管理配置,或者是直接由单独的配置中心管理配置。
最后,要提醒一下大家,这里只是提供一种比较成熟的思路,切忌生搬硬套,要切合公司的实际情况,梳理代码开发和测试规范,并且应用到持续集成流程中。
持续集成的实践示例
在这小节,我会演示一个简单的例子,来告诉大家持续集成的实践应用。
1. 选择 CI 工具
实现持续集成的工具有很多,例如:Jenkins、Hudson、Travis CI、Build Bot、Strider等等。
其中,Jenkins 是 CI 的主流工具,它的前身是 Hudson,我这里选用 Jenkins 为大家演示案例。
首先要给大家介绍一下在 Jenkins 中的专业名词:Jenkins 里面的集成构建的基本单位是任务-Task;每一次任务的运行,称之为构建-Build,同时会产生一个唯一的BUILD_ID;你可以把若干个任务添加到一个视图中,进行归类。
现在,让我们来看看任务里面的具体设置:
2. 设置构建任务
Jenkins 的构建任务分为8个模块,来支撑我们之前提到的持续集成的所有步骤,这里给大家介绍以下核心的模块:
General顾名思义,这里是设置任务的通用属性,这里简单介绍一下常用的参数:
丢弃旧的构建如果想Jenkins只保留一定数量的构建历史,那么勾选“丢弃旧的构建”进行选择:
源码管理该模块是设定 SCM 地址和需要进行构建的代码分支,对于许多 SCM,Jenkins 都有插件支持,我在这里选用了 Git:
在这里可以观察到一个任务只能对一个代码分支进行持续集成,在版本开发和分支管理策略上面就需要做好调整:
主干开发模式比较适合目前的持续集成;推荐使用 Git-Flow的代码管理,只需要对Develop分支和Master分支做持续集成,可以很方便地做较长版本发布周期的项目、持续集成和随时发布;
我在这里不展开更多的细节,更多的版本分支管理和发布实践可以参考 IBM 开发文库:《Git 分支管理最佳实践》。
PS:默认 Jenkins 只安装了Git插件,如果需要对其他的SCM进行持续集成,那么需要在“系统管理”-“管理插件”-“可选插件”中进行搜索和勾选安装;如果 Jenkins 服务器没有联网,还手动下载插件的.hpi安装文件,然后在“系统管理”-“管理插件”-“高级”中上传插件进行手动的安装,安装时注意自己解决依赖。^_^
构建触发器触发器非常关键,是实现自动化构建的入口。一般构建触发器会有以下的种类:
定时构建Jenkins的定时构建语法格式和Linux的crontab一样,只不过没有命令列,常见的有以下 2 种模式:Build periodically:不管源码是否发生变化,周期性地进行项目构建;Poll SCM:定时检查源码变更(根据SCM软件的版本号),如果有更新就checkout最新code下来,然后执行构建动作。依赖构建Jenkins 里面可以选择在任意的其他任务构建完毕后,触发当前任务的构建,当然也可以在“构建后操作”模块中触发其他下游的任务进行构建。触发构建触发构建一般有以下 3 种模式:Build when a change is pushed to GitHub:当前项目是GitHub项目时,可以勾选此构建,当产生Push操作时,可以定制GitHub上的事件,由GitHub来触发自动构建;Build when a change is pushed to GitLab:当前项目是 GitLab 项目时,可以勾选次构建,当产生 Push 操作时,可以定制 GitLab 上的事情,由 GitLab 来触发自动构建;通 过Remote HTTP API 来触发当前任务的构建:由通过任意的方式,使用 HTTP请求JenkinsAPI接口,可以触发当前任务PROJECTNAME的构建:http://YOURHOST/jenkins/job PROJECTNAME/build这是给用户自由定制触发条件和场合使用的。手动构建
这个就不需要解释了吧,大家手动点一下就好了。
Pre Steps
在进行构建之前你还有什么想要准备的,在这里编写 pre-build step。
Build
顾名思义,在这里执行构建动作,一般的构建动作会包括:编译、运行单元测试,如果需要上传和部署,那么还需要打包。
在这里,我给大家演示一下 Maven 项目的构建(mvn package 指令会经历 compile、test 等关键周期,因此编译、单元测试均均会运行):
Post Steps
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. 日志数据采集:常见于业务层数据采集,多维数据采集、分析和监控。
业务监控能力包括以下个方面:
基础监控能力:主机资源(CPU Usage、Memory Usage 等等)的监控;
业务基础监控:业务的端口、进程等;业务逻辑监控:业务整体流程、单个业务功能点的监控;业务高级监控:接口API级别的链路调度监控、请求全流程染色跟踪等;日志多维监控:对日志进行采集、格式化处理和存储、多维度的分析和监控。
在很多传统企业里面,生产环境可能不止是 Linux 服务器,还可能包含大量的 windows 服务器,监控系统需要对这 2个 OS 进行无缝支持:
写在最后
持续交付最终的目标,其实也就是IT运营,把IT部门从成本部门的印象中解放出来,变成能够为业务部门提高产品运营和发布效率、提升价值的支撑部门,估计应该是许多 IT 人的梦想吧。
近期文章
发表评论
暂时没有评论,来抢沙发吧~