大型网站运维:从系统管理到SRE
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

4.1 变更管理机制

传统运维、DevOps、SRE 对变更管理都有各自的落地逻辑和方法,只是这些落地逻辑和方法因为角色的不同,在实际应用场景中会有很多的不同。在传统运维模式中,运维对变更注重的是流程的合规性,如有没有走审批流程等,但不一定会有工具和方法来验证整个变更流程的每个环节。某些环节缺少工具会明显地影响变更的执行效果,也就是传统的变更从某种意义上会严重依赖运维/开发工程师的技术和运维意识。如果处于这个阶段,可以说运行于每家公司内部的变更流程,都是业务团队经过层层磨炼后沉淀下来的。

4.1.1 传统运维的变更管理

首先来看传统运维对变更管理的处理。很早之前,传统运维就开始注重变更管理了,不过因为角色属性,传统运维对变更管理的理解更多地来自团队对历史变更的经验归纳和总结。因为传统运维和开发是独立的部门,往小的说传统运维和开发的技术堆栈是完全不一样的,往大的说传统运维和开发的KPI是完全不一样的。但是因为业务稳定性会直接影响大家共同的利益,所以传统运维团队和开发团队坐到一起,会想办法协同制定变更相关的规范和流程。

通常这个变更逻辑的设计非常简单,总体分3个阶段。每个阶段又包含很多子项目,因为没有自动化工具的约束,所以每个环节的很多操作在执行时,顺序或执行严谨度是不确定的。变更流程如图4-1所示。

图4-1 变更流程

在所有公司,业务的稳定性都和钱有关系,业务团队通常会比较注重利用流程约束变更行为,进而规避或防止某些经常犯的变更错误。以图4-1为例,虽然看起来流程只有3步,但内部其实包含了大量人工执行的子项目。在很多公司,或多或少都会看到表4-1所示的变更申请表单。

表4-1 变更申请表单

表4-1中的每个表项其实都是线上业务的血泪教训总结。很早之前,最初发布的变更管理机制是申请人发起申请,申请人的领导审批确认后,就可以直接执行变更的。这种变更管理机制虽然能满足变更需求提出、变更需求审批、变更影响评估等多个环节,但是它在很多环节是缺少强制约束的,因为各个环节的约束都依赖人。

这样的变更管理机制有时候只是形式上的安慰,出过多次问题后,大家当然也会审视这个变更流程。例如,大家发现单纯只有申请人的领导审批是不够的,还得加上关联业务方的领导审批等。变更申请表单流程会随着业务运行逐渐趋于完善,但线上可能还会出现问题,因为太多的变更执行依赖于人。

每次出现问题后,运维团队和开发团队一起复盘时都会提到实际操作问题,也会将一些变更失败归根于人工变更的偏差性。因为无论是谁,在执行变更操作时,都可能会遇到不确定因素,如代码合并错分支了、单元测试漏了某个新模块等。

从个人的角度来看,流于形式的变更流程都是一次“丛林冒险”。即使变更执行人都是“老司机”,下一秒也会遇到出现超过预期的一些情况。慢慢地变更申请表单不断加入了“操作影响和评估”等新的表项,最终整个变更申请表单会随着时间的增长而慢慢完善(当然也会增加变更实施的复杂度)。如果这样的变更流程是一个强制的管理流程,那么有人就会有突破规则的欲望。

举例来说,很多团队会在变更操作影响层面明确地要求写清楚变更操作细节,并且要求在实际执行时只能直接复制命令。这种要求从某种程度上来说是线上执行人做了非常强的约束,需要注意的是这种约束会强依赖审批人的技术和经验,否则会很容易陷入变更申请表单写的是顺序执行A,B,C 命令,但实际落地时需要执行 A,A’,B,C 命令的情况。做过一线运维的同学都很清楚,很多时候写变更操作时是一回事,过了审批后又是另一回事。真正操作时,实施人员往往会发现有中间情况没有被评估到,但是线上好不容易申请到的变更窗口不执行不行,当场加入额外的补充操作又违反变更管理机制的情况。

一般这种情况下要么取消当次变更,要么允许临时调整。但是无论是取消后重新申请变更,还是先调整后补流程,都能说明变更出现了问题。这样的变更管理机制从某种意义上说已经有点不合理了。如果要求重新申请变更,执行人会反馈这样的变更管理机制太重,已经影响到了产品的迭代速度。如果允许临时调整变更,那么就更能说明流程是可以用来突破的,会给团队成员留下一个可以突破规则的印象。

从这样的例子来说,可以认为传统运维的变更管理在制定规范时是重流程的,但在执行时又是轻流程的。因为传统运维和开发是独立的,所以建立变更规范是非常重要的,只是太重的变更管理机制会导致执行缓慢,有时和互联网快速试错的理念是相违背的。

4.1.2 DevOps的变更管理

然后来看DevOps 对变更管理的处理。一般谈及DevOps 时,还有另一些词汇也经常被提及,那就是“敏捷”、Spring或Kanban(Kanban是一种流程管理方法)等项目管理方式。基本上所有互联网公司的项目都会实践敏捷开发、强调项目小步快跑和功能持续迭代实现,这种管理方式也会直接地影响DevOps的变更管理。

相比传统运维的流程式变更管理,DevOps 更加相信从代码提交到自动发布的CI/CD(持续集成/持续发布)流水线。很多DevOps的拥护者相信只要代码提交到主干,开始进入自动化CI/CD流水线,自动化测试用例通过,就应该允许代码直接发布到线上。这中间可能只要项目团队执行一次Release (发布)提交就可以触发一次线上变更。

DevOps 的变更管理会更多地和项目管理流程关联。相比传统运维的变更管理,DevOps的变更管理更加轻量化。如果非得说两者的差异,那么你可以理解为两者的差异是传统软件开发模式中的“瀑布开发”和“测试开发”这样的差异。

这种差异变化并不是说DevOps的变更管理真的很“轻”,而是因为他们的工具完善、流程自动化程度高,最终反映到变更管理上就是降低了对人的要求。对于DevOps来说,如果一个变更触发了线上的问题,那么就肯定是在工具或自动化流程上出现了问题,只要修正了这个问题,就自然解决了变更可能导致的问题。

以日常变更中DevOps最常见的CD(Continuous Delivery,持续发布)为例(见图4-2)。整个CD的核心过程是一个利用各自工具实现自动化流水线的过程。

图4-2 CD 持续迭代流程图

相比传统运维,可以看到 DevOps 对于变更最大的改进点在于 DevOps的工具能自动地完成之前需要人工操作的点,如上线前单元测试情况等信息的确认。对传统运维的变更管理来说,变更执行的稳定性完全取决于运维团队、开发团队的技术能力和执行力。DevOps用工具替代了传统运维的人工变更,通过建立CI/CD工具链,充分利用工具流水线的优势,减少了对个人技术和经验的依赖。

需要注意的是,传统运维的变更管理因为涉及运维和开发两个独立的部门,有时会因为人员警觉性下降,出现规范不执行或规范执行不到位等情况,结果就是实际线上产品的质量会出现周期性反复。在DevOps的变更管理中,整个工具链路和流程都融合到了一起,以前大量需要人工交互的环节都被工具替换了,真正需要人工参与的部分其实很少。因为所有的检查项和点都被工具覆盖,所以整个变更的稳定性会得到很大的提升。DevOps、传统运维、SRE的对比如表4-2所示。

表4-2 DevOps、传统运维、SRE的对比

DevOps在执行变更管理的时候,因为角色属性更多地偏开发一些,所以整个变更管理的侧重点会更倾向于代码开发/发布相关的流程和环节。在所有的DevOps相关介绍中,大量的实例都在介绍CI/CD。这在十年前传统的物理服务器部署上是很难想象的。

当整个业务都运行在云计算或K8S这样的平台时,DevOps会慢慢显示出它的优势,云平台工具让CI/CD有了落地基础。DevOps是将所有团队的做事方式对齐,不同团队的开发团队可能都实现了CI/CD,但是不同开发团队的CI/CD实现过程可能是完全不一样的。

传统运维和开发之前是有工具进行自动化对接的,也可以消灭需要人工交互的环节。关于这个问题我们可以回到DevOps的属性上,DevOps是在所有的团队中统一沟通做事方式,而这恰恰是传统运维在落地一些工具时的困难点。传统运维可以对一个部门进行自动化对接,但很难做到让所有部门都对接完成。如果传统运维真的做到了,那么就说明传统运维开始转型为SRE了。

4.1.3 SRE的变更管理

传统运维转型为 SRE 后,SRE 不可避免地会重新对变更管理进行一些探索,落地时主要结合DevOps和传统运维的一些变更管理方式。和DevOps一样,SRE也会非常注意变更管理的自动化建设,也会从运维的角度出发,致力于降低变更复杂度,实现和DevOps类似的效果。

首先是变更流程设计,SRE与传统运维最大的不同就是变更流程中的某些操作变得更加自动化。例如,最早的时候我们变更一份 Word 表单,是用邮件审批然后衍化成ITIL(Information Technology Infrastructure Library,信息技术基础设施组织标准)的形式,或者是用Web交互的形式。这个过程只是丰富了表单填写项,加了简单的审批逻辑,操作的内容完全依赖申请人的填写。运维团队和开发团队在实践这种管理方式时没有统一的做事方式,这会导致在执行效果上有很多的问题。

于是我们在细致梳理这样的场景后,从变更需求开始,将之前口头或手动操作的环节整理完善,然后用工具约束。例如,针对之前用户提的不合理性变更和新的变更提交工具默认进行多项检测,对变更提交进行约束和引导,另外针对变更流程中人工执行的环节,变成类似 DevOps 变更管理中CI/CD这样的自动执行机制。这种变化一方面解放了开发团队的精力,他们可以聚焦于代码开发,不用担心基础设施和流程;另一方面通过这样的工具化改造,解放了运维人力,使线上变更结果变得更加可控和可预测。

相比DevOps的变更管理,SRE虽然保留了变更表单和变更流程,但在变更表单部分,大部分的填写内容要么是模板化的,要么是工具自动填充合适的内容。例如,变更表单中的“变更内容”,之前是人工填写的,现在会变成工具自动从Git(代码维护工具)提交日志中提取信息。变更表单提交的自动化改造完成后,信息传递也更加清晰,不怕有人填写的变更表单不清楚导致没办法评审或自动化执行变更(也就是所有的团队都使用一样的发布流程和技术)。

和DevOps不一样的一点是,SRE虽然使用统一的变更工具,但会对不同的业务适配不同的发布策略(也就是不同的团队使用的变更机制一样,但在策略上允许自定义变更机制)。DevOps 在线上变更时有一步是“User Acceptance Test(用户接受度测试)”,而SRE会有对应“蓝绿发布”“灰度发布”“滚动发布”等众多的策略,更侧重变更的平滑性。

这里的区别是DevOps聚焦的是变更的逐渐性和可控性,而SRE聚焦的是整个变更会不会导致故障。实践时,要在整个变更管理中保留变更表单这样的形式,因为有些属性是传统的CI/CD流水线无法完全体现的。

例如,如果一个业务这次执行的是小变更,正常执行变更时使用默认的“灰度发布”策略就可以,如果下一次执行的是一个大变更,就需要执行“蓝绿发布”策略。如果是DevOps的CI/CD流水线,这样的调整往往很麻烦,因为发布信息里面可能无法包含这样的差异信息,所以CI/CD流水线很难做自动适配。即使能做到这点,整个流水线也会依赖人工去调整。

在自动化变更工具实现上,相比DevOps让所有业务都使用CI/CD模式,SRE 的每个业务都可以有个性化的实现(一般是业务对应的开发工程师各自维护各自产品的CI/CD工具)。SRE更加倾向于维护统一的平台,开放平台可调整项目满足每个业务真实的个性化需求。

除了在工具实现方面不一样,SRE和DevOps在变更执行上也会有些不一样的点。假设同样执行一个变更,执行到最后的时候,因为新旧代码不兼容,所以线上有少量页面报错,DevOps可能会从代码角度出发,接受这样的异常,如果评估确认后认为这个异常是暂时无法规避的,那么就会继续执行变更。SRE则会在看到异常报错后,先按照SLI/SLO评估,如果对应周期内的业务错误比例过高,那么就会有很大的概率停止新版本的发布,改由另外的时间执行。

4.1.4 变更管理实践总结

上面讲的一些变更管理机制,在公司内部的不同时期,不同部门都有应用和落地。虽然公司内部还有少量团队自己维护CI/CD流水线,但更多的是统一使用发布平台。因为对于多数业务来说,最主要的变更是线上发布,发布平台是目前相对省心的方式。在实际工作中,基本上开发工程师只要填写一下业务的集群信息、发布软件仓库和Git提交版本,就可以生成一个新的发布变更。如果是针对旧集群的发布,可以直接在对应集群上替换Git提交的 Hash 来实现发布。另外这样的操作可以让开发工程师自助执行,也可以让运维工程师介入执行(一般运维工程师只介入核心工程的发布或是线上错误配额消耗较多的情况)。

针对非业务发布相关的变更,如SRE发起的某些系统层面的调整,还可以执行之前的变更表单模式。只是在这里我们会充分利用历史变更的数据,平台会按照类型对变更进行分类和统计,实现在填写变更时,自动填充变更模板,进而提升变更的操作命令和流程一致性。另外当流程流转到审批环节时,审批人除了可以查阅变更主题内容,还可以关注对应变更的历史成功率等数据,让决策更有依据。

相比最初的模式,SRE团队在变更管理上更多的是注重用平台和工具减少人工操作。通过不断地梳理业务需求和应用场景,迭代平台的特性和功能,实现公司内部所有业务团队使用统一的变更平台。