云原生应用以容器镜像作为发布形式。云原生应用的构建过程负责把源代码转换成可以直接运行的镜像。这个转换过程根据编程语言而有所不同:
解释型语言,如 JavaScript 和 Python,一般并不需要执行额外的构建步骤,可以直接添加源代码。
编译型语言,如 Java、Go 和 Rust,则需要首先对源代码进行编译,再把结果添加到镜像中。Go 和 Rust 可以直接编译成原生可执行文件,而 Java 则可以编译成字节代码运行在 JVM 上,也可以通过 GraalVM 进一步编译成原生可执行文件。
对编译型语言来说,整个构建过程至少是分成两步的。编译过程所需要的工具和第三方依赖比较多,而运行时所需要的依赖则很少。以 Java 为例,编译过程可能需要用到 Git、Maven、Gradle、JDK 和 GraalVM 等工具,而运行时则只需要 JDK 或 JRE。编译成原生可执行文件的 Java 应用,连 JDK 或 JRE 都不需要。
为了解决编译和运行阶段的差异性,一般有两种做法:
第一种做法是由持续集成服务器来进行编译,容器镜像中直接使用编译的结果。以 Maven 为例,在构建完成之后,只需要把生成的
target
目录下的 JAR 文件复制到镜像中即可。第二种做法是把编译过程也在容器中进行。
第二种做法在某些情况下是必须的。比如,有的镜像注册中心,仅支持构建镜像,并不提供