Best practices for building multi architecture mirrors

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:

1. Docker Buildx

2. How to Build Multi-Architecture Docker Images with BuildX | Deploy containers to x86 and ARM!

Keywords: Container

Added by adammc on Mon, 24 Jan 2022 03:19:08 +0200