使用 Buildah 和 Merge-Image 构建跨平台镜像
功能概述
本指南演示如何使用 buildah Task 按架构构建镜像,然后使用 merge-image Task 将它们合并为一个多架构镜像。
典型流程:
- 构建
linux/amd64镜像标签(例如:v1.0.0-amd64) - 构建
linux/arm64镜像标签(例如:v1.0.0-arm64) - 将源标签合并为一个或多个目标标签(例如
:v1.0.0、:latest)
使用场景
- 从一个代码仓库构建并发布多架构镜像。
- 保留按架构区分的构建产物,同时对外提供一个统一的发布标签。
- 在一次合并步骤中重新打标签并发布多个目标标签。
前提条件
- 已安装
Tekton Pipelines。 - 已安装
git-clone、buildah(0.9)和merge-image(0.1)Tasks。 - 你可以将镜像推送到镜像仓库。
- 镜像仓库凭据已准备为 Kubernetes
Secret。 - 如果你使用基于节点原生的构建(如本指南所示),则集群必须同时具备
amd64和arm64节点。 - 可选的本地验证工具:
crane、jq。
第 1 步:准备镜像仓库凭据
使用 config.json 创建一个通用 Secret:
第 2 步:创建 Pipeline 并运行 PipelineRun
使用前请更新以下值:
- Git 仓库 URL 和 revision
- 按架构区分的源镜像标签以及最终目标镜像标签
- Crane 运行时镜像(如果你需要替换默认值)
- Workspace 和 Secret 名称
示例 Pipeline:
示例 PipelineRun:
本示例中的关键点:
- 示例使用了
git-clone、buildah和merge-image的 hub resolver 引用,因此这些对应的 catalog Tasks 必须能在你的集群中被解析。 image-amd64和image-arm64是显式的 Pipeline 参数。这样可以使合并输入更清晰,并与merge-image消费sourceImages的方式保持一致。taskRunSpecs+podTemplate.nodeSelector配置在PipelineRun中;当你的集群包含混合 CPU 架构时,这一点至关重要。它们可以确保每个构建任务运行在匹配的节点架构上。- 默认情况下,Tekton 使用
coschedule: workspaces,这会创建一个 Affinity Assistant,并尝试将共享同一个基于 PVC 的 workspace 的 TaskRuns 调度到同一个节点上。如果你将buildah-amd64和buildah-arm64固定到不同架构,这种默认行为会与按任务设置的nodeSelector冲突。在这种情况下,请在TektonConfig中设置spec.pipeline.coschedule: disabled,这样 Tekton 就不会再强制共享 workspace 的 TaskRuns 运行在同一节点上。operator 会自动将该设置传播到feature-flagsConfigMap。 - 对于跨架构调度而言,禁用
coschedule是必要的,但仅靠这一点还不够。如果共享 workspace 由ReadWriteOncePVC 提供支持,那么 Kubernetes 仍然无法在两个不同节点上同时以读写方式挂载该卷。要在不同节点上并行运行 amd64 和 arm64 构建,请使用支持多节点共享的 workspace 后端,例如ReadWriteMany。 sourceImages应指向按架构区分的标签,而targetImages应为你希望发布的最终多架构标签。registry-credentialsworkspace 会被buildah和merge-image共同复用;workspace 名称映射(registryconfigvsregistry-config)由 Task 接口决定,必须与各自的 Task 定义匹配。
第 3 步:验证合并后的镜像平台
在 PipelineRun 成功后,你可以使用 crane、podman 或 skopeo 验证合并后的镜像平台:
使用 crane:
使用 podman:
使用 skopeo:
预期输出应包含:
linux/amd64linux/arm64
故障排查
- 如果
buildah-amd64和buildah-arm64共享同一个基于 PVC 的 workspace,并且被固定到不同架构,请检查 Tekton Pipelines 的 feature flagcoschedule。当你需要这些 TaskRuns 调度到不同节点时,请在TektonConfig中设置spec.pipeline.coschedule: disabled;默认的workspaces模式会通过 Affinity Assistant 尝试将它们共同放置在同一个节点上。关于确切的设置位置和行为,请参见 Unable to Use Multiple PVC Workspaces in Tekton。 - 即使设置了
coschedule: disabled,ReadWriteOncePVC 仍然不能在两个不同节点之间同时以读写方式挂载。若要实现真正的跨架构并行构建,请将共享 workspace 绑定到支持ReadWriteMany的存储。 - 建议将
sourceImages和targetImages保持在同一个镜像仓库中。允许跨镜像仓库输入,但merge-image会输出警告日志。 merge-image允许跨仓库合并。对于跨镜像仓库的源镜像或目标镜像,它会继续执行但输出警告日志,因此请确保所有涉及的镜像仓库凭据都有效。sourceImages和targetImages不能为空。重复的源引用或重复的源 digest 会被跳过,并且至少必须保留一个唯一的源镜像。- 对于自签名镜像仓库:
buildah:将 CA 文件挂载到sslcertdirmerge-image:将 CA 文件挂载到ca-bundle,并可选设置caFileName- 仅在受信任的环境中将
TLS_VERIFY/tlsVerify设为false
buildah参数使用大写(例如IMAGES、CONTAINERFILE),而merge-image使用 lower camel case(例如sourceImages、targetImages)。