はじめに
docker imageのmulti-platform buildの動作確認手順を記載したもの。
実施環境
- Ubuntu 24.04, x86_64
- Docker 26.1.0
Docker Private Registry構築
docker imageの格納先となるPrivate Registryを構築する。
構築後、イメージが格納できることを確認しておく。
コマンド
$ docker run -d --name docker-registry -p 5000:5000 registry
$ docker pull busybox:latest
$ docker tag busybox:latest localhost:5000/busybox:latest
$ docker push localhost:5000/busybox:latest
実行結果のログ
実行結果
ubuntu@ubuntu:~/docker$ docker run -d --name docker-registry -p 5000:5000 registry
Unable to find image 'registry:latest' locally
latest: Pulling from library/registry
619be1103602: Pull complete
862815ae87dc: Pull complete
74e12953df95: Pull complete
6f0ce73649a0: Pull complete
ef4f267ce8ed: Pull complete
Digest: sha256:4fac7a8257b1d7a86599043fcc181dfbdf9c8f57e337db763ac94b0e67c6cfb5
Status: Downloaded newer image for registry:latest
14ee0d4b73c3e29eeb791630d14bd2ac249744c1dde48d42b52b71f6cbab084a
ubuntu@ubuntu:~/docker$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS
NAMES
14ee0d4b73c3 registry "/entrypoint.sh /etc…" 4 seconds ago Up 3 seconds 0.0.0.0:5000->5000/tcp, :::5000->5000/tcp docker-registry
ubuntu@ubuntu:~/docker$
ubuntu@ubuntu:~/docker$
ubuntu@ubuntu:~/docker$ curl -k http://localhost:5000/v2/_catalog
{"repositories":[]}
ubuntu@ubuntu:~/docker$
ubuntu@ubuntu:~/docker$
ubuntu@ubuntu:~/docker$ docker pull busybox:latest
latest: Pulling from library/busybox
ec562eabd705: Pull complete
Digest: sha256:5eef5ed34e1e1ff0a4ae850395cbf665c4de6b4b83a32a0bc7bcb998e24e7bbb
Status: Downloaded newer image for busybox:latest
docker.io/library/busybox:latest
ubuntu@ubuntu:~/docker$ docker tag busybox:latest localhost:5000/busybox:latest
ubuntu@ubuntu:~/docker$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry latest d6b2c32a0f14 7 months ago 25.4MB
busybox latest 65ad0d468eb1 12 months ago 4.26MB
localhost:5000/busybox latest 65ad0d468eb1 12 months ago 4.26MB
ubuntu@ubuntu:~/docker$
ubuntu@ubuntu:~/docker$ docker push localhost:5000/busybox:latest
The push refers to repository [localhost:5000/busybox]
d51af96cf93e: Pushed
latest: digest: sha256:28e01ab32c9dbcbaae96cf0d5b472f22e231d9e603811857b295e61197e40a9b size: 527
ubuntu@ubuntu:~/docker$
ubuntu@ubuntu:~/docker$
ubuntu@ubuntu:~/docker$ curl -k http://localhost:5000/v2/_catalog
{"repositories":["busybox"]}
ubuntu@ubuntu:~/docker$
Builder instanceの作成
コマンド
$ docker run --privileged --rm tonistiigi/binfmt --install all
$ docker buildx create --name mybuilder --bootstrap --use --driver docker-container --driver-opt network=host
$ docker buildx ls
$ docker buildx inspect mybuilder
実行結果のログ
実行結果
ubuntu@ubuntu:~/docker$ docker run --privileged --rm tonistiigi/binfmt --install all
Unable to find image 'tonistiigi/binfmt:latest' locally
latest: Pulling from tonistiigi/binfmt
8d4d64c318a5: Pull complete
e9c608ddc3cb: Pull complete
Digest: sha256:66e11bea77a5ea9d6f0fe79b57cd2b189b5d15b93a2bdb925be22949232e4e55
Status: Downloaded newer image for tonistiigi/binfmt:latest
installing: riscv64 OK
installing: mips64le OK
installing: mips64 OK
installing: s390x OK
installing: ppc64le OK
installing: arm64 OK
installing: arm OK
{
"supported": [
"linux/amd64",
"linux/arm64",
"linux/riscv64",
"linux/ppc64le",
"linux/s390x",
"linux/386",
"linux/mips64le",
"linux/mips64",
"linux/arm/v7",
"linux/arm/v6"
],
"emulators": [
"qemu-aarch64",
"qemu-arm",
"qemu-mips64",
"qemu-mips64el",
"qemu-ppc64le",
"qemu-riscv64",
"qemu-s390x"
]
}
ubuntu@ubuntu:~/docker$
ubuntu@ubuntu:~/docker$
ubuntu@ubuntu:~/docker$ docker buildx create --name mybuilder --bootstrap --use --driver docker-container --driver-opt network=host
[+] Building 14.8s (1/1) FINISHED
=> [internal] booting buildkit 14.8s
=> => pulling image moby/buildkit:buildx-stable-1 13.5s
=> => creating container buildx_buildkit_mybuilder0 1.3s
mybuilder
ubuntu@ubuntu:~/docker$
ubuntu@ubuntu:~/docker$
ubuntu@ubuntu:~/docker$ docker buildx ls
NAME/NODE DRIVER/ENDPOINT STATUS BUILDKIT PLATFORMS
mybuilder* docker-container
\_ mybuilder0 \_ unix:///var/run/docker.sock running v0.13.2 linux/amd64, linux/amd64/v2, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
default docker
\_ default \_ default running v0.13.1 linux/amd64, linux/amd64/v2, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
ubuntu@ubuntu:~/docker$
ubuntu@ubuntu:~/docker$
ubuntu@ubuntu:~/docker$ docker buildx inspect mybuilder
Name: mybuilder
Driver: docker-container
Last Activity: 2024-05-19 14:35:08 +0000 UTC
Nodes:
Name: mybuilder0
Endpoint: unix:///var/run/docker.sock
Driver Options: network="host"
Status: running
BuildKit daemon flags: --allow-insecure-entitlement=network.host
BuildKit version: v0.13.2
Platforms: linux/amd64, linux/amd64/v2, linux/arm64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/mips64le, linux/mips64, linux/arm/v7, linux/arm/v6
Labels:
org.mobyproject.buildkit.worker.executor: oci
org.mobyproject.buildkit.worker.hostname: ubuntu
org.mobyproject.buildkit.worker.network: host
org.mobyproject.buildkit.worker.oci.process-mode: sandbox
org.mobyproject.buildkit.worker.selinux.enabled: false
org.mobyproject.buildkit.worker.snapshotter: overlayfs
GC Policy rule#0:
All: false
Filters: type==source.local,type==exec.cachemount,type==source.git.checkout
Keep Duration: 48h0m0s
Keep Bytes: 488.3MiB
GC Policy rule#1:
All: false
Keep Duration: 1440h0m0s
Keep Bytes: 4.657GiB
GC Policy rule#2:
All: false
Keep Bytes: 4.657GiB
GC Policy rule#3:
All: true
Keep Bytes: 4.657GiB
ubuntu@ubuntu:~/docker$
multi-platform buildを行うための要件があり、QEMUのインストールにtonistiigi/binfmtを使用した。
Strategies
You can build multi-platform images using three different strategies, depending on your use case:
- Using emulation, via QEMU support in the Linux kernel
- Building on a single builder backed by multiple nodes of different architectures.
- Using a stage in your Dockerfile to cross-compile to different architectures
Build&push
--platformオプションを使用して、x86/arm用のイメージ作成を行う。
コマンド
$ vi Dockerfile
$ docker buildx build --platform linux/amd64,linux/arm64 -t localhost:5000/test:latest --push .
実行結果のログ
実行結果
ubuntu@ubuntu:~/docker$ docker buildx build --platform linux/amd64,linux/arm64 -t localhost:5000/test:latest --push .
[+] Building 23.3s (15/15) FINISHED docker-container:mybuilder
=> [internal] load build definition from Dockerfile 0.2s
=> => transferring dockerfile: 278B 0.0s
=> resolve image config for docker-image://docker.io/docker/dockerfile:1 2.4s
=> docker-image://docker.io/docker/dockerfile:1@sha256:a57df69d0ea827fb7266491f2813635de6f17269be881f696fbfdf2d83dda33e 1.5s
=> => resolve docker.io/docker/dockerfile:1@sha256:a57df69d0ea827fb7266491f2813635de6f17269be881f696fbfdf2d83dda33e 0.0s
=> => sha256:96918c57e42509b97f10c074d80672ecdbd3bb7dcd38c1bd95960cf291207416 11.98MB / 11.98MB 0.6s
=> => extracting sha256:96918c57e42509b97f10c074d80672ecdbd3bb7dcd38c1bd95960cf291207416 0.8s
=> [linux/amd64 internal] load metadata for docker.io/library/golang:alpine 2.7s
=> [linux/amd64 internal] load metadata for docker.io/library/alpine:latest 2.5s
=> [linux/arm64 internal] load metadata for docker.io/library/alpine:latest 2.7s
=> [internal] load .dockerignore 0.1s
=> => transferring context: 2B 0.0s
=> [linux/amd64 build 1/2] FROM docker.io/library/golang:alpine@sha256:f1fe698725f6ed14eb944dc587591f134632ed47fc0732ec27c7642adbe90618 13.1s
=> => resolve docker.io/library/golang:alpine@sha256:f1fe698725f6ed14eb944dc587591f134632ed47fc0732ec27c7642adbe90618 0.1s
=> => sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 32B / 32B 0.4s
=> => sha256:db27d6512129ba324acd616fd920202156dfadb8ccae8ffd1ec862bd46277c98 126B / 126B 0.4s
=> => sha256:3e347f261431f4a9affbd78ee6f59a7486c17be94c7c8274be137aab626f0555 69.34MB / 69.34MB 2.5s
=> => sha256:667a4259027594465efe0982aec566a89095e879511d0716b4ae322f291e393d 292.90kB / 292.90kB 0.6s
=> => extracting sha256:667a4259027594465efe0982aec566a89095e879511d0716b4ae322f291e393d 0.2s
=> => extracting sha256:3e347f261431f4a9affbd78ee6f59a7486c17be94c7c8274be137aab626f0555 9.9s
=> => extracting sha256:db27d6512129ba324acd616fd920202156dfadb8ccae8ffd1ec862bd46277c98 0.0s
=> => extracting sha256:4f4fb700ef54461cfa02571ae0db9a0dc1e0cdb5577484a6d75e68dc38e8acc1 0.0s
=> [linux/arm64 stage-1 1/2] FROM docker.io/library/alpine:latest@sha256:c5b1261d6d3e43071626931fc004f70149baeba2c8ec672bd4f27761f8e1ad6b 1.6s
=> => resolve docker.io/library/alpine:latest@sha256:c5b1261d6d3e43071626931fc004f70149baeba2c8ec672bd4f27761f8e1ad6b 0.1s
=> => sha256:bca4290a96390d7a6fc6f2f9929370d06f8dfcacba591c76e3d5c5044e7f420c 3.35MB / 3.35MB 0.5s
=> => extracting sha256:bca4290a96390d7a6fc6f2f9929370d06f8dfcacba591c76e3d5c5044e7f420c 0.8s
=> [linux/amd64 stage-1 1/2] FROM docker.io/library/alpine:latest@sha256:c5b1261d6d3e43071626931fc004f70149baeba2c8ec672bd4f27761f8e1ad6b 1.5s
=> => resolve docker.io/library/alpine:latest@sha256:c5b1261d6d3e43071626931fc004f70149baeba2c8ec672bd4f27761f8e1ad6b 0.1s
=> => sha256:4abcf20661432fb2d719aaf90656f55c287f8ca915dc1c92ec14ff61e67fbaf8 3.41MB / 3.41MB 0.4s
=> => extracting sha256:4abcf20661432fb2d719aaf90656f55c287f8ca915dc1c92ec14ff61e67fbaf8 0.8s
=> [linux/amd64 build 2/2] RUN echo "I am running on linux/amd64, building for linux/amd64" > /log 0.8s
=> [linux/amd64->arm64 build 2/2] RUN echo "I am running on linux/amd64, building for linux/arm64" > /log 0.8s
=> [linux/amd64 stage-1 2/2] COPY --from=build /log /log 0.2s
=> [linux/arm64 stage-1 2/2] COPY --from=build /log /log 0.2s
=> exporting to image 1.1s
=> => exporting layers 0.3s
=> => exporting manifest sha256:aac2940ff03955e14222c5d6c0952829a21786fa635db7e472a17df2458c1fc5 0.0s
=> => exporting config sha256:7d93dd4b642c38e2c06eb16dc4706963642fe9804e7bf643e71ea637824d7a69 0.0s
=> => exporting attestation manifest sha256:475ca97131d0c82289cf017101e45fc857a7d99ea2e75cda3fb9bba727fefc8b 0.0s
=> => exporting manifest sha256:ecb899a3e0ff4527a8ca5cd5e0429ae522b9ebb35d0ce60ee7a2c8a1819ac987 0.0s
=> => exporting config sha256:7ecdf7f0056dd4a8bf6d5e8c24bb6005171e0bda11ad01bd5170531f9f38c6c4 0.0s
=> => exporting attestation manifest sha256:cc24a5d4575484fb6635d9fbd9973181169d23f601bd31cc12baa4773cba9e71 0.0s
=> => exporting manifest list sha256:f6be49b394a70df268599d736cb67b257fb9b54ca332d67eb4694b22e6871ca1 0.0s
=> => pushing layers 0.3s
=> => pushing manifest for localhost:5000/test:latest@sha256:f6be49b394a70df268599d736cb67b257fb9b54ca332d67eb4694b22e6871ca1 0.2s
ubuntu@ubuntu:~/docker$
Dockerfileは、下記に記載されているCross compile用のサンプルをそのまま使用した。
動作確認
作成したイメージをそれぞれ起動し指定されたアーキテクチャーのイメージになっているか確認する。
docker run実行時に--platform
オプションを指定してx86/armのイメージを起動する。
コマンド
$ docker run --rm --platform linux/amd64 localhost:5000/test:latest uname -m
$ docker run --rm --platform linux/arm64 localhost:5000/test:latest uname -m
実行結果のログ
実行結果
ubuntu@ubuntu:~/docker$ docker run --rm --platform linux/amd64 localhost:5000/test:latest uname -m
Unable to find image 'localhost:5000/test:latest' locally
latest: Pulling from test
4abcf2066143: Already exists
a31561bca027: Pull complete
Digest: sha256:f6be49b394a70df268599d736cb67b257fb9b54ca332d67eb4694b22e6871ca1
Status: Downloaded newer image for localhost:5000/test:latest
x86_64
ubuntu@ubuntu:~/docker$
ubuntu@ubuntu:~/docker$
ubuntu@ubuntu:~/docker$ docker run --rm --platform linux/arm64 localhost:5000/test:latest uname -m
Unable to find image 'localhost:5000/test:latest' locally
latest: Pulling from test
bca4290a9639: Pull complete
d1eef5f67990: Pull complete
Digest: sha256:f6be49b394a70df268599d736cb67b257fb9b54ca332d67eb4694b22e6871ca1
Status: Downloaded newer image for localhost:5000/test:latest
aarch64
ubuntu@ubuntu:~/docker$
Cleanup
使用したリソースを削除する。
コマンド
$ docker rm -f docker-registry
$ docker run --privileged --rm tonistiigi/binfmt --uninstall "qemu-*"
$ docker system prune -a
$ docker system prune --volumes -f