ARTICLE DETAIL

资讯详情

深耕商务建站与企业官网运营的一线实战洞察。

OpenShift Builds 构建体系详解:Docker、S2I 与自定义构建策略实战指南

OpenShift Builds 构建体系详解:Docker、S2I 与自定义构建策略实战指南 测试云原生质量保障【免费下载链接】originConformance test suite for OpenShift项目地址https://gitcode.com/gh_mirrors/or/origin点击查看免费下载本文以 docs/builds.md 为核心脉络系统讲解 OpenShift即 origin 项目中镜像构建 API 的设计动机、三种默认构建策略Docker、Source-to-Image、Custom的原理与配置方法并结合本仓库的 e2e 测试与真实 YAML/JSON 配置样例帮助读者掌握如何通过构建 API 让 OpenShift 成为可调度、可限制资源、可被第三方 CI 编排的容器镜像构建后端。背景与动机为什么 Kubernetes 需要构建能力Kubernetes 本身只负责运行容器它从镜像仓库拉取已经构建好的镜像再以 Pod 的形式调度运行。镜像的构建环节并不在 Kubernetes 的核心能力范围内——按照原文档 docs/builds.md 的论述在没有构建支持的情况下系统管理员若想获得镜像构建能力只能自行挑选一套既有构建系统或从零编写一套并自行解决如何在 Kubernetes 之上或之外部署、维护它。然而大多数运维人员更希望复用 Kubernetes 的任务调度能力把构建任务作为可调度的任务塞进现有的资源池中而不是另起炉灶。这正是 OpenShift 构建 API 存在的根本理由构建 API 让 OpenShift 成为第三方容器镜像构建系统的可用后端这类系统通常需要资源约束与调度能力组织可以从既有的持续集成CI流程中编排 Docker 构建形成围绕容器镜像的 CI/CD 流水线绝大多数构建任务都具有共同特征一组构建输入、一个必须运行到完成的构建过程、构建过程日志的捕获、成功构建产物的发布以及最终的构建状态Kubernetes 倡导的镜像驱动部署image-driven deployment流程也依赖镜像的持续可用。原文档特别强调两个设计原则构建应利用资源限制机制如 CPU 用量、内存用量、构建 Pod 执行时间上限待 Kubernetes 原生支持后即可生效并且构建应当可重复、结果一致相同的输入 相同的输出。典型用户场景原文档给出了四类核心场景构成了构建 API 的验收视角从源码 URL 构建镜像并推送至仓库最终在 OpenShift 中部署从二进制输入Docker context、产物构建镜像并推送至仓库作为提供镜像构建服务的厂商把资源分配、调度、垃圾回收等负担转嫁给 OpenShift而不是自己解决作为构建系统开发者借助 OpenShift 执行构建但仍从现有 CI 侧编排以契合组织的 DevOps SOP。两个示例用例云 IDE 场景Company X一家提供 Docker 化云 IDE 服务的公司需要为客户托管项目大规模构建镜像希望获得一套开箱即用的方案能处理调度、资源分配与垃圾回收。通过构建 APICompany X 可以将构建工作交给 OpenShift集中精力解决核心业务问题。企业 DevOps 场景Company YCompany Y 希望用 OpenShift 构建镜像但其 SOP 强制要求使用第三方 CI 服务器来触发构建如上游项目构建成功后触发和推进构建CI 中签收通过后晋升。借助构建 APICompany Y 在 CI 服务器中实现编排 OpenShift 构建的工作流从而与其组织 SOP 集成。构建策略总览OpenShift 构建系统基于构建 API 中可选类型type提供可扩展的构建策略支持。默认提供三种策略策略类型用途DockerDockerStrategy基于 Docker context / Dockerfile 执行docker buildSource / S2ISourceStrategy基于 Source-to-Image 工具将源码注入基础镜像并组装新镜像CustomCustomStrategy使用用户自定义的 builder 镜像来执行构建扩展构建过程Docker 构建策略使用 Docker 策略时用户可以提供一个 Docker context 的 URL 作为 Docker 构建的基础。工作原理OpenShift 让构建容器直接访问节点上的 Docker daemon。构建期间会创建一个只含单个容器build container的 Pod节点上的 Docker socket 以 bind mount 方式挂载进构建容器构建容器随后执行docker build所有与 Docker 的交互都经由节点的 Docker daemon 完成。优势允许在非特权容器中执行 Docker 构建最小化镜像存储需求减少所需 Docker daemon 的数量。劣势按用户约束资源变得更困难构建期间创建的容器处于 kubelet 管理范围之外构建期间创建的容器进程是远端 Docker 进程的子进程使容器清理更加困难。原文档指出这些问题都有可行的缓解路径该机制被认定为 work in progress。为什么不用 Docker-in-Docker理论上可以用容器内嵌套 Docker daemonDocker-in-Docker实现构建表面上有诱人优势构建进程资源可自然地被限制在用户可接受范围内cgroups且构建期间创建的容器以构建容器为父进程、清理简单。但实践中存在无法接受的严重问题需要特权容器——这是无法解决的、一票否决的安全问题同时它也抵消了 cgroups 隔离的理论收益因为进程可能逃逸出容器使用 devicemapper 时极易在宿主机上泄漏 loopback 设备与存储构建容器之间难以共享镜像/层存储每个 Docker-in-Docker 实例都必须保存构建期间下载镜像的完整独立副本节点上的缓存代理至多能减少从远端仓库拉取镜像的次数无法消除每容器独立副本的需求。因此Docker-in-Docker 不被视为安全多租户生产环境下的可行构建策略。S2ISource-to-Image构建策略S2I 是一个用于构建可复现容器镜像的工具通过把用户源码注入容器镜像并组装出新的镜像产生可直接docker run的即用镜像。S2I 支持增量构建可复用之前下载的依赖、之前构建的产物等。从本仓库的 e2e 测试可以看到 S2I 策略的完整落地验证test/extended/builds/s2i_incremental.go 验证了增量 s2i 构建连续两次构建同一 BuildConfig第二次构建复用第一次构建产物随后用生成镜像实例化 Pod 与服务并curl验证容器内保存了上次构建的 artifacts响应包含artifacts existtest/extended/builds/s2i_env.go 验证源码中的环境文件.s2i/environment能正确注入应用响应包含successtest/extended/testdata/builds/test-build.yaml 中的sample-build展示了 Source 策略的标准写法source.type: Git指向https://github.com/openshift/ruby-hello-world.gitstrategy.type: Source并在sourceStrategy.env中注入FOO、BAR、BUILD_LOGLEVEL等环境变量from指向image-registry.openshift-image-registry.svc:5000/openshift/ruby:3.3-ubi8作为 s2i 基础镜像。结合 CLI 的 S2I 实操路径来自 test/extended/builds/start.gooc new-app https://github.com/openshift/ruby-hello-world#config从带分支引用的仓库创建应用并触发 s2i 构建测试验证会正确检出config分支而不是同名目录oc start-build sample-build --wait启动构建并等待完成配合--commitfffffff等错误引用时--wait会检测到status is Failedoc start-build sample-build -e FOObar -e VARtest覆盖环境变量构建日志中会同时出现新增变量与 BuildConfig 中继承的变量如BARtestoc start-build sample-verbose-build --build-loglevel1可覆盖 BuildConfig 中的BUILD_LOGLEVEL。自定义Custom构建策略自定义构建策略与 Docker 构建策略非常相似区别在于用户可以自定义用于执行构建的 builder 镜像。Docker 构建默认使用openshift/origin-docker-builder镜像使用自定义 builder 镜像则可以完全定制构建过程。原文档给出的自定义构建策略 JSON 示例strategy: { type: Custom, customStrategy: { image: my-custom-builder-image, exposeDockerSocket: true, env: [ { name: EXPOSE_PORT, value: 8080 } ] } }exposeDockerSocket把宿主机 Docker socket 挂载进 builder 容器允许在其中执行docker build与docker push。原文档特别提示该能力未来可能被管理员限制。env向 builder 容器环境传入额外环境变量。默认注入 builder 容器的环境变量原文档明确列出以下默认传递的环境变量变量含义$BUILD当前 Build 的 JSON 表示$OUTPUT_IMAGEBuild 中配置的输出容器镜像名$OUTPUT_REGISTRYBuild 中配置的输出容器镜像仓库$SOURCE_URI源代码仓库的 URL$SOURCE_REF源代码仓库的分支、tag 或 ref$DOCKER_SOCKETDocker socket 的完整路径仓库中的 Custom 策略实战样例本仓库 e2e 测试提供了比文档示例更完整的 Custom 策略 YAML 配置test/extended/testdata/builds/test-custom-build.yamlkind: BuildConfig apiVersion: build.openshift.io/v1 metadata: name: sample-custom-build spec: strategy: type: Custom customStrategy: env: - name: BUILD_LOGLEVEL value: 2 forcePull: true from: kind: ImageStreamTag name: custom-builder-image:latest output: to: kind: ImageStreamTag name: sample-custom:latest可以看到 Custom 策略除env外还支持forcePull强制每次拉取最新 builder 镜像与from通过 ImageStreamTag 指定 builder 镜像来源构建产物通过output.to写入名为sample-custom:latest的 ImageStreamTag。配套的 builder 镜像定义位于 test/extended/testdata/builds/custom-build/Dockerfile它基于registry.redhat.io/rhel8/buildah:latest将待构建的 Dockerfile 样例Dockerfile.sample内容为FROM image-registry.openshift-image-registry.svc:5000/openshift/tools:latestRUN touch /tmp/built放入/tmp/input/并将真正的构建逻辑脚本build.sh设为 ENTRYPOINT——即builder 镜像运行时执行的就是自定义构建逻辑。对应的 e2e 测试见 test/extended/builds/custom_build.go完整演练了自定义构建链路# 1. 用二进制方式先构建出自定义 builder 镜像 oc new-build --binary --strategydocker --namecustom-builder-image oc start-build custom-builder-image --from-dirtest/extended/testdata/builds/custom-build # 2. 应用 Custom 策略的 BuildConfig 并启动构建 oc create -f test/extended/testdata/builds/test-custom-build.yaml oc start-build sample-custom-build # 3. 等待名为 sample-custom-build-1 的构建成功完成构建输入与 CLI 实操从仓库测试看完整命令链原文档把构建输入列为构建任务的公共特征之一。结合 test/extended/builds/start.go 与 test/extended/testdata/builds/test-build.yaml可梳理出 OpenShift 支持的多种输入方式与对应命令二进制输入Binary构建对应 BuildConfig 中source.type: Binary的配置例如sample-build-binarysource: type: Binary binary: {} strategy: type: Docker dockerStrategy: from: kind: DockerImage name: image-registry.openshift-image-registry.svc:5000/openshift/ruby:3.3-ubi8oc start-build支持以下二进制输入形态命令参数说明测试验证点--from-filefile以单个文件作为构建输入也支持 HTTPS URL输出Uploading file ... as binary input for the build--from-dirdir以目录Docker context作为输入输出Uploading directory ... as binary input for the build--from-reporepo以本地 Git 仓库作为输入可配合--commitsha指定提交输出at commit HEAD--from-archiveurl以远程归档zip作为输入配合contextDir处理归档内的顶层目录输出Uploading archive from ... as binary input for the build此外构建日志中会出现Build complete表示成功若 BuildConfig 无有效输入oc start-build会报错has no valid source inputs。Git 源码输入与 Dockerfile 输入Git 源码输入source.type: Gitsource.git.uri如sample-build使用https://github.com/openshift/ruby-hello-world.gitDockerfile 输入source.type: Dockerfilesource.dockerfile内联内容测试 test/extended/builds/dockerfile.go 用oc new-build -D -从 stdin 传入 Dockerfile 创建构建并验证生成的 BuildConfig 中spec.source.git为空、Dockerfile 内容被完整保存最终镜像的Config.User为 Dockerfile 中声明的USER 1001还覆盖了FROM scratch、输出 tag 推断ruby:latest、以及非法 Dockerfile 内容导致构建失败并在日志中报no such file or directory等场景。构建参数Build Args对于 Docker 策略可在dockerStrategy.buildArgs中预设参数也可用 CLI 覆盖dockerStrategy: buildArgs: - name: foofoo value: default测试验证test/extended/builds/start.go预设的 build arg 会传入构建日志输出其值defaultoc start-build ... --build-argfoofoobar可覆盖日志输出新值bar传入 Dockerfile 未声明的 arg如--build-argbarfoo构建仍成功但日志出现警告one or more build args were not consumed: [bar]。触发与取消构建sample-build的触发配置示例triggers: - type: ImageChange imageChange: {} - type: Generic generic: secret: mysecret secretReference: name: webhooksecret对应 Generic Webhook 的调用端点是POST /apis/build.openshift.io/v1/namespaces/ns/buildconfigs/sample-build/webhooks/secret/generic测试验证了用内联 secretmysecret与引用的 Secretsecretvalue1都能成功触发构建而错误 secretinvalid则不会产生任何构建。取消构建使用oc cancel-build buildName配合oc start-build --wait时--wait会检测到status is Cancelled对于因 nodeSelector 无法匹配而无法调度的构建系统会自动取消并在事件中记录取消原因BuildCancelledEventReason。构建的运行模型Pod、调度与资源限制从构建 API 的设计目标与当前实现看每次构建都以 Pod 形式承载。以 test/extended/builds/start.go 中的verifyBuildPod为例可以确认构建 Pod 的实际形态构建 Pod 名形如buildName-buildPod 会显式选择 linux 节点kubernetes.io/oslinuxnodeSelector源码克隆通过名为git-clone的 init container 完成出于 CVE-2024-45496.gitconfig 可能被利用执行任意命令的考虑该 init container 必须是非特权、仅保留CHOWN/DAC_OVERRIDE能力、并 drop ALL 其余能力、使用 runtime-default seccomp profile 的加固配置构建容器与 Docker daemon 的交互、日志捕获、产物发布均由 OpenShift 构建控制器协调。资源限制方面原文档强调构建应当能够限定 CPU、内存与 Pod 执行时间在仓库的 BuildConfig 样例中可以通过resources与nodeSelector字段如sample-build-binary-invalidnodeselector中的nodelabelkey: nodelabelvalue进行配置构建系统会根据这些约束调度构建 Pod。构建 API 的定位面向第三方构建系统与 CI/CD 编排回到原文档的核心理念为构建提供 API使 OpenShift 成为任意第三方容器镜像构建系统的可行后端。这意味着资源约束与调度能力由 OpenShift 统一提供第三方系统无需自行解决资源分配、调度与垃圾回收对应云 IDE 场景组织现有的 CI 流程Jenkins 等可以通过构建 API 触发、监控、晋升构建将 OpenShift 构建无缝嵌入既有 DevOps SOP对应企业 DevOps 场景构建输出进入 ImageStream/ImageStreamTag如sample-custom:latest为后续镜像驱动部署提供输入。本仓库 test/extended/builds/ 下的数十个 e2e 测试涵盖构建触发、Webhook、二进制输入、增量构建、环境变量、配额 s2i_quota.go、机密注入 secrets.go、构建清理 build_pruning.go 等从实践层面印证了构建 API 的完整能力面可作为深入理解构建系统行为与边界条件的参考起点。赞分享测试云原生质量保障【免费下载链接】originConformance test suite for OpenShift项目地址https://gitcode.com/gh_mirrors/or/origin点击查看免费下载相关推荐一次配好大麦自动抢票脚本从原理到启动的完整教程一次配好大麦自动抢票脚本从原理到启动的完整教程 本文以开源项目 ticket purchase 为例讲清这个大麦自动抢票工具怎么用。它解决的事情很明确你只GUI 自动化RPAHandsontable 自定义构建Custom Builds完全指南Monorepo 构建流程与各包构建命令详解Handsontable 自定义构建Custom Builds完全指南Monorepo 构建流程与各包构建命令详解 Handsontable 的构建流程前端UI组件如何快速构建Apache Airflow自定义Docker镜像完整实战指南如何快速构建Apache Airflow自定义Docker镜像完整实战指南 Apache Airflow作为业界领先的工作流编排平台其Docker镜像构建是后端任务调度工作流自动化数据编排批处理数据工程流程编排上一篇Imba样式修饰符为什么你需要掌握这3类核心功能下一篇PowerInfer终极指南嵌入式设备上实现快速LLM推理的完整解决方案创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表
PREV
查看更多资讯
NEXT
返回资讯列表