3. 应用构建基础
在 OpenShift 中,构建(Build)是把源代码、Dockerfile 或流水线定义转换成可运行镜像的过程。理解三种构建策略的差异,是选择合适构建方式的前提。它们并不是互相替代的关系,而是分别面向不同的输入形态和团队能力。
Source-to-Image(S2I)的核心思想是“镜像即构建环境”。S2I 使用一个包含语言运行时和构建脚本的 builder 镜像,把源代码注入其中,执行 assemble 脚本完成依赖安装与编译,再通过 run 脚本定义容器启动方式。开发者只需提供源码仓库地址,无需编写 Dockerfile。它适合标准化的语言栈,例如 Java、Node.js、Python、PHP,团队希望统一构建规范、减少镜像维护成本时优先选择 S2I。
Docker 构建直接使用仓库中的 Dockerfile,由 OpenShift 调用构建器执行 docker build 等价流程。它适合需要精细控制镜像层、基础镜像、多阶段构建或引入特殊系统依赖的场景。当项目已有成熟 Dockerfile,或需要构建非标准运行时(如自定义 C 库、特定版本编译器)时,Docker 构建更灵活。
Pipeline 构建把构建过程定义为 Jenkins Pipeline 或 OpenShift Pipelines(Tekton)任务。它不局限于“源码到镜像”,而是可以编排测试、代码扫描、镜像推送、部署触发等多个阶段。适合需要多步骤质量门禁、跨仓库协作或复杂发布流程的团队。
BuildConfig 关键字段
BuildConfig(BC)是 OpenShift 中定义“如何构建”的核心资源。无论选择哪种策略,都需要通过 BC 描述输入、输出和触发条件。以下字段是实际配置中最常调整的:
spec.source:定义构建输入。S2I 和 Docker 构建通常使用type: Git,指定git.uri和ref;也可以使用type: Binary从本地流式上传源码。spec.strategy:决定构建类型。type: Source表示 S2I,需指定sourceStrategy.from(builder 镜像);type: Docker表示 Docker 构建,可指定dockerStrategy.dockerfilePath;type: JenkinsPipeline或type: Custom用于流水线类构建。spec.output:构建产物推送目标,通常为ImageStreamTag,例如myapp:latest。spec.triggers:定义自动触发构建的条件,是持续交付的关键。spec.resources:为构建 Pod 设置 CPU/内存请求与限制,避免构建过程影响集群稳定性。spec.completionDeadlineSeconds:构建超时时间,超时后构建被标记为失败。
下面是一个 S2I 构建的 BuildConfig 示例,使用 Node.js builder 镜像,输出到 web-app:latest:
apiVersion: build.openshift.io/v1
kind: BuildConfig
metadata:
name: web-app
spec:
source:
type: Git
git:
uri: https://github.com/example/web-app.git
ref: main
strategy:
type: Source
sourceStrategy:
from:
kind: ImageStreamTag
name: nodejs:18-ubi8
namespace: openshift
output:
to:
kind: ImageStreamTag
name: web-app:latest
triggers:
- type: ConfigChange
- type: ImageChange
imageChange:
from:
kind: ImageStreamTag
name: nodejs:18-ubi8
- type: GitHub
github:
secret: webhook-secret
resources:
requests:
cpu: "500m"
memory: "512Mi"
limits:
cpu: "1"
memory: "1Gi"
completionDeadlineSeconds: 1800
构建触发器:ConfigChange、ImageChange 与 Webhook
触发器让构建从“手动执行”变为“事件驱动”。OpenShift 支持三类主要触发器,理解它们的触发条件和验证方式,才能保证持续交付链路可靠。
ConfigChange:当 BuildConfig 本身被创建或更新时自动触发一次构建。它适合首次创建 BC 后立即验证配置是否正确,也适合在修改构建参数后自动重新构建。注意,它不会因为源码仓库变化而触发。
ImageChange:当指定的 ImageStreamTag 内容发生变化时触发构建。典型场景是 builder 镜像升级:当 nodejs:18-ubi8 标签指向新镜像时,所有引用它的 S2I 构建会自动重新执行,从而把安全补丁或运行时更新带入应用镜像。配置时需要指定 imageChange.from,并确保该 ImageStreamTag 存在。
Webhook:由外部系统通过 HTTP 请求触发,常见类型包括 GitHub、GitLab、Bitbucket 和 Generic。以 GitHub 为例,BC 创建后 OpenShift 会生成一个形如 https://api.example.com:6443/apis/build.openshift.io/v1/namespaces/myproject/buildconfigs/web-app/webhooks/<secret>/github 的 URL。在 GitHub 仓库的 Webhook 设置中填入该 URL,并选择 application/json 内容类型,即可在 push 或 pull request 时自动触发构建。
oc get bc web-app -o jsonpath='{.spec.triggers[?(@.type=="GitHub")].github.secret}' 查看。如果 secret 泄露,应删除并重新生成触发器。
配置与验证流程
实际配置时,建议按以下顺序操作并验证:
- 创建或确认 builder ImageStreamTag 可用:
oc get is nodejs -n openshift,确认18-ubi8标签存在。 - 编写 BuildConfig YAML,至少包含 source、strategy、output 和 triggers 四部分。
- 应用配置:
oc apply -f bc-web-app.yaml。 - 观察首次构建:
oc get builds应看到由 ConfigChange 触发的构建记录,状态从New变为Running,最终为Complete。 - 查看构建日志:
oc logs -f bc/web-app,确认 assemble 脚本执行成功、依赖安装无报错。 - 验证 ImageChange:手动更新 builder 镜像标签指向,例如
oc tag openshift/nodejs:18-ubi8 nodejs:18-ubi8 --source=imagestreamtag,观察是否产生新的构建。 - 验证 Webhook:在代码仓库提交一次变更,检查 OpenShift 中是否出现新的构建,并在 GitHub Webhook 的 Recent Deliveries 中确认返回 200。
选择构建策略时,可以用一个简单判断:如果团队希望“只写代码,不写 Dockerfile”,选 S2I;如果已有 Dockerfile 且需要精细控制镜像,选 Docker 构建;如果构建之外还要跑测试、扫描和多环境发布,选 Pipeline 构建。三者也可以组合使用,例如 Pipeline 中调用 S2I 或 Docker 构建作为其中一个阶段,从而兼顾标准化与流程编排能力。