第 1 章 理解镜像构建

1.1. 构建(build)

构建 (build)是将输入参数转换为结果对象的过程。此过程最常用于将输入参数或源代码转换为可运行的镜像。BuildConfig 对象是整个构建过程的定义。

OpenShift Container Platform 使用 Kubernetes,从构建镜像创建容器并将它们推送到容器镜像 registry。

构建对象具有共同的特征,包括构建的输入,完成构建过程要满足的要求、构建过程日志记录、从成功构建中发布资源,以及发布构建的最终状态。构建会使用资源限制,具体是指定资源限值,如 CPU 使用量、内存使用量,以及构建或 Pod 执行时间。

OpenShift Container Platform 构建系统提供对构建策略的可扩展支持,它们基于构建 API 中指定的可选择类型。可用的构建策略主要有三种:

  • Docker 构建
  • Source-to-Image (S2I) 构建
  • Custom 构建

默认情况下,支持 Docker 构建和 S2I 构建。

构建生成的对象取决于用于创建它的构建器(builder)。对于 Docker 和 S2I 构建,生成的对象为可运行的镜像。对于 Custom 构建,生成的对象是构建器镜像作者指定的任何事物。

此外,也可利用 Pipeline 构建策略来实现复杂的工作流:

  • 持续集成
  • 持续部署

1.1.1. Docker 构建

Docker 构建策略调用 docker build 命令,它需要一个含有 Dockerfile 的存储库并且其中包含所有必要的工件,从而能生成可运行的镜像。

1.1.2. Source-to-Image (S2I) 构建

Source-to-Image (S2I) 是一种用于构建可重复生成的 Docker 格式容器镜像的工具。它通过将应用程序源代码注入容器镜像并汇编新镜像来生成可随时运行的镜像。新镜像融合了基础镜像(构建器)和构建的源代码,并可搭配 buildah run 命令使用。S2I 支持递增构建,可重复利用以前下载的依赖项和过去构建的工件等。

S2I 的优点包括:

镜像灵活性

可以编写 S2I 脚本,将应用程序代码注入到几乎所有现有的 Docker 格式容器镜像,以此利用现有的生态系统。请注意,S2I 目前依靠 tar 来注入应用程序源代码,因此镜像需要能够处理 tar 压缩的内容。

速度

使用 S2I 时,汇编过程可以执行大量复杂操作,无需在每一步创建新层,进而能实现快速的流程。此外,可以编写 S2I 脚本来重复利用应用程序镜像的旧版本,而不必在每次运行构建时下载或构建它们。

可修补性

如果基础镜像因为安全问题而需要补丁,则 S2I 允许基于新的基础镜像重新构建应用程序。

操作效率

通过限制构建操作而不许随意进行 Dockerfile 允许的操作,PaaS 运维人员可以避免意外或故意滥用构建系统。

操作安全性

构建任意 Dockerfile 会将主机系统暴露于 root 特权提升。因为整个 Docker 构建过程都通过具备 Docker 特权的用户运行,这可能被恶意用户利用。S2I 限制以 root 用户执行操作,而能够以非 root 用户运行脚本。

用户效率

S2I 禁止开发人员在应用程序构建期间执行任意 yum install 类型的操作。因为这类操作可能会减慢开发迭代速度。

生态系统

S2I 倡导共享镜像生态系统,您可以将其中的最佳实践运用于自己的应用程序。

可重复生成性

生成的镜像可以包含所有输入,包括构建工具和依赖项的特定版本。这可确保精确地重新生成镜像。

1.1.3. Custom 构建

采用 Custom 构建策略时,开发人员可以定义负责整个构建过程的特定构建器镜像。通过利用自己的构建器镜像,可以自定义构建流程。

自定义构建器(Custom builder)镜像是嵌入了构建过程逻辑的普通 Docker 格式容器镜像,例如用于构建 RPM 或基础镜像。

Custom 构建以级别很高的特权运行,默认情况下不可供用户使用。只有可赋予集群管理权限的用户才应被授予运行自定义构建的权限。

1.1.4. Pipeline 构建

重要

Pipeline 构建策略在 OpenShift Container Platform 4 中弃用。基于 Tekton 的 OpenShift Pipelines 中带有等效且改进的功能。

OpenShift 上的 Jenkins 镜像被完全支持,用户可以按照 Jenkins 用户文档在作业中定义 Jenkinsfile,或者将其存储在 Source Control Management 系统中。

采用 Pipeline 构建策略时,开发人员可以定义由 Jenkins Pipeline 插件执行的 Jenkins Pipeline。构建可以由 OpenShift Container Platform 启动、监控和管理,其方式与任何其他构建类型相同。

Pipeline 工作流在 Jenkinsfile 中定义,或直接嵌入在构建配置中,或者在 Git 存储库中提供并由构建配置引用。