如何使用 DevOps 构建成熟的内部开发 - VTB 经验

DevOps 实践工作。 当我们将版本安装时间减少 10 倍时,我们自己也确信了这一点。 在我们在 VTB 使用的 FIS Profile 系统中,安装现在需要 90 分钟而不是 10 分钟。发布构建时间从两周缩短到两天。 持续存在的实施缺陷的数量几乎已降至最低。 为了摆脱“体力劳动”并消除对供应商的依赖,我们不得不拄着拐杖工作,寻找意想不到的解决方案。 剪辑下方是关于我们如何构建成熟的内部开发的详细故事。

如何使用 DevOps 构建成熟的内部开发 - VTB 经验
 

序言:DevOps 是一种哲学

一年来,我们在组织VTB内部开发和实施DevOps实践方面做了大量的工作:

  • 我们为12个系统建立了内部开发流程;
  • 我们推出了 15 条管道,其中 XNUMX 条已投产;
  • 自动化1445个测试场景;
  • 我们成功实施了内部团队准备的多个版本。

最难组织 DevSecOps 实践的内部开发和实施之一是 FIS Profile 系统 - 非关系 DBMS 上的零售产品处理器。 尽管如此,我们还是能够构建开发、启动管道、在产品上安装单独的非发布包,并学习如何组装发布。 这项任务并不容易,但很有趣,并且在实施中没有明显的限制:这是系统 - 您需要构建一个内部开发。 唯一的条件是在生产环境之前使用CD。

乍一看,实现算法看起来简单明了:

  • 我们开发初始开发专业知识,并让代码团队达到可接受的质量水平,没有严重缺陷;
  • 我们尽可能融入现有流程;
  • 为了在明显的阶段之间传输代码,我们切断了一条管道并将其一端推入延续。

在此期间,所需规模的开发团队必须发展技能并将其对发布的贡献份额增加到可接受的水平。 就这样,我们可以认为任务完成了。

看起来,这是一条达到所需结果的完全节能的路径:这里是 DevOps,这里是团队的绩效指标,这里是积累的专业知识......但在实践中,我们收到了另一个确认,即 DevOps 仍然是哲学,而不是“附加到 gitlab 进程、ansible、nexus 以及列表中更靠后的位置。”

再次分析行动计划后,我们意识到我们正在内部建立一种外包供应商。 因此,在上述算法中加入了流程再造,以及整个开发路线上的专业知识的培养,以达到在这个流程中的主导作用。 这不是最简单的选择,但这是思想上正确的发展道路。
 

内部开发从哪里开始? 

这不是最友好的系统。 从架构上来说,它是一个大型的非关系型 DBMS,由许多单独的可执行对象(脚本、过程、批处理等)组成,这些对象根据需要进行调用,并按照黑匣子的原理工作:它接收请求并发出请求一个回应。 其他值得注意的困难包括:

  • 异国语言(MUMPS);
  • 控制台界面;
  • 缺乏与流行的自动化工具和框架的集成;
  • 数据量数十TB;
  • 每小时超过2万次操作的负载;
  • 重要性 - 业务关键。

同时,我们这边没有源代码存储库。 完全没有。 有文档,但所有关键知识和能力都在外部组织方面。
考虑到它的特性和低分布性,我们几乎从头开始掌握系统的开发。 2018年XNUMX月开始:

  • 研究了代码生成的文档和基础知识;
  • 我们研究了供应商提供的短期开发课程;
  • 掌握初步的开发技能;
  • 我们为新团队成员编写了培训手册;
  • 我们同意将团队纳入“战斗”模式;
  • 解决了代码质量控制问题;
  • 我们组织了一个发展展台。

我们花了三个月的时间培养专业知识并沉浸在系统中,从2019年初开始,内部开发开始迈向光明的未来,有时会遇到困难,但充满信心和目标明确。

存储库迁移和自动测试

第一个 DevOps 任务是存储库。 我们很快同意提供访问权限,但有必要从当前具有一个主干分支的 SVN 迁移到我们的目标 Git,并过渡到多个分支的模型并开发 Git Flow。 我们还有 2 个拥有自己基础设施的团队,以及部分供应商在国外的团队。 我必须忍受两个 Git 并确保同步。 在这种情况下,两害相权取其轻。

存储库的迁移一再推迟,直到四月份才在前线同事的帮助下完成。 对于 Git Flow,我们决定一开始就让事情变得简单,并选择了带有修补程序、开发和发布的经典方案。 他们决定放弃master(又名prod-like)。 下面我们将解释为什么这个选项对我们来说是最佳选择。 属于供应商的外部存储库(两个团队共用)被用作工作人员。 它根据时间表与内部存储库同步。 现在,有了 Git 和 Gitlab,就可以实现流程自动化。

自动测试的问题出人意料地轻松解决了——我们提供了一个现成的框架。 考虑到系统的特殊性,调用单独的操作是业务流程中可以理解的一部分,同时也可以作为单元测试。 剩下的就是准备测试数据并设置调用脚本和评估结果的所需顺序。 随着基于操作统计、流程关键性和现有回归方法形成的场景列表的填写,自动测试开始出现。 现在我们可以开始构建管道了。

它是怎样的:自动化之前的模型

现有的实施过程模型是一个单独的故事。 每个修改都作为单独的增量安装包手动传输。 接下来是在 Jira 中手动注册并在环境中手动安装。 对于单个软件包,一切看起来都很清楚,但随着发布的准备,事情变得更加复杂。

组装是在单独交付的层面上进行的,这些交付是独立的对象。 任何更改都是新的交付。 除其他外,主要版本组合的 60-70 个包中添加了 10-15 个技术版本 - 在版本中添加或排除某些内容并反映版本外销售变化时获得的版本。

交付内容中的对象彼此重叠,特别是在可执行代码中,其唯一性不到一半。 已安装的代码和刚刚计划安装的代码都存在许多依赖性。 

为了获得所需版本的代码,必须严格遵循安装顺序,在此过程中对象被物理重写多次,大约10-12次。

安装一批软件包后,我必须手动按照说明初始化设置。 该版本由供应商组装和安装。 该版本的组成几乎在实施之前就已明确,这需要创建“解耦”包。 结果,很大一部分供应品从一个发布到另一个发布,都有自己的“脱钩”尾巴。

现在很明显,使用这种方法 - 在包级别组装发布难题 - 单个主分支没有实际意义。 生产安装需要一个半小时到两个小时的体力劳动。 至少在安装程序级别指定了对象处理的顺序是件好事:在输入字段和结构的数据和过程之前输入字段和结构。 然而,这只能在单独的包中起作用。

这种方法的逻辑结果是不可避免的安装缺陷,其形式包括对象的歪曲版本、不必要的代码、缺少指令以及未考虑对象的相互影响,这些缺陷在发布后被疯狂地消除。 

首次更新:提交组装和交付

自动化首先通过沿着这条路线的管道传输代码:

  • 从仓库提取成品交货;
  • 安装在专用环境上;
  • 运行自动测试;
  • 评估安装结果;
  • 在测试命令一侧调用以下管道。

下一个管道应在 Jira 中注册任务并等待命令分发到选定的测试循环,这取决于任务实现的时间。 触发器 - 关于准备交付到给定地址的信件。 当然,这显然是一个拐杖,但我必须从某个地方开始。 2019 年 XNUMX 月,代码传输开始于对我们的环境进行检查。 该过程已经开始,剩下的就是将其调整为合适的形状:

  • 每次修改都在单独的分支中进行,该分支对应安装包并合并到目标master分支中;
  • 管道启动触发器是通过合并请求在主分支中出现新的提交,该提交由内部团队的维护人员关闭;
  • 存储库每五分钟同步一次;
  • 使用从供应商处收到的汇编器开始安装包的汇编。

此后,已经有检查和传输代码、启动管道并在我们这边组装的现有步骤。

该选项于七月推出。 过渡的困难导致了供应商和一线人员的一些不满,但在接下来的一个月里,我们成功地消除了所有的障碍,并在团队之间建立了一个流程。 我们现在通过提交和交付进行组装。
40 月份,我们成功地使用我们的管道完成了生产中单独软件包的首次安装,自 XNUMX 月份以来,所有单独的非发布软件包的安装无一例外都是通过我们的 CD 工具执行的。 此外,我们成功地以比供应商更小的团队完成了 XNUMX% 的发布组合中的内部任务 - 这绝对是成功的。 最重要的任务仍然是组装和安装该版本。

最终解决方案:累积安装包 

我们非常清楚,编写供应商指令的脚本是一种马马虎虎的自动化;我们必须重新考虑流程本身。 解决方案很明显 - 从发布分支收集累积供应以及所需版本的所有对象。

我们从概念验证开始:我们根据过去实现的内容手动组装发布包并将其安装在我们的环境中。 一切顺利,这个概念被证明是可行的。 接下来,我们解决了编写初始化设置脚本并将其包含在提交中的问题。 作为轮廓更新的一部分,我们准备了一个新包并在测试环境中对其进行了测试。 尽管实施团队提出了广泛的评论,但安装还是成功的。 但最重要的是,我们已获准在 XNUMX 月份的版本中进行组装并投入生产。

只剩下一个多月的时间了,精心挑选的物资显然暗示着时间已经不多了。 他们决定从发布分支进行构建,但为什么要把它分开呢? 我们没有类似产品的产品,现有的分支也不好——有很多不必要的代码。 我们迫切需要削减类似的产品,这已经超过三千次提交。 手工组装根本不是一种选择。 我们草拟了一个脚本,该脚本运行产品安装日志并收集对分支的提交。 第三次它工作正常,在“完成文件”之后,分支就准备好了。 

我们为安装包编写了自己的构建器,并在一周内完成了它。 然后我们必须从系统的核心功能修改安装程序,因为它是开源的。 经过一系列的检查和修改,结果算是成功了。 与此同时,版本的组成已经形成,为了正确安装,必须将测试电路与生产电路对齐,并为此编写了一个单独的脚本。

当然,对于第一次安装有很多评论,但总的来说,代码是有效的。 大约第三次安装后,一切开始看起来不错。 对象的组成控制和版本控制在手动模式下分别进行监控,这在现阶段是相当合理的。

另一个挑战是必须考虑大量未发布的情况。 但有了类似 Prod 的分支和 Rebase,任务就变得透明了。

第一次,快速且无错误

我们以乐观的态度对待发布,并在不同的电路上成功安装了十几次。 但实际上就在截止日期前一天,事实证明供应商尚未完成以可接受的方式准备安装版本的工作。 如果由于某种原因我们的构建无法正常工作,发布将会中断。 而且,通过我们的努力,这是特别不愉快的。 我们无路可退。 因此,我们考虑了替代方案,准备了行动计划并开始安装。

令人惊讶的是,由 800 多个对象组成的整个发布首次在短短 10 分钟内就正确启动。 我们花了一个小时检查日志寻找错误,但没有发现任何错误。

第二天一整天,发布聊天中都一片寂静:没有实现问题、歪曲的版本或“不合适”的代码。 甚至有点尴尬。 后来出现了一些评论,但与其他系统和之前的经验相比,其数量和优先级明显较低。

累积效应的另一个效果是组装和测试质量的提高。 由于完整版本的多次安装,及时发现了构建缺陷和部署错误。 在完整版本配置中进行测试可以额外识别增量安装期间未出现的对象相互影响中的缺陷。 这绝对是成功的,特别是考虑到我们对该版本的贡献达到了 57%。

结果和结论

在不到一年的时间里,我们成功做到了:

  • 使用外来系统构建成熟的内部开发;
  • 消除对供应商的关键依赖;
  • 启动 CI/CD 是为了一个非常不友好的遗产;
  • 将实施流程提升到新的技术水平;
  • 显着减少部署时间;
  • 显着减少执行错误的数量;
  • 自信地宣称自己是领先的开发专家。

当然,所描述的大部分内容看起来完全是废话,但这些都是系统的特征以及其中存在的流程限制。 目前,这些变化影响了 IS Profile 产品和服务(主账户、塑料卡、储蓄账户、托管、现金贷款),但该方法可能适用于任何设定了实施 DevOps 实践任务的 IS。 可以从许多交付中安全地复制累积模型以用于后续实施(包括非发布实施)。

来源: habr.com

添加评论