必须满足以下条件:
您需要访问运行所需架构的构建机器(在模拟器中运行 Kaniko,例如 QEMU 也应该是可能的,但超出了本文档的范围)。在使用 github.com 或 gitlab.com 等 SaaS 构建工具时需要记住这一点,在撰写本文时,它们都不支持任何非 x86_64 SaaS 运行程序(GitHub、GitLab),因此请准备好自带机器(GitHub、GitLab。
Kaniko 需要能够在所需的架构上运行。在撰写本文时,官方 Kaniko 容器支持 linux/amd64、linux/arm64、linux/s390x 和 linux/ppc64le(不在 *-debug 映像上)。
您选择的容器注册表必须与 OCIv1 或 Docker v2.2 兼容。
您可以找到最适合您需求的自动化工具。我们建议使用现代 CI/CD 系统,例如 GitHub 工作流程或 GitLab CI。由于我们(作者)碰巧使用 GitLab CI,因此以下示例是针对该特定平台量身定制的,但基本原则应该适用于其他任何地方,并且示例保持足够简单,以便您应该能够遵循,即使没有任何以前使用此特定平台的经验。如有疑问,请访问 gitlab-ci.yml 参考页面,获取 GitLab CI 关键字的全面概述。
gitlab-ci.yml:
# 定义一个构建容器的作业build-container: stage: container-build # 为所需的架构运行并行构建 并行:矩阵: - ARCH:amd64 - ARCH:arm64 Tags:# 在合适的预配置运行器上运行每个构建(必须匹配目标架构)- runner-${ARCH} 图像:名称:gcr.io/kaniko-project/executor:debugentrypoint: [""] script:# 使用 kaniko->- /kaniko/executor 为当前架构构建容器镜像 --context "${CI_PROJECT_DIR}" --dockerfile "${CI_PROJECT_DIR}/Dockerfile" # 将镜像推送到 GitLab 容器注册表,添加当前拱门作为标签。 --目的地“${CI_REGISTRY_IMAGE}:${ARCH}”
gitlab-ci.yml:
# 定义一个作业来创建和推送合并的清单merge-manifests: stage: container-build # 所有容器必须在合并之前构建 # 或者,作业可以配置为在稍后阶段运行 需求: - 工作:容器构建工件:false 标签:#可以在manifest-tool image-runner-xyz支持的任何架构上运行 图像:名称:mplatform/manifest-tool:alpineentrypoint:[“”] 脚本: - >- manifest-tool # 针对您的容器注册表进行授权 --username=${CI_REGISTRY_USER} --password=${CI_REGISTRY_PASSWORD} push from-args # 定义要合并的架构 --platforms linux/amd64,linux/arm64 # “ARCH”将自动被清单工具替换为平台定义中的适当架构 --template ${CI_REGISTRY_IMAGE}:ARCH # 的名称最终的组合图像将被推送到您的注册表 --target ${CI_REGISTRY_IMAGE}
为了简单起见,我们在前面的示例中故意避免使用版本化标记图像(所有版本都将标记为“最新”),因为我们觉得这会添加许多平台和工作流程特定的代码。
尽管如此,对于任何对我们如何在 GitLab 中处理(动态)版本控制感兴趣的人,这里有一个简短的概述:
如果您只对构建标记版本感兴趣,则可以在运行标记管道时简单地使用 GitLab 预定义的CI_COMMIT_TAG
变量。
当您(像我们一样)想要在版本之外额外构建容器映像时,事情会变得有点混乱。在我们的例子中,我们添加了一个在构建和合并作业之前运行的附加作业(不要忘记相应地扩展构建和合并作业的needs
部分),这将在默认分支上运行时将标记设置为latest
,在其他分支上运行时为提交哈希,在标签管道上运行时为发布标签。
gitlab-ci.yml:
容器获取标签:阶段:预容器构建阶段 标签: - 跑步者-xyz 图片:busybox script:# 所有其他分支都用当前构建的提交 SHA 哈希标记- | # 如果管道在默认分支上运行:将标记设置为“最新” if test "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH"; then tag="latest" # 如果 pipeline 是 tag pipeline,则将 tag 设置为 git commit 标签 elif test -n "$CI_COMMIT_TAG"; then tag="$CI_COMMIT_TAG" # 否则将标签设置为 git commit sha else tag="$CI_COMMIT_SHA" fi - echo "tag=$tag" > build.env # 解析构建和合并作业的标签。 # 请参阅:https://docs.gitlab.com/ee/ci/variables/#pass-an-environment-variable-to-another-job 工件:报告:dotenv:build.env
类似的工具包括:
构建套件
图像
Orca 构建
乌莫奇
建造者
超光速
Bazel规则_docker
所有这些工具都使用不同的方法构建容器映像。
BuildKit (和img
)可以在容器内以非 root 用户身份执行,但需要禁用 seccomp 和 AppArmor 才能创建嵌套容器。 kaniko
实际上并不创建嵌套容器,因此不需要禁用 seccomp 和 AppArmor。 BuildKit 通过利用 QEMU 支持“交叉构建”多架构容器。
orca-build
依赖于runc
从 Dockerfile 构建镜像,它不能在容器内运行(原因与上面的img
类似)。 kaniko
不使用runc
,因此不需要使用内核命名空间技术。然而, orca-build
不需要 Docker 或任何特权守护进程(因此构建可以完全在没有特权的情况下完成)。
umoci
无需任何权限即可工作,并且对提取的根文件系统也没有限制(尽管如果您的文件系统足够复杂,则需要额外的处理)。但是,它没有类似Dockerfile
的构建工具(它是一个稍微低级的工具,可用于构建此类构建器 - 例如orca-build
)。
Buildah
专门构建 OCI 镜像。 Buildah 的命令复制 Dockerfile 中的所有命令。这允许使用或不使用 Dockerfile 构建映像,同时不需要任何 root 权限。 Buildah 的最终目标是提供一个较低级别的 coreutils 接口来构建镜像。无需 Dockerfile 构建镜像的灵活性允许将其他脚本语言集成到构建过程中。 Buildah 遵循简单的 fork-exec 模型,并不作为守护进程运行,但它基于 golang 中的综合 API,可以供应到其他工具中。
FTL
和Bazel
目标是尽可能最快地为镜像子集创建 Docker 镜像。这些可以被认为是一种特殊情况的“快速路径”,可以与 kaniko 提供的对通用 Dockerfiles 的支持结合使用。
kaniko 用户 Google 群组
要为 kaniko 做出贡献,请参阅 DEVELOPMENT.md 和 CONTRIBUTING.md。
拍摄快照时,kaniko 的哈希算法包括(或在--snapshot-mode=time
的情况下,仅使用)文件的mtime
来确定文件是否已更改。不幸的是,对文件进行更改和更新mtime
之间存在延迟。这意味着:
使用仅时间快照模式 ( --snapshot-mode=time
),kaniko 可能会完全错过RUN
命令引入的更改。
使用默认快照模式( --snapshot-mode=full
),在RUN
命令修改文件但内容没有改变的情况下 kaniko 是否会添加一层理论上是不确定的。这不会影响仍然正确的内容,但会影响层数。
请注意,这些问题目前仅是理论上的。如果您发现出现此问题,请提出问题。
--chown
支持Kaniko 目前支持COPY --chown
和ADD --chown
Dockerfile 命令。它不支持RUN --chown
。
Kaniko - 在没有 Docker 的 Kubernetes 中构建容器镜像。