5.2. Source-to-Image (S2I) 构建
Source-to-Image (S2I) 是一种用于构建可重复生成的 Docker 格式容器镜像的工具。它通过将应用程序源代码注入容器镜像并汇编新镜像来生成可随时运行的镜像。新镜像融合了基础镜像(构建器)和构建的源代码,并可搭配 buildah run
命令使用。S2I 支持递增构建,可重复利用以前下载的依赖项和过去构建的工件等。
S2I 的优点包括:
镜像灵活性 |
可以编写 S2I 脚本,将应用程序代码注入到几乎所有现有的 Docker 格式容器镜像,以此利用现有的生态系统。请注意,S2I 目前依靠 |
速度 | 使用 S2I 时,汇编过程可以执行大量复杂操作,无需在每一步创建新层,进而能实现快速的流程。此外,可以编写 S2I 脚本来重复利用应用程序镜像的旧版本,而不必在每次运行构建时下载或构建它们。 |
可修补性 | 如果基础镜像因为安全问题而需要补丁,则 S2I 允许基于新的基础镜像重新构建应用程序。 |
操作效率 | 通过限制构建操作而不许随意进行 Dockerfile 允许的操作,PaaS 运维人员可以避免意外或故意滥用构建系统。 |
操作安全性 | 构建任意 Dockerfile 会将主机系统暴露于 root 特权提升。因为整个 Docker 构建过程都通过具备 Docker 特权的用户运行,这可能被恶意用户利用。S2I 限制以 root 用户执行操作,而能够以非 root 用户运行脚本。 |
用户效率 |
S2I 禁止开发人员在应用程序构建期间执行任意 |
生态系统 | S2I 倡导共享镜像生态系统,您可以将其中的最佳实践运用于自己的应用程序。 |
可重复生成性 | 生成的镜像可以包含所有输入,包括构建工具和依赖项的特定版本。这可确保精确地重新生成镜像。 |
5.2.1. 执行 Source-to-Image (S2I) 增量构建
S2I 可以执行增量构建,也就是能够重复利用过去构建的镜像中的工件。
流程
要创建增量构建,请创建 BuildConfig
并对策略定义进行以下修改:
strategy: sourceStrategy: from: kind: "ImageStreamTag" name: "incremental-image:latest" 1 incremental: true 2
其他资源
- 如需有关如何创建支持增量构建的构建器镜像的信息,请参阅 S2I 要求。
5.2.2. 覆盖 Source-to-Image (S2I) 构建器镜像脚本
您可以覆盖构建器镜像提供的 assemble、run 和 save-artifacts S2I 脚本。
流程
要覆盖构建器镜像提供的 assemble、run 和 save-artifacts S2I 脚本,请执行以下任一操作:
- 在应用程序源存储库的 .s2i/bin 目录中提供 assemble、run 或 save-artifacts 脚本;或者
- 提供包含脚本的目录的 URL,作为策略定义的一部分。例如:
strategy:
sourceStrategy:
from:
kind: "ImageStreamTag"
name: "builder-image:latest"
scripts: "http://somehost.com/scripts_directory" 1
- 1
- 此路径会将 run、assemble 和 save-artifacts 附加到其中。如果找到任何或所有脚本,将使用它们代替镜像中提供的同名脚本。
位于 scripts
URL 的文件优先于源存储库的 .s2i/bin 中的文件。
5.2.3. Source-to-Image (S2I) 环境变量
可以通过两种方式将环境变量提供给源构建过程和生成的镜像:环境文件和 BuildConfig 环境值。提供的变量将存在于构建过程和输出镜像中。
5.2.3.1. 使用 Source-to-Image (S2I) 环境文件
利用源代码构建,您可以在应用程序内设置环境值(每行一个),方法是在源存储库中的 .s2i/environment 文件中指定它们。此文件中指定的环境变量存在于构建过程和输出镜像。
如果在源存储库中提供 .s2i/environment 文件,则 S2I 会在构建期间读取此文件。这允许自定义构建行为,因为 assembe 脚本可能会使用这些变量。
流程
例如,在构建期间禁用 Rails 应用程序的资产编译:
-
在 .s2i/environment 文件中添加
DISABLE_ASSET_COMPILATION=true
。
除了构建之外,指定的环境变量也可以在运行的应用程序本身中使用。例如,使 Rails 应用程序在 development
模式而非 production
模式中启动:
-
在 .s2i/environment 文件中添加
RAILS_ENV=development
。
其他资源
- 使用镜像部分中提供了各个镜像支持的环境变量的完整列表。
5.2.3.2. 使用 Source-to-Image (S2I) BuildConfig 环境
您可以在 BuildConfig
的 sourceStrategy
定义中添加环境变量。这里定义的环境变量可在 assemble 脚本执行期间看到,也会在输出镜像中定义,使它们能够供 run 脚本和应用程序代码使用。
流程
- 例如,禁用 Rails 应用程序的资产编译:
sourceStrategy: ... env: - name: "DISABLE_ASSET_COMPILATION" value: "true"
其他资源
- “构建环境”部分提供了更多高级指导。
-
您也可以使用
oc set env
命令管理BuildConfig
中定义的环境变量。
5.2.4. 忽略 Source-to-Image (S2I) 源文件
Source-to-Image 支持 .s2iignore
文件,该文件包含了需要被忽略的文件列表。构建工作目录中的文件(由各种输入源提供)若与 .s2iignore
文件中指定的文件匹配,将不会提供给 assemble
脚本使用。
如需有关 .s2iignore
文件格式的更多详细信息,请参阅 Source-to-Image 文档。
5.2.5. 使用 S2I 从源代码创建镜像
Source-to-Image (S2I) 是一种框架,它可以轻松地将应用程序源代码作为输入,生成可运行编译的应用程序的新镜像。
使用 S2I 构建可重复生成的容器镜像的主要优点是便于开发人员使用。作为构建器镜像作者,您必须理解两个基本概念,才能让您的镜像提供最佳的 S2I 性能:构建过程和 S2I 脚本。
5.2.5.1. 了解 S2I 构建过程
构建过程包含以下三个基本元素,这些元素组合成最终的容器镜像:
- 源代码
- S2I 脚本
- 构建器镜像
在构建过程中,S2I 必须将源代码和脚本放在构建器镜像中。为此,S2I 创建一个包含源和脚本的 tar
文件,然后将该文件流传输到构建器镜像中。在执行 assemble
脚本前,S2I 解压缩该文件并将其内容放到构建器镜像的 io.openshift.s2i.destination
标签中指定的位置,默认位置为 /tmp
目录。
为了使这个过程能够发生,您必须提供 tar
存档实用程序(可在 $PATH
中使用的 tar
命令)和命令行解释器(/bin/sh
命令);这样,您的镜像能够使用最快捷的构建路径。如果 tar
或 /bin/sh
命令不可用,则强制 s2i build
过程自动执行额外容器构建,将源和脚本放进镜像中,然后才运行常规构建。
参见下图中的基本 S2I 构建工作流:
图 5.1. 构建工作流
运行构建的过程包括解压源代码、脚本和工件(若存在),并且调用 assemble
脚本。如果这是二次运行(在捕获了“未找到 tar
或 /bin/sh
”错误后),它将仅负责调用 assemble
脚本,因为脚本和源代码都已就位。
5.2.5.2. 编写 S2I 脚本
您可以使用任何编程语言编写 S2I 脚本,只要脚本可在构建器镜像中执行。S2I 支持多种提供 assemble
/run
/save-artifacts
脚本的选项。每次构建时按以下顺序检查所有这些位置:
- BuildConfig 中指定的脚本
-
在应用程序源
.s2i/bin
目录中找到的脚本 -
在默认镜像 URL(
io.openshift.s2i.scripts-url
标签)中找到的脚本
镜像中指定的 io.openshift.s2i.scripts-url
标签和 BuildConfig
中指定的脚本都可以采用以下形式之一:
-
image:///path_to_scripts_dir
- 镜像中 S2I 脚本所处目录的绝对路径 -
file:///path_to_scripts_dir
- 主机上 S2I 脚本所处目录的相对或绝对路径 -
http(s)://path_to_scripts_dir
- S2I 脚本所处目录的 URL
脚本 | 描述 |
---|---|
assemble(必需) | assemble 用来从源代码构建应用程序工件,并将其放置在镜像内部的适当目录中的脚本。此脚本的工作流为:
|
run(必需) | run 脚本将执行您的应用程序。 |
save-artifacts(可选) | save-artifacts 脚本将收集所有可加快后续构建过程的依赖项。例如:
这些依赖项收集到一个 tar 文件中,再传输到标准输出。 |
usage(可选) | 借助 usage 脚本,可以告知用户如何正确使用您的镜像。 |
test/run(可选) | 借助 test/run 脚本,可以创建一个简单流程来检查镜像是否正常工作。该流程的建议工作流是:
注意 建议将 test/run 脚本构建的测试应用程序放置到镜像存储库中的 test/test-app 目录。如需更多信息,请参阅 S2I 文档。 |
5.2.5.2.1. S2I 脚本示例
以下示例 S2I 脚本采用 Bash 编写。每个示例都假定其 tar 内容解压缩到 /tmp/s2i
目录中。
例 5.1. assemble
脚本:
#!/bin/bash # restore build artifacts if [ "$(ls /tmp/s2i/artifacts/ 2>/dev/null)" ]; then mv /tmp/s2i/artifacts/* $HOME/. fi # move the application source mv /tmp/s2i/src $HOME/src # build application artifacts pushd ${HOME} make all # install the artifacts make install popd
例 5.2. run
脚本:
#!/bin/bash # run the application /opt/application/run.sh
例 5.3. save-artifacts 脚本:
#!/bin/bash pushd ${HOME} if [ -d deps ]; then # all deps contents to tar stream tar cf - deps fi popd
例 5.4. usage
脚本:
#!/bin/bash # inform the user how to use the image cat <<EOF This is a S2I sample builder image, to use it, install https://github.com/openshift/source-to-image EOF