持续交付流水线软件构建的关键问题

由于静态语言从过程上要比动态语言复杂一些,代码提交后,对于 Java 和 C++ 这样的静态语言,我们要进行代码编译和打包。而对于 PHP 和 Python 这样的动态语言,就不需要编译,直接打包即可。同时,编译过程就开始要依赖多环境以及多环境下的配置管理,并根据不同的环境获取不同的配置,然后打包到最终的软件发布包中。

1. 配置文件如何打包?

按照持续交付理念,软件只需打包一次就可以各处运行,这对于代码编译是没有问题的,但是对于一些跟环境相关的配置就无法满足。

在做构建时,我们是可以确认这个软件包是要发布到哪个环境的。比如,按照流程,当前处于线下集成测试环境这个流程环节上,这时只要根据集成测试环境对应的配置项,生成配置文件,然后构建进软件包即可。如果是处于预发环境,那就生成预发环境对应的配置文件。

在我们的实际场景中,多个环境需要多次打包,这与我们持续交付中只构建一次的理念相悖。这并不是有意违背,而是对于 Java 构建出的交付件,最终无论生成的是 war 包,还是 jar 包,上述提到的跟环境相关的配置文件,是要在构建时就打入软件包中的。

而且在后续启动和运行阶段,我们是无法修改已经构建进软件包里的文件及其内容的。这样一来,配置文件无法独立发布,那么就必须跟软件包一起发布。所以,在实际场景下,我们要针对不同环境多次打包。

这就还是要依赖我们前面介绍的各个环节的建设过程,主要有以下 3 个方面:

  • 代码提交。通过分支提交管理模式,每次构建都以 master 为基线,确保合入的代码是以线上运行代码为基础的。且前面的发布分支代码未上线之前,后续分支不允许进入线上发布环节,确保发布分支在多环境下是同一套代码。
  • 编译环境统一。上述过程已经介绍,编译环境通过全新的 Docker 容器环境来保证。
  • 配置管理。前面介绍到的多环境配置管理手段, 通过模板和 auto-config 的配置管理能力,确保多环境配置项和配置值统一管理。至此,一个完整的软件构建过程就完成了。可以看到,如果充分完善前期的准备工作,在做后期的方案时就会顺畅很多。

2. 为什么用 Docker 做编译环境的工具?

Docker 容器很大的一个优势在于其创建和销毁的效率非常高,而且每次新拉起的实例都是全新的,消除了环境共用带来的交叉影响。而且对于并发打包的情况,Docker 可以快速创建出多个并行的实例来提供编译环境,所以无论在效率上还是环境隔离上,都有非常好的支持。

3. 为什么不直接生成 Docker 镜像做发布?

在使用 Docker 容器做编译的过程中,我们最终取得的交付件模式是一个 war 包,或者是一个 jar 包,这个也是我们后续发布的对象。如果单纯从发布的维度来看,直接发布镜像会更方便,更高效。不过,在现实场景下,我们应该更全面地看问题。

容器也好,虚拟机也罢,这些都是工具,只不过最终交付模式不一样。但是不管是标准化、多环境、配置管理等等这些基础工作,无论用不用容器都要去做。而且,容器的高效使用,一定是建立在更加完善和高度标准化的体系之上,否则工具只会是越用越乱。

此文章为3月Day25 学习笔记,内容来源于极客时间《赵成的运维体系管理课》,推荐该课程。

你可能感兴趣的:(运维,运维)