Author: xcbeyond
Blog: https://xcbeyond.cn/
In the cloud era, containerization has become a fact. Packaging and building software products into Docker images is the most basic and critical step. In the context of Xinchuang, there will be different architectures such as x86 and arm in the cloud environment. Therefore, when building images, you need to build images of multiple architectures to adapt to servers of different architectures.
When pulling the Docker image, the image of the corresponding architecture will be automatically pulled according to the architecture of the current environment. For example, the image pulled down in x86 environment is the image of x86 architecture, and the image pulled down in arm environment is the image of arm architecture. (provided that the image is a multi architecture image)
This article will explain how to build a multi architecture image based on Docker Buildx (build a multi architecture image at one time).
1. buildx installation
Docker Buildx is a CLI plug-in that extends docker commands and fully supports Moby BuildKit Functionality provided by the builder toolkit. It provides the same user experience as docker build and has many new functions, such as creating scope builder instances and building against multiple nodes at the same time.
1. Download the buildx binary file.
stay Github Release page Download the latest buildx binaries.
Select the corresponding binary file according to your operating system.
2. Copy buildx to the corresponding directory of Docker.
Rename the downloaded buildx binary file and copy it to the corresponding directory of your operating system:
For example, my MacOS:
xcbeyond@xcbeyonddeMacBook-Pro ~ % mv ~/Downloads/buildx-v0.7.1.darwin-arm64 ~/.docker/cli-plugins/docker-buildx xcbeyond@xcbeyonddeMacBook-Pro ~ % chmod +x ~/.docker/cli-plugins/docker-buildx
Note: you need to give permission to the buildx binary file and execute chmod +x.
3. Check buildx.
Execute docker buildx version:
xcbeyond@xcbeyonddeMacBook-Pro ~ % docker buildx version github.com/docker/buildx v0.7.1 05846896d149da05f3d6fd1e7770da187b52a247
2. Enable binfmt_misc to run Docker images of non local architectures
If you are using a Mac or Windows version Docker desktop version, you can skip this step because binfmt_misc is on by default.
If you are using other platforms, you can use tonistiigi/binfmt Image for installation:
docker run --privileged --rm tonistiigi/binfmt --install all
3. Switch the default Docker builder to a multi schema builder
By default, Docker uses the default builder, which does not support multi architecture construction.
In order to build a multi architecture image, you need to create a new builder that supports multi architecture. You need to execute docker buildx create --use:
xcbeyond@xcbeyonddeMacBook-Pro % docker buildx create --use --name mybuilder mybuilder
To check whether the new multi architecture builder is effective, you need to execute docker buildx ls:
xcbeyond@xcbeyonddeMacBook-Pro % docker buildx ls NAME/NODE DRIVER/ENDPOINT STATUS PLATFORMS mybuilder * docker-container mybuilder0 unix:///var/run/docker.sock inactive desktop-linux docker desktop-linux desktop-linux running linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6 default docker default default running linux/arm64, linux/amd64, linux/riscv64, linux/ppc64le, linux/s390x, linux/386, linux/arm/v7, linux/arm/v6
4. Building multi architecture images
1. Write test procedures.
For the convenience of testing, a simple program is written in Golang program , and output the architecture information of the current program running environment:
package main import ( "fmt" "runtime" ) func main() { fmt.Printf("the current platform architecture is %s.\n", runtime.GOARCH) }
2. Write Dockerfile.
To write the program Dockerfile:
FROM xcbeyond/go-builder:1.16 LABEL maintainer xcbeyond WORKDIR /app COPY multi-arch-test.go /app RUN go build -o multi-arch-test /app/multi-arch-test.go CMD ["./multi-arch-test"]
3. Build a multi architecture image.
Use the command docker buildx build - T < image name > -- platform = Linux / arm64, Linux / amd64-- Push, build a multi architecture image supporting arm64 and amd64 architecture, and push it to Docker Hub:
(the parameter ` -- push 'will automatically push the image to the Docker Hub, and the image will not be retained locally. If you do not want to push, you can remove this parameter.)
xcbeyond@xcbeyonddeMacBook-Pro build-multi-platform-images-best-practices % docker buildx build -t xcbeyond/multi-arch-test --platform=linux/arm64,linux/amd64 . --push [+] Building 3105.4s (19/19) FINISHED => [internal] load build definition from Dockerfile 0.0s => => transferring dockerfile: 222B 0.0s => [internal] load .dockerignore 0.0s => => transferring context: 2B 0.0s => [linux/amd64 internal] load metadata for docker.io/xcbeyond/go-builder:1.16 5.2s => [linux/arm64 internal] load metadata for docker.io/xcbeyond/go-builder:1.16 4.9s => [auth] xcbeyond/go-builder:pull token for registry-1.docker.io 0.0s => [internal] load build context 0.0s => => transferring context: 40B 0.0s => [linux/amd64 1/4] FROM docker.io/xcbeyond/go-builder:1.16@sha256:ace56967e44e98b1a8c286ad97717c878650d0312ac3e69767234f766601d6fc 2323.9s => => resolve docker.io/xcbeyond/go-builder:1.16@sha256:ace56967e44e98b1a8c286ad97717c878650d0312ac3e69767234f766601d6fc 0.0s => => sha256:6e1d20a8313edd44a36cb9198f4d11ac5eedb41d1faf5e8a33c5a0a5a25d2b92 85.80MB / 85.80MB 2318.7s => => sha256:6494e4811622b31c027ccac322ca463937fd805f569a93e6f15c01aade718793 54.57MB / 54.57MB 27.3s => => sha256:5b59121a0c3517cfd68aba8a3955cbb40ca12dd56db3317e3a17cf56131ca915 129.08MB / 129.08MB 77.1s => => sha256:cb5b7ae361722f070eca53f35823ed21baa85d61d5d95cd5a95ab53d740cdd56 10.87MB / 10.87MB 96.5s => => sha256:9b829c73b52b92b97d5c07a54fb0f3e921995a296c714b53a32ae67d19231fcd 5.15MB / 5.15MB 5.2s => => sha256:0e29546d541cdbd309281d21a73a9d1db78665c1b95b74f32b009e0b77a6e1e3 54.92MB / 54.92MB 61.0s => => extracting sha256:0e29546d541cdbd309281d21a73a9d1db78665c1b95b74f32b009e0b77a6e1e3 1.5s => => extracting sha256:9b829c73b52b92b97d5c07a54fb0f3e921995a296c714b53a32ae67d19231fcd 0.1s => => extracting sha256:cb5b7ae361722f070eca53f35823ed21baa85d61d5d95cd5a95ab53d740cdd56 0.3s => => extracting sha256:6494e4811622b31c027ccac322ca463937fd805f569a93e6f15c01aade718793 1.6s => => extracting sha256:6e1d20a8313edd44a36cb9198f4d11ac5eedb41d1faf5e8a33c5a0a5a25d2b92 1.9s => => extracting sha256:5b59121a0c3517cfd68aba8a3955cbb40ca12dd56db3317e3a17cf56131ca915 3.3s => => extracting sha256:2db41f0db9d9d9a1f49978ec31e8d187f491767e9b377f5ee121827c407e015e 0.0s => [linux/arm64 1/4] FROM docker.io/xcbeyond/go-builder:1.16@sha256:ace56967e44e98b1a8c286ad97717c878650d0312ac3e69767234f766601d6fc 2187.3s => => resolve docker.io/xcbeyond/go-builder:1.16@sha256:ace56967e44e98b1a8c286ad97717c878650d0312ac3e69767234f766601d6fc 0.0s => => sha256:221ff675cd357b3b345da24f781791fc9b91066d687f9e928993aab31618d13d 99.63MB / 99.63MB 54.3s => => sha256:627b3401fb617535edd16e96bd5941ecea7fe10ce6087bd47707602cfc396c2b 81.01MB / 81.01MB 472.1s => => sha256:841dd868500b6685b6cda93c97ea76e817b427d7a10bf73e9d03356fac199ffd 54.67MB / 54.67MB 2084.9s => => sha256:aa9c5b49b9db3dd2553e8ae6c2081b77274ec0a8b1f9903b0e5ac83900642098 10.66MB / 10.66MB 6.2s => => sha256:ac9d381bd1e98fa8759f80ff42db63c8fce4ac9407b2e7c8e0f031ed9f96432b 5.14MB / 5.14MB 6.8s => => sha256:94a23d3cb5be24659b25f17537307e7f568d665244f6a383c1c6e51e31080749 53.60MB / 53.60MB 22.7s => => extracting sha256:94a23d3cb5be24659b25f17537307e7f568d665244f6a383c1c6e51e31080749 1.5s => => extracting sha256:ac9d381bd1e98fa8759f80ff42db63c8fce4ac9407b2e7c8e0f031ed9f96432b 0.1s => => extracting sha256:aa9c5b49b9db3dd2553e8ae6c2081b77274ec0a8b1f9903b0e5ac83900642098 0.2s => => extracting sha256:841dd868500b6685b6cda93c97ea76e817b427d7a10bf73e9d03356fac199ffd 1.5s => => extracting sha256:627b3401fb617535edd16e96bd5941ecea7fe10ce6087bd47707602cfc396c2b 1.7s => => extracting sha256:221ff675cd357b3b345da24f781791fc9b91066d687f9e928993aab31618d13d 2.7s => => extracting sha256:10c716f05a00666c190fb40f99503dc83b2886de744ab9b3dc6c5d37d01f6e49 0.0s => [auth] xcbeyond/go-builder:pull token for registry-1.docker.io 0.0s => [linux/arm64 2/4] WORKDIR /app 0.1s => [linux/arm64 3/4] COPY multi-arch-test.go /app 0.0s => [linux/arm64 4/4] RUN go build -o multi-arch-test /app/multi-arch-test.go 0.3s => [linux/amd64 2/4] WORKDIR /app 0.2s => [linux/amd64 3/4] COPY multi-arch-test.go /app 0.0s => [linux/amd64 4/4] RUN go build -o multi-arch-test /app/multi-arch-test.go 1.5s => exporting to image 774.4s => => exporting layers 10.5s => => exporting manifest sha256:f38420339c9665b4f7d8b1e5edc66dc09e596ec7aa78113914b8a5b1b900e9e2 0.0s => => exporting config sha256:628f504898973d1d935ffd37993d1db5fdc4715c5d58467db2c6531d3d7d3181 0.0s => => exporting manifest sha256:a259302dca0d3f432d08f578e3243c5244bc50e54ea561c80dba03622897fcfd 0.0s => => exporting config sha256:47e7af533f821be5ba256919303e0de3b39990109a419a98dbfddc6c82086822 0.0s => => exporting manifest list sha256:8417543ebc47e6040a67a392d6ee9de05735ed464e48b22fcc3bdf66ce22224b 0.0s => => pushing layers 761.8s => => pushing manifest for docker.io/xcbeyond/multi-arch-test:latest@sha256:8417543ebc47e6040a67a392d6ee9de05735ed464e48b22fcc3bdf66ce22224b 2.0s => [auth] xcbeyond/multi-arch-test:pull,push token for registry-1.docker.io 0.0s => [auth] xcbeyond/multi-arch-test:pull,push token for registry-1.docker.io 0.0s => [auth] xcbeyond/multi-arch-test:pull,push token for registry-1.docker.io 0.0s
5. Test multi architecture mirroring
Multi architecture image to be built xcbeyond/multi-arch-test:latest Test to ensure normal operation, and use the corresponding schema image to output matching schema information.
1. View the information of each architecture image.
Execute the command docker manifest inspect to view the image detailed list And can know the image SHA value of the corresponding architecture of the image:
xcbeyond@xcbeyonddeMacBook-Pro build-multi-platform-images-best-practices % docker manifest inspect xcbeyond/multi-arch-test:latest { "schemaVersion": 2, "mediaType": "application/vnd.docker.distribution.manifest.list.v2+json", "manifests": [ { "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "size": 2419, "digest": "sha256:f38420339c9665b4f7d8b1e5edc66dc09e596ec7aa78113914b8a5b1b900e9e2", "platform": { "architecture": "arm64", "os": "linux" } }, { "mediaType": "application/vnd.docker.distribution.manifest.v2+json", "size": 2420, "digest": "sha256:a259302dca0d3f432d08f578e3243c5244bc50e54ea561c80dba03622897fcfd", "platform": { "architecture": "amd64", "os": "linux" } } ] }
You can also directly see the multi architecture information supported by the image on the Docker Hub:
2. Run the image one by one according to the SHA value of different architecture images and view its output results.
Execute the docker run --rm command respectively:
Image of arm Architecture:
xcbeyond@xcbeyonddeMacBook-Pro build-multi-platform-images-best-practices % docker run --rm xcbeyond/multi-arch-test:latest@sha256:f38420339c9665b4f7d8b1e5edc66dc09e596ec7aa78113914b8a5b1b900e9e2 Unable to find image 'xcbeyond/multi-arch-test:latest@sha256:f38420339c9665b4f7d8b1e5edc66dc09e596ec7aa78113914b8a5b1b900e9e2' locally docker.io/xcbeyond/multi-arch-test@sha256:f38420339c9665b4f7d8b1e5edc66dc09e596ec7aa78113914b8a5b1b900e9e2: Pulling from xcbeyond/multi-arch-test 94a23d3cb5be: Pull complete ac9d381bd1e9: Pull complete aa9c5b49b9db: Pull complete 841dd868500b: Pull complete 627b3401fb61: Pull complete 221ff675cd35: Pull complete 10c716f05a00: Pull complete 15bae122089f: Pull complete d764b5be0a55: Pull complete 34bfa57028a2: Pull complete Digest: sha256:f38420339c9665b4f7d8b1e5edc66dc09e596ec7aa78113914b8a5b1b900e9e2 Status: Downloaded newer image for xcbeyond/multi-arch-test@sha256:f38420339c9665b4f7d8b1e5edc66dc09e596ec7aa78113914b8a5b1b900e9e2 the current platform architecture is arm64.
Image of x86 architecture:
xcbeyond@xcbeyonddeMacBook-Pro build-multi-platform-images-best-practices % docker run --rm xcbeyond/multi-arch-test:latest@sha256:a259302dca0d3f432d08f578e3243c5244bc50e54ea561c80dba03622897fcfd Unable to find image 'xcbeyond/multi-arch-test:latest@sha256:a259302dca0d3f432d08f578e3243c5244bc50e54ea561c80dba03622897fcfd' locally docker.io/xcbeyond/multi-arch-test@sha256:a259302dca0d3f432d08f578e3243c5244bc50e54ea561c80dba03622897fcfd: Pulling from xcbeyond/multi-arch-test 0e29546d541c: Pull complete 9b829c73b52b: Pull complete cb5b7ae36172: Pull complete 6494e4811622: Pull complete 6e1d20a8313e: Pull complete 5b59121a0c35: Pull complete 2db41f0db9d9: Pull complete f708bf6a9dc8: Pull complete cb0d69b97354: Pull complete a8f5aa83ecfb: Pull complete Digest: sha256:a259302dca0d3f432d08f578e3243c5244bc50e54ea561c80dba03622897fcfd Status: Downloaded newer image for xcbeyond/multi-arch-test@sha256:a259302dca0d3f432d08f578e3243c5244bc50e54ea561c80dba03622897fcfd the current platform architecture is amd64.
The above output results are consistent with our expectations: the multi architecture image is successfully built and can run in their own architecture environment.
6. Summary
Multi architecture image is built based on Docker Buildx. At present, buildx needs additional installation. In the future, buildx is likely to become a part of docker build command without additional installation. After all, multi architecture image has been widely used in various scenarios.
Reference article:
2. How to Build Multi-Architecture Docker Images with BuildX | Deploy containers to x86 and ARM!