必須滿足以下條件:
您可以找到最適合您需求的自動化工具。我們建議使用現代 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
。