You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Jun 3, 2025. It is now read-only.
While kaniko itself does not natively support building multi-arch
container manifests, it may be used in combination with tools such as
manifest-tool to create and merge seperate arch builds into a single
manifest.
Fixes#1102Fixes#786
1. You need access to build-machines running the desired architectures
1169
+
(running Kaniko in an emulator, e.g. QEMU should also be possible but goes
1170
+
beyond the scope of this documentation). This is something to keep in mind
1171
+
when using SaaS build tools such as github.com or gitlab.com, of which at the
1172
+
time of writing neither supports any non-x86_64 SaaS runners ([GitHub](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#supported-runners-and-hardware-resources),[GitLab](https://docs.gitlab.com/ee/ci/runners/saas/linux_saas_runner.html#machine-types-available-for-private-projects-x86-64)),
1173
+
so be prepared to bring your own machines ([GitHub](https://docs.github.com/en/actions/hosting-your-own-runners/about-self-hosted-runners),[GitLab](https://docs.gitlab.com/runner/register/).
1174
+
2. Kaniko needs to be able to run on the desired architectures. At the time of
1175
+
writing, the official Kaniko container supports [linux/amd64, linux/arm64,
1176
+
linux/s390x and linux/ppc64le (not on *-debug images)](https://github.com/GoogleContainerTools/kaniko/blob/main/.github/workflows/images.yaml).
1177
+
3. The container registry of your choice must be OCIv1 or Docker v2.2
1178
+
compatible.
1179
+
1180
+
### Example CI Pipeline (GitLab)
1181
+
1182
+
It is up to you to find an automation tool that suits your needs best.
1183
+
We recommend using a modern CI/CD system such as GitHub workflows or GitLab CI.
1184
+
As we (the authors) happen to use GitLab CI, the following examples are
1185
+
tailored to this specific platform but the underlying principles should apply
1186
+
anywhere else and the examples are kept simple enough, so that you should be
1187
+
able to follow along, even without any previous experiences with this specific
1188
+
platform. When in doubt, visit the [gitlab-ci.yml reference page](https://docs.gitlab.com/ee/ci/yaml/index.html)
1189
+
for a comprehensive overview of the GitLab CI keywords.
1190
+
1191
+
#### Building the Separate Container Images
1192
+
1193
+
gitlab-ci.yml:
1194
+
1195
+
```yaml
1196
+
# define a job for building the containers
1197
+
build-container:
1198
+
stage: container-build
1199
+
# run parallel builds for the desired architectures
1200
+
parallel:
1201
+
matrix:
1202
+
- ARCH: amd64
1203
+
- ARCH: arm64
1204
+
tags:
1205
+
# run each build on a suitable, preconfigured runner (must match the target architecture)
1206
+
- runner-${ARCH}
1207
+
image:
1208
+
name: gcr.io/kaniko-project/executor:debug
1209
+
entrypoint: [""]
1210
+
script:
1211
+
# build the container image for the current arch using kaniko
1212
+
- >-
1213
+
/kaniko/executor
1214
+
--context "${CI_PROJECT_DIR}"
1215
+
--dockerfile "${CI_PROJECT_DIR}/Dockerfile"
1216
+
# push the image to the GitLab container registry, add the current arch as tag.
1217
+
--destination "${CI_REGISTRY_IMAGE}:${ARCH}"
1218
+
```
1219
+
1220
+
#### Merging the Container Manifests
1221
+
1222
+
gitlab-ci.yml:
1223
+
1224
+
```yaml
1225
+
# define a job for creating and pushing a merged manifest
1226
+
merge-manifests:
1227
+
stage: container-build
1228
+
# all containers must be build before merging them
1229
+
# alternatively the job may be configured to run in a later stage
1230
+
needs:
1231
+
- container-build
1232
+
artifacts: false
1233
+
tags:
1234
+
# may run on any architecture supported by manifest-tool image
1235
+
- runner-xyz
1236
+
image:
1237
+
name: mplatform/manifest-tool:alpine
1238
+
script:
1239
+
- >-
1240
+
manifest-tool
1241
+
# authorize against your container registry
1242
+
--username=${CI_REGISTRY_USER}
1243
+
--password=${CI_REGISTRY_PASSWORD}
1244
+
push from-args
1245
+
# define the architectures you want to merge
1246
+
--platforms linux/amd64,linux/arm64
1247
+
# "ARCH" will be automatically replaced by manifest-tool
1248
+
# with the appropriate arch from the platform definitions
1249
+
--template ${CI_REGISTRY_IMAGE}:ARCH
1250
+
# The name of the final, combined image which will be pushed to your registry
1251
+
--target ${CI_REGISTRY_IMAGE}
1252
+
```
1253
+
1254
+
#### On the Note of Adding Versioned Tags
1255
+
1256
+
For simplicity's sake we deliberately refrained from using versioned
1257
+
tagged images (all builds will be tagged as "latest") in the
1258
+
previous examples, as we feel like this adds to much platform and workflow
1259
+
specific code.
1260
+
1261
+
Nethertheless, for anyone interested in how we handle (dynamic) versioning in
1262
+
GitLab, here is a short rundown:
1263
+
1264
+
- If you are only interested in building tagged releases, you can simply
1265
+
use the [GitLab predefined](https://docs.gitlab.com/ee/ci/variables/predefined_variables.html) `CI_COMMIT_TAG` variable when running a tag pipeline.
1266
+
- When you (like us) want to additionally build container images outside of
1267
+
releases, things get a bit messier. In our case, we added a additional job
1268
+
which runs before the build and merge jobs (don't forget to extend the `needs`
1269
+
section of the build and merge jobs accordingly), which will set the tag to
1270
+
`latest`when running on the default branch, to the commit hash when run on
1271
+
other branches and to the release tag when run on a tag pipeline.
1272
+
1273
+
gitlab-ci.yml:
1274
+
1275
+
```yaml
1276
+
container-get-tag:
1277
+
stage: pre-container-build-stage
1278
+
tags:
1279
+
- runner-xyz
1280
+
image: busybox
1281
+
script:
1282
+
# All other branches are tagged with the currently built commit SHA hash
1283
+
- |
1284
+
# If pipeline runs on the default branch: Set tag to "latest"
1285
+
if test "$CI_COMMIT_BRANCH" == "$CI_DEFAULT_BRANCH"; then
1286
+
tag="latest"
1287
+
# If pipeline is a tag pipeline, set tag to the git commit tag
0 commit comments