必须满足以下条件:
您可以找到最适合您需求的自动化工具。我们建议使用现代 CI/CD 系统,例如 GitHub 工作流程或 GitLab CI。由于我们(作者)碰巧使用 GitLab CI,因此以下示例是针对该特定平台量身定制的,但基本原则应该适用于其他任何地方,并且示例保持足够简单,以便您应该能够遵循,即使没有任何以前使用此特定平台的经验。如有疑问,请访问 gitlab-ci.yml 参考页面,获取 GitLab CI 关键字的全面概述。
gitlab-ci.yml:
# define a job for building the containers
build-container :
stage : container-build
# run parallel builds for the desired architectures
parallel :
matrix :
- ARCH : amd64
- ARCH : arm64
tags :
# run each build on a suitable, preconfigured runner (must match the target architecture)
- runner-${ARCH}
image :
name : gcr.io/kaniko-project/executor:debug
entrypoint : [""]
script :
# build the container image for the current arch using kaniko
- >-
/kaniko/executor --context "${CI_PROJECT_DIR}" --dockerfile
"${CI_PROJECT_DIR}/Dockerfile" # push the image to the GitLab container
registry, add the current arch as tag. --destination
"${CI_REGISTRY_IMAGE}:${ARCH}"
gitlab-ci.yml:
# define a job for creating and pushing a merged manifest
merge-manifests :
stage : container-build
# all containers must be build before merging them
# alternatively the job may be configured to run in a later stage
needs :
- job : container-build
artifacts : false
tags :
# may run on any architecture supported by manifest-tool image
- runner-xyz
image :
name : mplatform/manifest-tool:alpine
entrypoint : [""]
script :
- >-
manifest-tool # authorize against your container registry
--username=${CI_REGISTRY_USER} --password=${CI_REGISTRY_PASSWORD} push
from-args # define the architectures you want to merge --platforms
linux/amd64,linux/arm64 # "ARCH" will be automatically replaced by
manifest-tool # with the appropriate arch from the platform definitions
--template ${CI_REGISTRY_IMAGE}:ARCH # The name of the final, combined
image which will be pushed to your registry --target ${CI_REGISTRY_IMAGE}
为了简单起见,我们在前面的示例中故意避免使用版本化标记图像(所有版本都将标记为“最新”),因为我们觉得这会添加许多平台和工作流程特定的代码。
尽管如此,对于任何对我们如何在 GitLab 中处理(动态)版本控制感兴趣的人,这里有一个简短的概述:
CI_COMMIT_TAG
变量。needs
部分),这将在默认分支上运行时将标记设置为latest
,在其他分支上运行时为提交哈希,在标签管道上运行时为发布标签。gitlab-ci.yml:
container-get-tag :
stage : pre-container-build-stage
tags :
- runner-xyz
image : busybox
script :
# All other branches are tagged with the currently built commit SHA hash
- |
# If pipeline runs on the default branch: Set tag to "latest"
if test "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH"; then
tag="latest"
# If pipeline is a tag pipeline, set tag to the git commit tag
elif test -n "$CI_COMMIT_TAG"; then
tag="$CI_COMMIT_TAG"
# Else set the tag to the git commit sha
else
tag="$CI_COMMIT_SHA"
fi
- echo "tag=$tag" > build.env
# parse tag to the build and merge jobs.
# See: https://docs.gitlab.com/ee/ci/variables/#pass-an-environment-variable-to-another-job
artifacts :
reports :
dotenv : build.env
类似的工具包括:
所有这些工具都使用不同的方法构建容器映像。
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
。