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